From e1009876e62de4e59e2267afcb32431bafe8c9f3 Mon Sep 17 00:00:00 2001 From: leebeomjun Date: Mon, 22 Jan 2024 13:29:03 +0900 Subject: [PATCH] =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WEB-INF/jsp/fims/sprt/sprt03010-main.jsp | 2 +- .../WEB-INF/jsp/fims/sprt/sprt03020-main.jsp | 2 +- .../WEB-INF/jsp/fims/user/user-info.jsp | 2 +- src/main/webapp/WEB-INF/jsp/include/tail.jsp | 2 +- src/main/webapp/WEB-INF/jsp/select-url.jsp | 2 +- .../resources/3rd-party/jstree/jstree.js | 8605 ---------------- .../resources/3rd-party/jstree/jstree.min.js | 6 - .../jstree/themes/default-dark/32px.png | Bin 1525 -> 0 bytes .../jstree/themes/default-dark/40px.png | Bin 6526 -> 0 bytes .../jstree/themes/default-dark/style.css | 1146 --- .../jstree/themes/default-dark/style.min.css | 1 - .../jstree/themes/default-dark/throbber.gif | Bin 1464 -> 0 bytes .../3rd-party/jstree/themes/default/32px.png | Bin 5667 -> 0 bytes .../3rd-party/jstree/themes/default/40px.png | Bin 2218 -> 0 bytes .../3rd-party/jstree/themes/default/style.css | 1102 --- .../jstree/themes/default/style.min.css | 1 - .../jstree/themes/default/throbber.gif | Bin 1464 -> 0 bytes .../3rd-party/jstree/themes/proton/30px.png | Bin 6423 -> 0 bytes .../3rd-party/jstree/themes/proton/32px.png | Bin 3333 -> 0 bytes .../titillium/titilliumweb-bold-webfont.eot | Bin 24108 -> 0 bytes .../titillium/titilliumweb-bold-webfont.svg | 2377 ----- .../titillium/titilliumweb-bold-webfont.ttf | Bin 49936 -> 0 bytes .../titillium/titilliumweb-bold-webfont.woff | Bin 27344 -> 0 bytes .../titilliumweb-extralight-webfont.eot | Bin 24056 -> 0 bytes .../titilliumweb-extralight-webfont.svg | 2410 ----- .../titilliumweb-extralight-webfont.ttf | Bin 50224 -> 0 bytes .../titilliumweb-extralight-webfont.woff | Bin 27108 -> 0 bytes .../titilliumweb-regular-webfont.eot | Bin 25059 -> 0 bytes .../titilliumweb-regular-webfont.svg | 2725 ----- .../titilliumweb-regular-webfont.ttf | Bin 50788 -> 0 bytes .../titilliumweb-regular-webfont.woff | Bin 28152 -> 0 bytes .../3rd-party/jstree/themes/proton/style.css | 1122 --- .../jstree/themes/proton/style.min.css | 1 - .../jstree/themes/proton/throbber.gif | Bin 1720 -> 0 bytes .../3rd-party/sneat/libs/jstree/jstree.js | 8735 ++++++++++++++++- .../webapp/resources/html/fileUpload.html | 2 +- .../resources/html/inputDateDialog.html | 2 +- .../webapp/resources/html/inputRsnDialog.html | 2 +- .../resources/html/inputTtlDocNoDialog.html | 2 +- src/main/webapp/resources/html/pdf.html | 2 +- .../webapp/resources/html/searchAddr.html | 2 +- 41 files changed, 8614 insertions(+), 19639 deletions(-) delete mode 100644 src/main/webapp/resources/3rd-party/jstree/jstree.js delete mode 100644 src/main/webapp/resources/3rd-party/jstree/jstree.min.js delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default-dark/32px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default-dark/40px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.min.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default-dark/throbber.gif delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default/32px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default/40px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default/style.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default/style.min.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/default/throbber.gif delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/30px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/32px.png delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.eot delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.svg delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.ttf delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.woff delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.eot delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.svg delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.ttf delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.woff delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.eot delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.svg delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.ttf delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.woff delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/style.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/style.min.css delete mode 100644 src/main/webapp/resources/3rd-party/jstree/themes/proton/throbber.gif diff --git a/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03010-main.jsp b/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03010-main.jsp index 6b23bb5a..dd8866b7 100644 --- a/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03010-main.jsp +++ b/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03010-main.jsp @@ -89,7 +89,7 @@ - + diff --git a/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03020-main.jsp b/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03020-main.jsp index 616a970b..6a8213d1 100644 --- a/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03020-main.jsp +++ b/src/main/webapp/WEB-INF/jsp/fims/sprt/sprt03020-main.jsp @@ -51,7 +51,7 @@ - + diff --git a/src/main/webapp/WEB-INF/jsp/fims/user/user-info.jsp b/src/main/webapp/WEB-INF/jsp/fims/user/user-info.jsp index 93f04d37..3363b545 100644 --- a/src/main/webapp/WEB-INF/jsp/fims/user/user-info.jsp +++ b/src/main/webapp/WEB-INF/jsp/fims/user/user-info.jsp @@ -220,7 +220,7 @@ - + diff --git a/src/main/webapp/WEB-INF/jsp/include/tail.jsp b/src/main/webapp/WEB-INF/jsp/include/tail.jsp index d75dd84b..7e96d298 100644 --- a/src/main/webapp/WEB-INF/jsp/include/tail.jsp +++ b/src/main/webapp/WEB-INF/jsp/include/tail.jsp @@ -14,7 +14,7 @@ - + diff --git a/src/main/webapp/WEB-INF/jsp/select-url.jsp b/src/main/webapp/WEB-INF/jsp/select-url.jsp index 4e1f826e..56cf9a19 100644 --- a/src/main/webapp/WEB-INF/jsp/select-url.jsp +++ b/src/main/webapp/WEB-INF/jsp/select-url.jsp @@ -1,6 +1,6 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%> <%@ include file="/WEB-INF/jsp/include/taglib.jsp"%> -" /--%> +"
diff --git a/src/main/webapp/resources/3rd-party/jstree/jstree.js b/src/main/webapp/resources/3rd-party/jstree/jstree.js deleted file mode 100644 index 00617ef6..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/jstree.js +++ /dev/null @@ -1,8605 +0,0 @@ -/*globals jQuery, define, module, exports, require, window, document, postMessage */ -(function (factory) { - "use strict"; - if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } - else if(typeof module !== 'undefined' && module.exports) { - module.exports = factory(require('jquery')); - } - else { - factory(jQuery); - } -}(function ($, undefined) { - "use strict"; -/*! - * jsTree 3.3.7 - * http://jstree.com/ - * - * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com) - * - * Licensed same as jquery - under the terms of the MIT License - * http://www.opensource.org/licenses/mit-license.php - */ -/*! - * if using jslint please allow for the jQuery global and use following options: - * jslint: loopfunc: true, browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true - */ -/*jshint -W083 */ - - // prevent another load? maybe there is a better way? - if($.jstree) { - return; - } - - /** - * ### jsTree core functionality - */ - - // internal variables - var instance_counter = 0, - ccp_node = false, - ccp_mode = false, - ccp_inst = false, - themes_loaded = [], - src = $('script:last').attr('src'), - document = window.document; // local variable is always faster to access then a global - - /** - * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances. - * @name $.jstree - */ - $.jstree = { - /** - * specifies the jstree version in use - * @name $.jstree.version - */ - version : '3.3.7', - /** - * holds all the default options used when creating new instances - * @name $.jstree.defaults - */ - defaults : { - /** - * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]` - * @name $.jstree.defaults.plugins - */ - plugins : [] - }, - /** - * stores all loaded jstree plugins (used internally) - * @name $.jstree.plugins - */ - plugins : {}, - path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '', - idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g, - root : '#' - }; - - /** - * creates a jstree instance - * @name $.jstree.create(el [, options]) - * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector - * @param {Object} options options for this instance (extends `$.jstree.defaults`) - * @return {jsTree} the new instance - */ - $.jstree.create = function (el, options) { - var tmp = new $.jstree.core(++instance_counter), - opt = options; - options = $.extend(true, {}, $.jstree.defaults, options); - if(opt && opt.plugins) { - options.plugins = opt.plugins; - } - $.each(options.plugins, function (i, k) { - if(i !== 'core') { - tmp = tmp.plugin(k, options[k]); - } - }); - $(el).data('jstree', tmp); - tmp.init(el, options); - return tmp; - }; - /** - * remove all traces of jstree from the DOM and destroy all instances - * @name $.jstree.destroy() - */ - $.jstree.destroy = function () { - $('.jstree:jstree').jstree('destroy'); - $(document).off('.jstree'); - }; - /** - * the jstree class constructor, used only internally - * @private - * @name $.jstree.core(id) - * @param {Number} id this instance's index - */ - $.jstree.core = function (id) { - this._id = id; - this._cnt = 0; - this._wrk = null; - this._data = { - core : { - themes : { - name : false, - dots : false, - icons : false, - ellipsis : false - }, - selected : [], - last_error : {}, - working : false, - worker_queue : [], - focused : null - } - }; - }; - /** - * get a reference to an existing instance - * - * __Examples__ - * - * // provided a container with an ID of "tree", and a nested node with an ID of "branch" - * // all of there will return the same instance - * $.jstree.reference('tree'); - * $.jstree.reference('#tree'); - * $.jstree.reference($('#tree')); - * $.jstree.reference(document.getElementByID('tree')); - * $.jstree.reference('branch'); - * $.jstree.reference('#branch'); - * $.jstree.reference($('#branch')); - * $.jstree.reference(document.getElementByID('branch')); - * - * @name $.jstree.reference(needle) - * @param {DOMElement|jQuery|String} needle - * @return {jsTree|null} the instance or `null` if not found - */ - $.jstree.reference = function (needle) { - var tmp = null, - obj = null; - if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; } - - if(!obj || !obj.length) { - try { obj = $(needle); } catch (ignore) { } - } - if(!obj || !obj.length) { - try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { } - } - if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) { - tmp = obj; - } - else { - $('.jstree').each(function () { - var inst = $(this).data('jstree'); - if(inst && inst._model.data[needle]) { - tmp = inst; - return false; - } - }); - } - return tmp; - }; - /** - * Create an instance, get an instance or invoke a command on a instance. - * - * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken). - * - * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function). - * - * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`). - * - * In any other case - nothing is returned and chaining is not broken. - * - * __Examples__ - * - * $('#tree1').jstree(); // creates an instance - * $('#tree2').jstree({ plugins : [] }); // create an instance with some options - * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments - * $('#tree2').jstree(); // get an existing instance (or create an instance) - * $('#tree2').jstree(true); // get an existing instance (will not create new instance) - * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method) - * - * @name $().jstree([arg]) - * @param {String|Object} arg - * @return {Mixed} - */ - $.fn.jstree = function (arg) { - // check for string argument - var is_method = (typeof arg === 'string'), - args = Array.prototype.slice.call(arguments, 1), - result = null; - if(arg === true && !this.length) { return false; } - this.each(function () { - // get the instance (if there is one) and method (if it exists) - var instance = $.jstree.reference(this), - method = is_method && instance ? instance[arg] : null; - // if calling a method, and method is available - execute on the instance - result = is_method && method ? - method.apply(instance, args) : - null; - // if there is no instance and no method is being called - create one - if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) { - $.jstree.create(this, arg); - } - // if there is an instance and no method is called - return the instance - if( (instance && !is_method) || arg === true ) { - result = instance || false; - } - // if there was a method call which returned a result - break and return the value - if(result !== null && result !== undefined) { - return false; - } - }); - // if there was a method call with a valid return value - return that, otherwise continue the chain - return result !== null && result !== undefined ? - result : this; - }; - /** - * used to find elements containing an instance - * - * __Examples__ - * - * $('div:jstree').each(function () { - * $(this).jstree('destroy'); - * }); - * - * @name $(':jstree') - * @return {jQuery} - */ - $.expr.pseudos.jstree = $.expr.createPseudo(function(search) { - return function(a) { - return $(a).hasClass('jstree') && - $(a).data('jstree') !== undefined; - }; - }); - - /** - * stores all defaults for the core - * @name $.jstree.defaults.core - */ - $.jstree.defaults.core = { - /** - * data configuration - * - * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items). - * - * You can also pass in a HTML string or a JSON array here. - * - * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree. - * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used. - * - * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result. - * - * __Examples__ - * - * // AJAX - * $('#tree').jstree({ - * 'core' : { - * 'data' : { - * 'url' : '/get/children/', - * 'data' : function (node) { - * return { 'id' : node.id }; - * } - * } - * }); - * - * // direct data - * $('#tree').jstree({ - * 'core' : { - * 'data' : [ - * 'Simple root node', - * { - * 'id' : 'node_2', - * 'text' : 'Root node with options', - * 'state' : { 'opened' : true, 'selected' : true }, - * 'children' : [ { 'text' : 'Child 1' }, 'Child 2'] - * } - * ] - * } - * }); - * - * // function - * $('#tree').jstree({ - * 'core' : { - * 'data' : function (obj, callback) { - * callback.call(this, ['Root 1', 'Root 2']); - * } - * }); - * - * @name $.jstree.defaults.core.data - */ - data : false, - /** - * configure the various strings used throughout the tree - * - * You can use an object where the key is the string you need to replace and the value is your replacement. - * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement. - * If left as `false` no replacement is made. - * - * __Examples__ - * - * $('#tree').jstree({ - * 'core' : { - * 'strings' : { - * 'Loading ...' : 'Please wait ...' - * } - * } - * }); - * - * @name $.jstree.defaults.core.strings - */ - strings : false, - /** - * determines what happens when a user tries to modify the structure of the tree - * If left as `false` all operations like create, rename, delete, move or copy are prevented. - * You can set this to `true` to allow all interactions or use a function to have better control. - * - * __Examples__ - * - * $('#tree').jstree({ - * 'core' : { - * 'check_callback' : function (operation, node, node_parent, node_position, more) { - * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node', 'copy_node' or 'edit' - * // in case of 'rename_node' node_position is filled with the new node name - * return operation === 'rename_node' ? true : false; - * } - * } - * }); - * - * @name $.jstree.defaults.core.check_callback - */ - check_callback : false, - /** - * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc) - * @name $.jstree.defaults.core.error - */ - error : $.noop, - /** - * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`) - * @name $.jstree.defaults.core.animation - */ - animation : 200, - /** - * a boolean indicating if multiple nodes can be selected - * @name $.jstree.defaults.core.multiple - */ - multiple : true, - /** - * theme configuration object - * @name $.jstree.defaults.core.themes - */ - themes : { - /** - * the name of the theme to use (if left as `false` the default theme is used) - * @name $.jstree.defaults.core.themes.name - */ - name : false, - /** - * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme. - * @name $.jstree.defaults.core.themes.url - */ - url : false, - /** - * the location of all jstree themes - only used if `url` is set to `true` - * @name $.jstree.defaults.core.themes.dir - */ - dir : false, - /** - * a boolean indicating if connecting dots are shown - * @name $.jstree.defaults.core.themes.dots - */ - dots : true, - /** - * a boolean indicating if node icons are shown - * @name $.jstree.defaults.core.themes.icons - */ - icons : true, - /** - * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container - * @name $.jstree.defaults.core.themes.ellipsis - */ - ellipsis : false, - /** - * a boolean indicating if the tree background is striped - * @name $.jstree.defaults.core.themes.stripes - */ - stripes : false, - /** - * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants) - * @name $.jstree.defaults.core.themes.variant - */ - variant : false, - /** - * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`. - * @name $.jstree.defaults.core.themes.responsive - */ - responsive : false - }, - /** - * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user) - * @name $.jstree.defaults.core.expand_selected_onload - */ - expand_selected_onload : true, - /** - * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true` - * @name $.jstree.defaults.core.worker - */ - worker : true, - /** - * Force node text to plain text (and escape HTML). Defaults to `false` - * @name $.jstree.defaults.core.force_text - */ - force_text : false, - /** - * Should the node be toggled if the text is double clicked. Defaults to `true` - * @name $.jstree.defaults.core.dblclick_toggle - */ - dblclick_toggle : true, - /** - * Should the loaded nodes be part of the state. Defaults to `false` - * @name $.jstree.defaults.core.loaded_state - */ - loaded_state : false, - /** - * Should the last active node be focused when the tree container is blurred and the focused again. This helps working with screen readers. Defaults to `true` - * @name $.jstree.defaults.core.restore_focus - */ - restore_focus : true, - /** - * Default keyboard shortcuts (an object where each key is the button name or combo - like 'enter', 'ctrl-space', 'p', etc and the value is the function to execute in the instance's scope) - * @name $.jstree.defaults.core.keyboard - */ - keyboard : { - 'ctrl-space': function (e) { - // aria defines space only with Ctrl - e.type = "click"; - $(e.currentTarget).trigger(e); - }, - 'enter': function (e) { - // enter - e.type = "click"; - $(e.currentTarget).trigger(e); - }, - 'left': function (e) { - // left - e.preventDefault(); - if(this.is_open(e.currentTarget)) { - this.close_node(e.currentTarget); - } - else { - var o = this.get_parent(e.currentTarget); - if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); } - } - }, - 'up': function (e) { - // up - e.preventDefault(); - var o = this.get_prev_dom(e.currentTarget); - if(o && o.length) { o.children('.jstree-anchor').focus(); } - }, - 'right': function (e) { - // right - e.preventDefault(); - if(this.is_closed(e.currentTarget)) { - this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); }); - } - else if (this.is_open(e.currentTarget)) { - var o = this.get_node(e.currentTarget, true).children('.jstree-children')[0]; - if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); } - } - }, - 'down': function (e) { - // down - e.preventDefault(); - var o = this.get_next_dom(e.currentTarget); - if(o && o.length) { o.children('.jstree-anchor').focus(); } - }, - '*': function (e) { - // aria defines * on numpad as open_all - not very common - this.open_all(); - }, - 'home': function (e) { - // home - e.preventDefault(); - var o = this._firstChild(this.get_container_ul()[0]); - if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); } - }, - 'end': function (e) { - // end - e.preventDefault(); - this.element.find('.jstree-anchor').filter(':visible').last().focus(); - }, - 'f2': function (e) { - // f2 - safe to include - if check_callback is false it will fail - e.preventDefault(); - this.edit(e.currentTarget); - } - } - }; - $.jstree.core.prototype = { - /** - * used to decorate an instance with a plugin. Used internally. - * @private - * @name plugin(deco [, opts]) - * @param {String} deco the plugin to decorate with - * @param {Object} opts options for the plugin - * @return {jsTree} - */ - plugin : function (deco, opts) { - var Child = $.jstree.plugins[deco]; - if(Child) { - this._data[deco] = {}; - Child.prototype = this; - return new Child(opts, this); - } - return this; - }, - /** - * initialize the instance. Used internally. - * @private - * @name init(el, optons) - * @param {DOMElement|jQuery|String} el the element we are transforming - * @param {Object} options options for this instance - * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree - */ - init : function (el, options) { - this._model = { - data : {}, - changed : [], - force_full_redraw : false, - redraw_timeout : false, - default_state : { - loaded : true, - opened : false, - selected : false, - disabled : false - } - }; - this._model.data[$.jstree.root] = { - id : $.jstree.root, - parent : null, - parents : [], - children : [], - children_d : [], - state : { loaded : false } - }; - - this.element = $(el).addClass('jstree jstree-' + this._id); - this.settings = options; - - this._data.core.ready = false; - this._data.core.loaded = false; - this._data.core.rtl = (this.element.css("direction") === "rtl"); - this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl"); - this.element.attr('role','tree'); - if(this.settings.core.multiple) { - this.element.attr('aria-multiselectable', true); - } - if(!this.element.attr('tabindex')) { - this.element.attr('tabindex','0'); - } - - this.bind(); - /** - * triggered after all events are bound - * @event - * @name init.jstree - */ - this.trigger("init"); - - this._data.core.original_container_html = this.element.find(" > ul > li").clone(true); - this._data.core.original_container_html - .find("li").addBack() - .contents().filter(function() { - return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); - }) - .remove(); - this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><"+"a class='jstree-anchor' href='#'>" + this.get_string("Loading ...") + ""); - this.element.attr('aria-activedescendant','j' + this._id + '_loading'); - this._data.core.li_height = this.get_container_ul().children("li").first().outerHeight() || 24; - this._data.core.node = this._create_prototype_node(); - /** - * triggered after the loading text is shown and before loading starts - * @event - * @name loading.jstree - */ - this.trigger("loading"); - this.load_node($.jstree.root); - }, - /** - * destroy an instance - * @name destroy() - * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact - */ - destroy : function (keep_html) { - /** - * triggered before the tree is destroyed - * @event - * @name destroy.jstree - */ - this.trigger("destroy"); - if(this._wrk) { - try { - window.URL.revokeObjectURL(this._wrk); - this._wrk = null; - } - catch (ignore) { } - } - if(!keep_html) { this.element.empty(); } - this.teardown(); - }, - /** - * Create a prototype node - * @name _create_prototype_node() - * @return {DOMElement} - */ - _create_prototype_node : function () { - var _node = document.createElement('LI'), _temp1, _temp2; - _node.setAttribute('role', 'treeitem'); - _temp1 = document.createElement('I'); - _temp1.className = 'jstree-icon jstree-ocl'; - _temp1.setAttribute('role', 'presentation'); - _node.appendChild(_temp1); - _temp1 = document.createElement('A'); - _temp1.className = 'jstree-anchor'; - _temp1.setAttribute('href','#'); - _temp1.setAttribute('tabindex','-1'); - _temp2 = document.createElement('I'); - _temp2.className = 'jstree-icon jstree-themeicon'; - _temp2.setAttribute('role', 'presentation'); - _temp1.appendChild(_temp2); - _node.appendChild(_temp1); - _temp1 = _temp2 = null; - - return _node; - }, - _kbevent_to_func : function (e) { - var keys = { - 8: "Backspace", 9: "Tab", 13: "Return", 19: "Pause", 27: "Esc", - 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", - 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "Print", 45: "Insert", - 46: "Delete", 96: "Numpad0", 97: "Numpad1", 98: "Numpad2", 99 : "Numpad3", - 100: "Numpad4", 101: "Numpad5", 102: "Numpad6", 103: "Numpad7", - 104: "Numpad8", 105: "Numpad9", '-13': "NumpadEnter", 112: "F1", - 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", - 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", 144: "Numlock", - 145: "Scrolllock", 16: 'Shift', 17: 'Ctrl', 18: 'Alt', - 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', - 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a', - 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', - 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o', - 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', - 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.', - 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', - 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*', 173: '-' - }; - var parts = []; - if (e.ctrlKey) { parts.push('ctrl'); } - if (e.altKey) { parts.push('alt'); } - if (e.shiftKey) { parts.push('shift'); } - parts.push(keys[e.which] || e.which); - parts = parts.sort().join('-').toLowerCase(); - - var kb = this.settings.core.keyboard, i, tmp; - for (i in kb) { - if (kb.hasOwnProperty(i)) { - tmp = i; - if (tmp !== '-' && tmp !== '+') { - tmp = tmp.replace('--', '-MINUS').replace('+-', '-MINUS').replace('++', '-PLUS').replace('-+', '-PLUS'); - tmp = tmp.split(/-|\+/).sort().join('-').replace('MINUS', '-').replace('PLUS', '+').toLowerCase(); - } - if (tmp === parts) { - return kb[i]; - } - } - } - return null; - }, - /** - * part of the destroying of an instance. Used internally. - * @private - * @name teardown() - */ - teardown : function () { - this.unbind(); - this.element - .removeClass('jstree') - .removeData('jstree') - .find("[class^='jstree']") - .addBack() - .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); - this.element = null; - }, - /** - * bind all events. Used internally. - * @private - * @name bind() - */ - bind : function () { - var word = '', - tout = null, - was_click = 0; - this.element - .on("dblclick.jstree", function (e) { - if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } - if(document.selection && document.selection.empty) { - document.selection.empty(); - } - else { - if(window.getSelection) { - var sel = window.getSelection(); - try { - sel.removeAllRanges(); - sel.collapse(); - } catch (ignore) { } - } - } - }) - .on("mousedown.jstree", $.proxy(function (e) { - if(e.target === this.element[0]) { - e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome) - was_click = +(new Date()); // ie does not allow to prevent losing focus - } - }, this)) - .on("mousedown.jstree", ".jstree-ocl", function (e) { - e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon - }) - .on("click.jstree", ".jstree-ocl", $.proxy(function (e) { - this.toggle_node(e.target); - }, this)) - .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) { - if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } - if(this.settings.core.dblclick_toggle) { - this.toggle_node(e.target); - } - }, this)) - .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { - e.preventDefault(); - if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); } - this.activate_node(e.currentTarget, e); - }, this)) - .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) { - if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } - if(this._data.core.rtl) { - if(e.which === 37) { e.which = 39; } - else if(e.which === 39) { e.which = 37; } - } - var f = this._kbevent_to_func(e); - if (f) { - var r = f.call(this, e); - if (r === false || r === true) { - return r; - } - } - }, this)) - .on("load_node.jstree", $.proxy(function (e, data) { - if(data.status) { - if(data.node.id === $.jstree.root && !this._data.core.loaded) { - this._data.core.loaded = true; - if(this._firstChild(this.get_container_ul()[0])) { - this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); - } - /** - * triggered after the root node is loaded for the first time - * @event - * @name loaded.jstree - */ - this.trigger("loaded"); - } - if(!this._data.core.ready) { - setTimeout($.proxy(function() { - if(this.element && !this.get_container_ul().find('.jstree-loading').length) { - this._data.core.ready = true; - if(this._data.core.selected.length) { - if(this.settings.core.expand_selected_onload) { - var tmp = [], i, j; - for(i = 0, j = this._data.core.selected.length; i < j; i++) { - tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents); - } - tmp = $.vakata.array_unique(tmp); - for(i = 0, j = tmp.length; i < j; i++) { - this.open_node(tmp[i], false, 0); - } - } - this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected }); - } - /** - * triggered after all nodes are finished loading - * @event - * @name ready.jstree - */ - this.trigger("ready"); - } - }, this), 0); - } - } - }, this)) - // quick searching when the tree is focused - .on('keypress.jstree', $.proxy(function (e) { - if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } - if(tout) { clearTimeout(tout); } - tout = setTimeout(function () { - word = ''; - }, 500); - - var chr = String.fromCharCode(e.which).toLowerCase(), - col = this.element.find('.jstree-anchor').filter(':visible'), - ind = col.index(document.activeElement) || 0, - end = false; - word += chr; - - // match for whole word from current node down (including the current node) - if(word.length > 1) { - col.slice(ind).each($.proxy(function (i, v) { - if($(v).text().toLowerCase().indexOf(word) === 0) { - $(v).focus(); - end = true; - return false; - } - }, this)); - if(end) { return; } - - // match for whole word from the beginning of the tree - col.slice(0, ind).each($.proxy(function (i, v) { - if($(v).text().toLowerCase().indexOf(word) === 0) { - $(v).focus(); - end = true; - return false; - } - }, this)); - if(end) { return; } - } - // list nodes that start with that letter (only if word consists of a single char) - if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) { - // search for the next node starting with that letter - col.slice(ind + 1).each($.proxy(function (i, v) { - if($(v).text().toLowerCase().charAt(0) === chr) { - $(v).focus(); - end = true; - return false; - } - }, this)); - if(end) { return; } - - // search from the beginning - col.slice(0, ind + 1).each($.proxy(function (i, v) { - if($(v).text().toLowerCase().charAt(0) === chr) { - $(v).focus(); - end = true; - return false; - } - }, this)); - if(end) { return; } - } - }, this)) - // THEME RELATED - .on("init.jstree", $.proxy(function () { - var s = this.settings.core.themes; - this._data.core.themes.dots = s.dots; - this._data.core.themes.stripes = s.stripes; - this._data.core.themes.icons = s.icons; - this._data.core.themes.ellipsis = s.ellipsis; - this.set_theme(s.name || "default", s.url); - this.set_theme_variant(s.variant); - }, this)) - .on("loading.jstree", $.proxy(function () { - this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ](); - this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ](); - this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ](); - this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ](); - }, this)) - .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) { - this._data.core.focused = null; - $(e.currentTarget).filter('.jstree-hovered').mouseleave(); - this.element.attr('tabindex', '0'); - }, this)) - .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) { - var tmp = this.get_node(e.currentTarget); - if(tmp && tmp.id) { - this._data.core.focused = tmp.id; - } - this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave(); - $(e.currentTarget).mouseenter(); - this.element.attr('tabindex', '-1'); - }, this)) - .on('focus.jstree', $.proxy(function () { - if(+(new Date()) - was_click > 500 && !this._data.core.focused && this.settings.core.restore_focus) { - was_click = 0; - var act = this.get_node(this.element.attr('aria-activedescendant'), true); - if(act) { - act.find('> .jstree-anchor').focus(); - } - } - }, this)) - .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) { - this.hover_node(e.currentTarget); - }, this)) - .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) { - this.dehover_node(e.currentTarget); - }, this)); - }, - /** - * part of the destroying of an instance. Used internally. - * @private - * @name unbind() - */ - unbind : function () { - this.element.off('.jstree'); - $(document).off('.jstree-' + this._id); - }, - /** - * trigger an event. Used internally. - * @private - * @name trigger(ev [, data]) - * @param {String} ev the name of the event to trigger - * @param {Object} data additional data to pass with the event - */ - trigger : function (ev, data) { - if(!data) { - data = {}; - } - data.instance = this; - this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data); - }, - /** - * returns the jQuery extended instance container - * @name get_container() - * @return {jQuery} - */ - get_container : function () { - return this.element; - }, - /** - * returns the jQuery extended main UL node inside the instance container. Used internally. - * @private - * @name get_container_ul() - * @return {jQuery} - */ - get_container_ul : function () { - return this.element.children(".jstree-children").first(); - }, - /** - * gets string replacements (localization). Used internally. - * @private - * @name get_string(key) - * @param {String} key - * @return {String} - */ - get_string : function (key) { - var a = this.settings.core.strings; - if($.isFunction(a)) { return a.call(this, key); } - if(a && a[key]) { return a[key]; } - return key; - }, - /** - * gets the first child of a DOM node. Used internally. - * @private - * @name _firstChild(dom) - * @param {DOMElement} dom - * @return {DOMElement} - */ - _firstChild : function (dom) { - dom = dom ? dom.firstChild : null; - while(dom !== null && dom.nodeType !== 1) { - dom = dom.nextSibling; - } - return dom; - }, - /** - * gets the next sibling of a DOM node. Used internally. - * @private - * @name _nextSibling(dom) - * @param {DOMElement} dom - * @return {DOMElement} - */ - _nextSibling : function (dom) { - dom = dom ? dom.nextSibling : null; - while(dom !== null && dom.nodeType !== 1) { - dom = dom.nextSibling; - } - return dom; - }, - /** - * gets the previous sibling of a DOM node. Used internally. - * @private - * @name _previousSibling(dom) - * @param {DOMElement} dom - * @return {DOMElement} - */ - _previousSibling : function (dom) { - dom = dom ? dom.previousSibling : null; - while(dom !== null && dom.nodeType !== 1) { - dom = dom.previousSibling; - } - return dom; - }, - /** - * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc) - * @name get_node(obj [, as_dom]) - * @param {mixed} obj - * @param {Boolean} as_dom - * @return {Object|jQuery} - */ - get_node : function (obj, as_dom) { - if(obj && obj.id) { - obj = obj.id; - } - if (obj instanceof jQuery && obj.length && obj[0].id) { - obj = obj[0].id; - } - var dom; - try { - if(this._model.data[obj]) { - obj = this._model.data[obj]; - } - else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) { - obj = this._model.data[obj.replace(/^#/, '')]; - } - else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { - obj = this._model.data[dom.closest('.jstree-node').attr('id')]; - } - else if((dom = this.element.find(obj)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { - obj = this._model.data[dom.closest('.jstree-node').attr('id')]; - } - else if((dom = this.element.find(obj)).length && dom.hasClass('jstree')) { - obj = this._model.data[$.jstree.root]; - } - else { - return false; - } - - if(as_dom) { - obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); - } - return obj; - } catch (ex) { return false; } - }, - /** - * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array) - * @name get_path(obj [, glue, ids]) - * @param {mixed} obj the node - * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned - * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used - * @return {mixed} - */ - get_path : function (obj, glue, ids) { - obj = obj.parents ? obj : this.get_node(obj); - if(!obj || obj.id === $.jstree.root || !obj.parents) { - return false; - } - var i, j, p = []; - p.push(ids ? obj.id : obj.text); - for(i = 0, j = obj.parents.length; i < j; i++) { - p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i])); - } - p = p.reverse().slice(1); - return glue ? p.join(glue) : p; - }, - /** - * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned. - * @name get_next_dom(obj [, strict]) - * @param {mixed} obj - * @param {Boolean} strict - * @return {jQuery} - */ - get_next_dom : function (obj, strict) { - var tmp; - obj = this.get_node(obj, true); - if(obj[0] === this.element[0]) { - tmp = this._firstChild(this.get_container_ul()[0]); - while (tmp && tmp.offsetHeight === 0) { - tmp = this._nextSibling(tmp); - } - return tmp ? $(tmp) : false; - } - if(!obj || !obj.length) { - return false; - } - if(strict) { - tmp = obj[0]; - do { - tmp = this._nextSibling(tmp); - } while (tmp && tmp.offsetHeight === 0); - return tmp ? $(tmp) : false; - } - if(obj.hasClass("jstree-open")) { - tmp = this._firstChild(obj.children('.jstree-children')[0]); - while (tmp && tmp.offsetHeight === 0) { - tmp = this._nextSibling(tmp); - } - if(tmp !== null) { - return $(tmp); - } - } - tmp = obj[0]; - do { - tmp = this._nextSibling(tmp); - } while (tmp && tmp.offsetHeight === 0); - if(tmp !== null) { - return $(tmp); - } - return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first(); - }, - /** - * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned. - * @name get_prev_dom(obj [, strict]) - * @param {mixed} obj - * @param {Boolean} strict - * @return {jQuery} - */ - get_prev_dom : function (obj, strict) { - var tmp; - obj = this.get_node(obj, true); - if(obj[0] === this.element[0]) { - tmp = this.get_container_ul()[0].lastChild; - while (tmp && tmp.offsetHeight === 0) { - tmp = this._previousSibling(tmp); - } - return tmp ? $(tmp) : false; - } - if(!obj || !obj.length) { - return false; - } - if(strict) { - tmp = obj[0]; - do { - tmp = this._previousSibling(tmp); - } while (tmp && tmp.offsetHeight === 0); - return tmp ? $(tmp) : false; - } - tmp = obj[0]; - do { - tmp = this._previousSibling(tmp); - } while (tmp && tmp.offsetHeight === 0); - if(tmp !== null) { - obj = $(tmp); - while(obj.hasClass("jstree-open")) { - obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last"); - } - return obj; - } - tmp = obj[0].parentNode.parentNode; - return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false; - }, - /** - * get the parent ID of a node - * @name get_parent(obj) - * @param {mixed} obj - * @return {String} - */ - get_parent : function (obj) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - return obj.parent; - }, - /** - * get a jQuery collection of all the children of a node (node must be rendered), returns false on error - * @name get_children_dom(obj) - * @param {mixed} obj - * @return {jQuery} - */ - get_children_dom : function (obj) { - obj = this.get_node(obj, true); - if(obj[0] === this.element[0]) { - return this.get_container_ul().children(".jstree-node"); - } - if(!obj || !obj.length) { - return false; - } - return obj.children(".jstree-children").children(".jstree-node"); - }, - /** - * checks if a node has children - * @name is_parent(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_parent : function (obj) { - obj = this.get_node(obj); - return obj && (obj.state.loaded === false || obj.children.length > 0); - }, - /** - * checks if a node is loaded (its children are available) - * @name is_loaded(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_loaded : function (obj) { - obj = this.get_node(obj); - return obj && obj.state.loaded; - }, - /** - * check if a node is currently loading (fetching children) - * @name is_loading(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_loading : function (obj) { - obj = this.get_node(obj); - return obj && obj.state && obj.state.loading; - }, - /** - * check if a node is opened - * @name is_open(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_open : function (obj) { - obj = this.get_node(obj); - return obj && obj.state.opened; - }, - /** - * check if a node is in a closed state - * @name is_closed(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_closed : function (obj) { - obj = this.get_node(obj); - return obj && this.is_parent(obj) && !obj.state.opened; - }, - /** - * check if a node has no children - * @name is_leaf(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_leaf : function (obj) { - return !this.is_parent(obj); - }, - /** - * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array. - * @name load_node(obj [, callback]) - * @param {mixed} obj - * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status - * @return {Boolean} - * @trigger load_node.jstree - */ - load_node : function (obj, callback) { - var k, l, i, j, c; - if($.isArray(obj)) { - this._load_nodes(obj.slice(), callback); - return true; - } - obj = this.get_node(obj); - if(!obj) { - if(callback) { callback.call(this, obj, false); } - return false; - } - // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again? - if(obj.state.loaded) { - obj.state.loaded = false; - for(i = 0, j = obj.parents.length; i < j; i++) { - this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { - return $.inArray(v, obj.children_d) === -1; - }); - } - for(k = 0, l = obj.children_d.length; k < l; k++) { - if(this._model.data[obj.children_d[k]].state.selected) { - c = true; - } - delete this._model.data[obj.children_d[k]]; - } - if (c) { - this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { - return $.inArray(v, obj.children_d) === -1; - }); - } - obj.children = []; - obj.children_d = []; - if(c) { - this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected }); - } - } - obj.state.failed = false; - obj.state.loading = true; - this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true); - this._load_node(obj, $.proxy(function (status) { - obj = this._model.data[obj.id]; - obj.state.loading = false; - obj.state.loaded = status; - obj.state.failed = !obj.state.loaded; - var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false; - for(i = 0, j = obj.children.length; i < j; i++) { - if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) { - has_children = true; - break; - } - } - if(obj.state.loaded && dom && dom.length) { - dom.removeClass('jstree-closed jstree-open jstree-leaf'); - if (!has_children) { - dom.addClass('jstree-leaf'); - } - else { - if (obj.id !== '#') { - dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed'); - } - } - } - dom.removeClass("jstree-loading").attr('aria-busy',false); - /** - * triggered after a node is loaded - * @event - * @name load_node.jstree - * @param {Object} node the node that was loading - * @param {Boolean} status was the node loaded successfully - */ - this.trigger('load_node', { "node" : obj, "status" : status }); - if(callback) { - callback.call(this, obj, status); - } - }, this)); - return true; - }, - /** - * load an array of nodes (will also load unavailable nodes as soon as they appear in the structure). Used internally. - * @private - * @name _load_nodes(nodes [, callback]) - * @param {array} nodes - * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes - */ - _load_nodes : function (nodes, callback, is_callback, force_reload) { - var r = true, - c = function () { this._load_nodes(nodes, callback, true); }, - m = this._model.data, i, j, tmp = []; - for(i = 0, j = nodes.length; i < j; i++) { - if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) { - if(!this.is_loading(nodes[i])) { - this.load_node(nodes[i], c); - } - r = false; - } - } - if(r) { - for(i = 0, j = nodes.length; i < j; i++) { - if(m[nodes[i]] && m[nodes[i]].state.loaded) { - tmp.push(nodes[i]); - } - } - if(callback && !callback.done) { - callback.call(this, tmp); - callback.done = true; - } - } - }, - /** - * loads all unloaded nodes - * @name load_all([obj, callback]) - * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree - * @param {function} callback a function to be executed once loading all the nodes is complete, - * @trigger load_all.jstree - */ - load_all : function (obj, callback) { - if(!obj) { obj = $.jstree.root; } - obj = this.get_node(obj); - if(!obj) { return false; } - var to_load = [], - m = this._model.data, - c = m[obj.id].children_d, - i, j; - if(obj.state && !obj.state.loaded) { - to_load.push(obj.id); - } - for(i = 0, j = c.length; i < j; i++) { - if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) { - to_load.push(c[i]); - } - } - if(to_load.length) { - this._load_nodes(to_load, function () { - this.load_all(obj, callback); - }); - } - else { - /** - * triggered after a load_all call completes - * @event - * @name load_all.jstree - * @param {Object} node the recursively loaded node - */ - if(callback) { callback.call(this, obj); } - this.trigger('load_all', { "node" : obj }); - } - }, - /** - * handles the actual loading of a node. Used only internally. - * @private - * @name _load_node(obj [, callback]) - * @param {mixed} obj - * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status - * @return {Boolean} - */ - _load_node : function (obj, callback) { - var s = this.settings.core.data, t; - var notTextOrCommentNode = function notTextOrCommentNode () { - return this.nodeType !== 3 && this.nodeType !== 8; - }; - // use original HTML - if(!s) { - if(obj.id === $.jstree.root) { - return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) { - callback.call(this, status); - }); - } - else { - return callback.call(this, false); - } - // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false); - } - if($.isFunction(s)) { - return s.call(this, obj, $.proxy(function (d) { - if(d === false) { - callback.call(this, false); - } - else { - this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) { - callback.call(this, status); - }); - } - // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d)); - }, this)); - } - if(typeof s === 'object') { - if(s.url) { - s = $.extend(true, {}, s); - if($.isFunction(s.url)) { - s.url = s.url.call(this, obj); - } - if($.isFunction(s.data)) { - s.data = s.data.call(this, obj); - } - return $.ajax(s) - .done($.proxy(function (d,t,x) { - var type = x.getResponseHeader('Content-Type'); - if((type && type.indexOf('json') !== -1) || typeof d === "object") { - return this._append_json_data(obj, d, function (status) { callback.call(this, status); }); - //return callback.call(this, this._append_json_data(obj, d)); - } - if((type && type.indexOf('html') !== -1) || typeof d === "string") { - return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); - // return callback.call(this, this._append_html_data(obj, $(d))); - } - this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) }; - this.settings.core.error.call(this, this._data.core.last_error); - return callback.call(this, false); - }, this)) - .fail($.proxy(function (f) { - this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) }; - callback.call(this, false); - this.settings.core.error.call(this, this._data.core.last_error); - }, this)); - } - if ($.isArray(s)) { - t = $.extend(true, [], s); - } else if ($.isPlainObject(s)) { - t = $.extend(true, {}, s); - } else { - t = s; - } - if(obj.id === $.jstree.root) { - return this._append_json_data(obj, t, function (status) { - callback.call(this, status); - }); - } - else { - this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; - this.settings.core.error.call(this, this._data.core.last_error); - return callback.call(this, false); - } - //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) ); - } - if(typeof s === 'string') { - if(obj.id === $.jstree.root) { - return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) { - callback.call(this, status); - }); - } - else { - this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; - this.settings.core.error.call(this, this._data.core.last_error); - return callback.call(this, false); - } - //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) ); - } - return callback.call(this, false); - }, - /** - * adds a node to the list of nodes to redraw. Used only internally. - * @private - * @name _node_changed(obj [, callback]) - * @param {mixed} obj - */ - _node_changed : function (obj) { - obj = this.get_node(obj); - if (obj && $.inArray(obj.id, this._model.changed) === -1) { - this._model.changed.push(obj.id); - } - }, - /** - * appends HTML content to the tree. Used internally. - * @private - * @name _append_html_data(obj, data) - * @param {mixed} obj the node to append to - * @param {String} data the HTML string to parse and append - * @trigger model.jstree, changed.jstree - */ - _append_html_data : function (dom, data, cb) { - dom = this.get_node(dom); - dom.children = []; - dom.children_d = []; - var dat = data.is('ul') ? data.children() : data, - par = dom.id, - chd = [], - dpc = [], - m = this._model.data, - p = m[par], - s = this._data.core.selected.length, - tmp, i, j; - dat.each($.proxy(function (i, v) { - tmp = this._parse_model_from_html($(v), par, p.parents.concat()); - if(tmp) { - chd.push(tmp); - dpc.push(tmp); - if(m[tmp].children_d.length) { - dpc = dpc.concat(m[tmp].children_d); - } - } - }, this)); - p.children = chd; - p.children_d = dpc; - for(i = 0, j = p.parents.length; i < j; i++) { - m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); - } - /** - * triggered when new data is inserted to the tree model - * @event - * @name model.jstree - * @param {Array} nodes an array of node IDs - * @param {String} parent the parent ID of the nodes - */ - this.trigger('model', { "nodes" : dpc, 'parent' : par }); - if(par !== $.jstree.root) { - this._node_changed(par); - this.redraw(); - } - else { - this.get_container_ul().children('.jstree-initial-node').remove(); - this.redraw(true); - } - if(this._data.core.selected.length !== s) { - this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); - } - cb.call(this, true); - }, - /** - * appends JSON content to the tree. Used internally. - * @private - * @name _append_json_data(obj, data) - * @param {mixed} obj the node to append to - * @param {String} data the JSON object to parse and append - * @param {Boolean} force_processing internal param - do not set - * @trigger model.jstree, changed.jstree - */ - _append_json_data : function (dom, data, cb, force_processing) { - if(this.element === null) { return; } - dom = this.get_node(dom); - dom.children = []; - dom.children_d = []; - // *%$@!!! - if(data.d) { - data = data.d; - if(typeof data === "string") { - data = JSON.parse(data); - } - } - if(!$.isArray(data)) { data = [data]; } - var w = null, - args = { - 'df' : this._model.default_state, - 'dat' : data, - 'par' : dom.id, - 'm' : this._model.data, - 't_id' : this._id, - 't_cnt' : this._cnt, - 'sel' : this._data.core.selected - }, - func = function (data, undefined) { - if(data.data) { data = data.data; } - var dat = data.dat, - par = data.par, - chd = [], - dpc = [], - add = [], - df = data.df, - t_id = data.t_id, - t_cnt = data.t_cnt, - m = data.m, - p = m[par], - sel = data.sel, - tmp, i, j, rslt, - parse_flat = function (d, p, ps) { - if(!ps) { ps = []; } - else { ps = ps.concat(); } - if(p) { ps.unshift(p); } - var tid = d.id.toString(), - i, j, c, e, - tmp = { - id : tid, - text : d.text || '', - icon : d.icon !== undefined ? d.icon : true, - parent : p, - parents : ps, - children : d.children || [], - children_d : d.children_d || [], - data : d.data, - state : { }, - li_attr : { id : false }, - a_attr : { href : '#' }, - original : false - }; - for(i in df) { - if(df.hasOwnProperty(i)) { - tmp.state[i] = df[i]; - } - } - if(d && d.data && d.data.jstree && d.data.jstree.icon) { - tmp.icon = d.data.jstree.icon; - } - if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { - tmp.icon = true; - } - if(d && d.data) { - tmp.data = d.data; - if(d.data.jstree) { - for(i in d.data.jstree) { - if(d.data.jstree.hasOwnProperty(i)) { - tmp.state[i] = d.data.jstree[i]; - } - } - } - } - if(d && typeof d.state === 'object') { - for (i in d.state) { - if(d.state.hasOwnProperty(i)) { - tmp.state[i] = d.state[i]; - } - } - } - if(d && typeof d.li_attr === 'object') { - for (i in d.li_attr) { - if(d.li_attr.hasOwnProperty(i)) { - tmp.li_attr[i] = d.li_attr[i]; - } - } - } - if(!tmp.li_attr.id) { - tmp.li_attr.id = tid; - } - if(d && typeof d.a_attr === 'object') { - for (i in d.a_attr) { - if(d.a_attr.hasOwnProperty(i)) { - tmp.a_attr[i] = d.a_attr[i]; - } - } - } - if(d && d.children && d.children === true) { - tmp.state.loaded = false; - tmp.children = []; - tmp.children_d = []; - } - m[tmp.id] = tmp; - for(i = 0, j = tmp.children.length; i < j; i++) { - c = parse_flat(m[tmp.children[i]], tmp.id, ps); - e = m[c]; - tmp.children_d.push(c); - if(e.children_d.length) { - tmp.children_d = tmp.children_d.concat(e.children_d); - } - } - delete d.data; - delete d.children; - m[tmp.id].original = d; - if(tmp.state.selected) { - add.push(tmp.id); - } - return tmp.id; - }, - parse_nest = function (d, p, ps) { - if(!ps) { ps = []; } - else { ps = ps.concat(); } - if(p) { ps.unshift(p); } - var tid = false, i, j, c, e, tmp; - do { - tid = 'j' + t_id + '_' + (++t_cnt); - } while(m[tid]); - - tmp = { - id : false, - text : typeof d === 'string' ? d : '', - icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, - parent : p, - parents : ps, - children : [], - children_d : [], - data : null, - state : { }, - li_attr : { id : false }, - a_attr : { href : '#' }, - original : false - }; - for(i in df) { - if(df.hasOwnProperty(i)) { - tmp.state[i] = df[i]; - } - } - if(d && d.id) { tmp.id = d.id.toString(); } - if(d && d.text) { tmp.text = d.text; } - if(d && d.data && d.data.jstree && d.data.jstree.icon) { - tmp.icon = d.data.jstree.icon; - } - if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { - tmp.icon = true; - } - if(d && d.data) { - tmp.data = d.data; - if(d.data.jstree) { - for(i in d.data.jstree) { - if(d.data.jstree.hasOwnProperty(i)) { - tmp.state[i] = d.data.jstree[i]; - } - } - } - } - if(d && typeof d.state === 'object') { - for (i in d.state) { - if(d.state.hasOwnProperty(i)) { - tmp.state[i] = d.state[i]; - } - } - } - if(d && typeof d.li_attr === 'object') { - for (i in d.li_attr) { - if(d.li_attr.hasOwnProperty(i)) { - tmp.li_attr[i] = d.li_attr[i]; - } - } - } - if(tmp.li_attr.id && !tmp.id) { - tmp.id = tmp.li_attr.id.toString(); - } - if(!tmp.id) { - tmp.id = tid; - } - if(!tmp.li_attr.id) { - tmp.li_attr.id = tmp.id; - } - if(d && typeof d.a_attr === 'object') { - for (i in d.a_attr) { - if(d.a_attr.hasOwnProperty(i)) { - tmp.a_attr[i] = d.a_attr[i]; - } - } - } - if(d && d.children && d.children.length) { - for(i = 0, j = d.children.length; i < j; i++) { - c = parse_nest(d.children[i], tmp.id, ps); - e = m[c]; - tmp.children.push(c); - if(e.children_d.length) { - tmp.children_d = tmp.children_d.concat(e.children_d); - } - } - tmp.children_d = tmp.children_d.concat(tmp.children); - } - if(d && d.children && d.children === true) { - tmp.state.loaded = false; - tmp.children = []; - tmp.children_d = []; - } - delete d.data; - delete d.children; - tmp.original = d; - m[tmp.id] = tmp; - if(tmp.state.selected) { - add.push(tmp.id); - } - return tmp.id; - }; - - if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) { - // Flat JSON support (for easy import from DB): - // 1) convert to object (foreach) - for(i = 0, j = dat.length; i < j; i++) { - if(!dat[i].children) { - dat[i].children = []; - } - if(!dat[i].state) { - dat[i].state = {}; - } - m[dat[i].id.toString()] = dat[i]; - } - // 2) populate children (foreach) - for(i = 0, j = dat.length; i < j; i++) { - if (!m[dat[i].parent.toString()]) { - this._data.core.last_error = { 'error' : 'parse', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Node with invalid parent', 'data' : JSON.stringify({ 'id' : dat[i].id.toString(), 'parent' : dat[i].parent.toString() }) }; - this.settings.core.error.call(this, this._data.core.last_error); - continue; - } - - m[dat[i].parent.toString()].children.push(dat[i].id.toString()); - // populate parent.children_d - p.children_d.push(dat[i].id.toString()); - } - // 3) normalize && populate parents and children_d with recursion - for(i = 0, j = p.children.length; i < j; i++) { - tmp = parse_flat(m[p.children[i]], par, p.parents.concat()); - dpc.push(tmp); - if(m[tmp].children_d.length) { - dpc = dpc.concat(m[tmp].children_d); - } - } - for(i = 0, j = p.parents.length; i < j; i++) { - m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); - } - // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true; - rslt = { - 'cnt' : t_cnt, - 'mod' : m, - 'sel' : sel, - 'par' : par, - 'dpc' : dpc, - 'add' : add - }; - } - else { - for(i = 0, j = dat.length; i < j; i++) { - tmp = parse_nest(dat[i], par, p.parents.concat()); - if(tmp) { - chd.push(tmp); - dpc.push(tmp); - if(m[tmp].children_d.length) { - dpc = dpc.concat(m[tmp].children_d); - } - } - } - p.children = chd; - p.children_d = dpc; - for(i = 0, j = p.parents.length; i < j; i++) { - m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); - } - rslt = { - 'cnt' : t_cnt, - 'mod' : m, - 'sel' : sel, - 'par' : par, - 'dpc' : dpc, - 'add' : add - }; - } - if(typeof window === 'undefined' || typeof window.document === 'undefined') { - postMessage(rslt); - } - else { - return rslt; - } - }, - rslt = function (rslt, worker) { - if(this.element === null) { return; } - this._cnt = rslt.cnt; - var i, m = this._model.data; - for (i in m) { - if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) { - rslt.mod[i].state.loading = true; - } - } - this._model.data = rslt.mod; // breaks the reference in load_node - careful - - if(worker) { - var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(); - m = this._model.data; - // if selection was changed while calculating in worker - if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) { - // deselect nodes that are no longer selected - for(i = 0, j = r.length; i < j; i++) { - if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) { - m[r[i]].state.selected = false; - } - } - // select nodes that were selected in the mean time - for(i = 0, j = s.length; i < j; i++) { - if($.inArray(s[i], r) === -1) { - m[s[i]].state.selected = true; - } - } - } - } - if(rslt.add.length) { - this._data.core.selected = this._data.core.selected.concat(rslt.add); - } - - this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par }); - - if(rslt.par !== $.jstree.root) { - this._node_changed(rslt.par); - this.redraw(); - } - else { - // this.get_container_ul().children('.jstree-initial-node').remove(); - this.redraw(true); - } - if(rslt.add.length) { - this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); - } - cb.call(this, true); - }; - if(this.settings.core.worker && window.Blob && window.URL && window.Worker) { - try { - if(this._wrk === null) { - this._wrk = window.URL.createObjectURL( - new window.Blob( - ['self.onmessage = ' + func.toString()], - {type:"text/javascript"} - ) - ); - } - if(!this._data.core.working || force_processing) { - this._data.core.working = true; - w = new window.Worker(this._wrk); - w.onmessage = $.proxy(function (e) { - rslt.call(this, e.data, true); - try { w.terminate(); w = null; } catch(ignore) { } - if(this._data.core.worker_queue.length) { - this._append_json_data.apply(this, this._data.core.worker_queue.shift()); - } - else { - this._data.core.working = false; - } - }, this); - if(!args.par) { - if(this._data.core.worker_queue.length) { - this._append_json_data.apply(this, this._data.core.worker_queue.shift()); - } - else { - this._data.core.working = false; - } - } - else { - w.postMessage(args); - } - } - else { - this._data.core.worker_queue.push([dom, data, cb, true]); - } - } - catch(e) { - rslt.call(this, func(args), false); - if(this._data.core.worker_queue.length) { - this._append_json_data.apply(this, this._data.core.worker_queue.shift()); - } - else { - this._data.core.working = false; - } - } - } - else { - rslt.call(this, func(args), false); - } - }, - /** - * parses a node from a jQuery object and appends them to the in memory tree model. Used internally. - * @private - * @name _parse_model_from_html(d [, p, ps]) - * @param {jQuery} d the jQuery object to parse - * @param {String} p the parent ID - * @param {Array} ps list of all parents - * @return {String} the ID of the object added to the model - */ - _parse_model_from_html : function (d, p, ps) { - if(!ps) { ps = []; } - else { ps = [].concat(ps); } - if(p) { ps.unshift(p); } - var c, e, m = this._model.data, - data = { - id : false, - text : false, - icon : true, - parent : p, - parents : ps, - children : [], - children_d : [], - data : null, - state : { }, - li_attr : { id : false }, - a_attr : { href : '#' }, - original : false - }, i, tmp, tid; - for(i in this._model.default_state) { - if(this._model.default_state.hasOwnProperty(i)) { - data.state[i] = this._model.default_state[i]; - } - } - tmp = $.vakata.attributes(d, true); - $.each(tmp, function (i, v) { - v = $.trim(v); - if(!v.length) { return true; } - data.li_attr[i] = v; - if(i === 'id') { - data.id = v.toString(); - } - }); - tmp = d.children('a').first(); - if(tmp.length) { - tmp = $.vakata.attributes(tmp, true); - $.each(tmp, function (i, v) { - v = $.trim(v); - if(v.length) { - data.a_attr[i] = v; - } - }); - } - tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone(); - tmp.children("ins, i, ul").remove(); - tmp = tmp.html(); - tmp = $('
').html(tmp); - data.text = this.settings.core.force_text ? tmp.text() : tmp.html(); - tmp = d.data(); - data.data = tmp ? $.extend(true, {}, tmp) : null; - data.state.opened = d.hasClass('jstree-open'); - data.state.selected = d.children('a').hasClass('jstree-clicked'); - data.state.disabled = d.children('a').hasClass('jstree-disabled'); - if(data.data && data.data.jstree) { - for(i in data.data.jstree) { - if(data.data.jstree.hasOwnProperty(i)) { - data.state[i] = data.data.jstree[i]; - } - } - } - tmp = d.children("a").children(".jstree-themeicon"); - if(tmp.length) { - data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel'); - } - if(data.state.icon !== undefined) { - data.icon = data.state.icon; - } - if(data.icon === undefined || data.icon === null || data.icon === "") { - data.icon = true; - } - tmp = d.children("ul").children("li"); - do { - tid = 'j' + this._id + '_' + (++this._cnt); - } while(m[tid]); - data.id = data.li_attr.id ? data.li_attr.id.toString() : tid; - if(tmp.length) { - tmp.each($.proxy(function (i, v) { - c = this._parse_model_from_html($(v), data.id, ps); - e = this._model.data[c]; - data.children.push(c); - if(e.children_d.length) { - data.children_d = data.children_d.concat(e.children_d); - } - }, this)); - data.children_d = data.children_d.concat(data.children); - } - else { - if(d.hasClass('jstree-closed')) { - data.state.loaded = false; - } - } - if(data.li_attr['class']) { - data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open',''); - } - if(data.a_attr['class']) { - data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled',''); - } - m[data.id] = data; - if(data.state.selected) { - this._data.core.selected.push(data.id); - } - return data.id; - }, - /** - * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally. - * @private - * @name _parse_model_from_flat_json(d [, p, ps]) - * @param {Object} d the JSON object to parse - * @param {String} p the parent ID - * @param {Array} ps list of all parents - * @return {String} the ID of the object added to the model - */ - _parse_model_from_flat_json : function (d, p, ps) { - if(!ps) { ps = []; } - else { ps = ps.concat(); } - if(p) { ps.unshift(p); } - var tid = d.id.toString(), - m = this._model.data, - df = this._model.default_state, - i, j, c, e, - tmp = { - id : tid, - text : d.text || '', - icon : d.icon !== undefined ? d.icon : true, - parent : p, - parents : ps, - children : d.children || [], - children_d : d.children_d || [], - data : d.data, - state : { }, - li_attr : { id : false }, - a_attr : { href : '#' }, - original : false - }; - for(i in df) { - if(df.hasOwnProperty(i)) { - tmp.state[i] = df[i]; - } - } - if(d && d.data && d.data.jstree && d.data.jstree.icon) { - tmp.icon = d.data.jstree.icon; - } - if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { - tmp.icon = true; - } - if(d && d.data) { - tmp.data = d.data; - if(d.data.jstree) { - for(i in d.data.jstree) { - if(d.data.jstree.hasOwnProperty(i)) { - tmp.state[i] = d.data.jstree[i]; - } - } - } - } - if(d && typeof d.state === 'object') { - for (i in d.state) { - if(d.state.hasOwnProperty(i)) { - tmp.state[i] = d.state[i]; - } - } - } - if(d && typeof d.li_attr === 'object') { - for (i in d.li_attr) { - if(d.li_attr.hasOwnProperty(i)) { - tmp.li_attr[i] = d.li_attr[i]; - } - } - } - if(!tmp.li_attr.id) { - tmp.li_attr.id = tid; - } - if(d && typeof d.a_attr === 'object') { - for (i in d.a_attr) { - if(d.a_attr.hasOwnProperty(i)) { - tmp.a_attr[i] = d.a_attr[i]; - } - } - } - if(d && d.children && d.children === true) { - tmp.state.loaded = false; - tmp.children = []; - tmp.children_d = []; - } - m[tmp.id] = tmp; - for(i = 0, j = tmp.children.length; i < j; i++) { - c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps); - e = m[c]; - tmp.children_d.push(c); - if(e.children_d.length) { - tmp.children_d = tmp.children_d.concat(e.children_d); - } - } - delete d.data; - delete d.children; - m[tmp.id].original = d; - if(tmp.state.selected) { - this._data.core.selected.push(tmp.id); - } - return tmp.id; - }, - /** - * parses a node from a JSON object and appends it to the in memory tree model. Used internally. - * @private - * @name _parse_model_from_json(d [, p, ps]) - * @param {Object} d the JSON object to parse - * @param {String} p the parent ID - * @param {Array} ps list of all parents - * @return {String} the ID of the object added to the model - */ - _parse_model_from_json : function (d, p, ps) { - if(!ps) { ps = []; } - else { ps = ps.concat(); } - if(p) { ps.unshift(p); } - var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp; - do { - tid = 'j' + this._id + '_' + (++this._cnt); - } while(m[tid]); - - tmp = { - id : false, - text : typeof d === 'string' ? d : '', - icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, - parent : p, - parents : ps, - children : [], - children_d : [], - data : null, - state : { }, - li_attr : { id : false }, - a_attr : { href : '#' }, - original : false - }; - for(i in df) { - if(df.hasOwnProperty(i)) { - tmp.state[i] = df[i]; - } - } - if(d && d.id) { tmp.id = d.id.toString(); } - if(d && d.text) { tmp.text = d.text; } - if(d && d.data && d.data.jstree && d.data.jstree.icon) { - tmp.icon = d.data.jstree.icon; - } - if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { - tmp.icon = true; - } - if(d && d.data) { - tmp.data = d.data; - if(d.data.jstree) { - for(i in d.data.jstree) { - if(d.data.jstree.hasOwnProperty(i)) { - tmp.state[i] = d.data.jstree[i]; - } - } - } - } - if(d && typeof d.state === 'object') { - for (i in d.state) { - if(d.state.hasOwnProperty(i)) { - tmp.state[i] = d.state[i]; - } - } - } - if(d && typeof d.li_attr === 'object') { - for (i in d.li_attr) { - if(d.li_attr.hasOwnProperty(i)) { - tmp.li_attr[i] = d.li_attr[i]; - } - } - } - if(tmp.li_attr.id && !tmp.id) { - tmp.id = tmp.li_attr.id.toString(); - } - if(!tmp.id) { - tmp.id = tid; - } - if(!tmp.li_attr.id) { - tmp.li_attr.id = tmp.id; - } - if(d && typeof d.a_attr === 'object') { - for (i in d.a_attr) { - if(d.a_attr.hasOwnProperty(i)) { - tmp.a_attr[i] = d.a_attr[i]; - } - } - } - if(d && d.children && d.children.length) { - for(i = 0, j = d.children.length; i < j; i++) { - c = this._parse_model_from_json(d.children[i], tmp.id, ps); - e = m[c]; - tmp.children.push(c); - if(e.children_d.length) { - tmp.children_d = tmp.children_d.concat(e.children_d); - } - } - tmp.children_d = tmp.children_d.concat(tmp.children); - } - if(d && d.children && d.children === true) { - tmp.state.loaded = false; - tmp.children = []; - tmp.children_d = []; - } - delete d.data; - delete d.children; - tmp.original = d; - m[tmp.id] = tmp; - if(tmp.state.selected) { - this._data.core.selected.push(tmp.id); - } - return tmp.id; - }, - /** - * redraws all nodes that need to be redrawn. Used internally. - * @private - * @name _redraw() - * @trigger redraw.jstree - */ - _redraw : function () { - var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]), - f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused; - for(i = 0, j = nodes.length; i < j; i++) { - tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw); - if(tmp && this._model.force_full_redraw) { - f.appendChild(tmp); - } - } - if(this._model.force_full_redraw) { - f.className = this.get_container_ul()[0].className; - f.setAttribute('role','group'); - this.element.empty().append(f); - //this.get_container_ul()[0].appendChild(f); - } - if(fe !== null && this.settings.core.restore_focus) { - tmp = this.get_node(fe, true); - if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) { - tmp.children('.jstree-anchor').focus(); - } - else { - this._data.core.focused = null; - } - } - this._model.force_full_redraw = false; - this._model.changed = []; - /** - * triggered after nodes are redrawn - * @event - * @name redraw.jstree - * @param {array} nodes the redrawn nodes - */ - this.trigger('redraw', { "nodes" : nodes }); - }, - /** - * redraws all nodes that need to be redrawn or optionally - the whole tree - * @name redraw([full]) - * @param {Boolean} full if set to `true` all nodes are redrawn. - */ - redraw : function (full) { - if(full) { - this._model.force_full_redraw = true; - } - //if(this._model.redraw_timeout) { - // clearTimeout(this._model.redraw_timeout); - //} - //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0); - this._redraw(); - }, - /** - * redraws a single node's children. Used internally. - * @private - * @name draw_children(node) - * @param {mixed} node the node whose children will be redrawn - */ - draw_children : function (node) { - var obj = this.get_node(node), - i = false, - j = false, - k = false, - d = document; - if(!obj) { return false; } - if(obj.id === $.jstree.root) { return this.redraw(true); } - node = this.get_node(node, true); - if(!node || !node.length) { return false; } // TODO: quick toggle - - node.children('.jstree-children').remove(); - node = node[0]; - if(obj.children.length && obj.state.loaded) { - k = d.createElement('UL'); - k.setAttribute('role', 'group'); - k.className = 'jstree-children'; - for(i = 0, j = obj.children.length; i < j; i++) { - k.appendChild(this.redraw_node(obj.children[i], true, true)); - } - node.appendChild(k); - } - }, - /** - * redraws a single node. Used internally. - * @private - * @name redraw_node(node, deep, is_callback, force_render) - * @param {mixed} node the node to redraw - * @param {Boolean} deep should child nodes be redrawn too - * @param {Boolean} is_callback is this a recursion call - * @param {Boolean} force_render should children of closed parents be drawn anyway - */ - redraw_node : function (node, deep, is_callback, force_render) { - var obj = this.get_node(node), - par = false, - ind = false, - old = false, - i = false, - j = false, - k = false, - c = '', - d = document, - m = this._model.data, - f = false, - s = false, - tmp = null, - t = 0, - l = 0, - has_children = false, - last_sibling = false; - if(!obj) { return false; } - if(obj.id === $.jstree.root) { return this.redraw(true); } - deep = deep || obj.children.length === 0; - node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element); - if(!node) { - deep = true; - //node = d.createElement('LI'); - if(!is_callback) { - par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null; - if(par !== null && (!par || !m[obj.parent].state.opened)) { - return false; - } - ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children); - } - } - else { - node = $(node); - if(!is_callback) { - par = node.parent().parent()[0]; - if(par === this.element[0]) { - par = null; - } - ind = node.index(); - } - // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage - if(!deep && obj.children.length && !node.children('.jstree-children').length) { - deep = true; - } - if(!deep) { - old = node.children('.jstree-children')[0]; - } - f = node.children('.jstree-anchor')[0] === document.activeElement; - node.remove(); - //node = d.createElement('LI'); - //node = node[0]; - } - node = this._data.core.node.cloneNode(true); - // node is DOM, deep is boolean - - c = 'jstree-node '; - for(i in obj.li_attr) { - if(obj.li_attr.hasOwnProperty(i)) { - if(i === 'id') { continue; } - if(i !== 'class') { - node.setAttribute(i, obj.li_attr[i]); - } - else { - c += obj.li_attr[i]; - } - } - } - if(!obj.a_attr.id) { - obj.a_attr.id = obj.id + '_anchor'; - } - node.setAttribute('aria-selected', !!obj.state.selected); - node.setAttribute('aria-level', obj.parents.length); - node.setAttribute('aria-labelledby', obj.a_attr.id); - if(obj.state.disabled) { - node.setAttribute('aria-disabled', true); - } - - for(i = 0, j = obj.children.length; i < j; i++) { - if(!m[obj.children[i]].state.hidden) { - has_children = true; - break; - } - } - if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) { - i = $.inArray(obj.id, m[obj.parent].children); - last_sibling = obj.id; - if(i !== -1) { - i++; - for(j = m[obj.parent].children.length; i < j; i++) { - if(!m[m[obj.parent].children[i]].state.hidden) { - last_sibling = m[obj.parent].children[i]; - } - if(last_sibling !== obj.id) { - break; - } - } - } - } - - if(obj.state.hidden) { - c += ' jstree-hidden'; - } - if (obj.state.loading) { - c += ' jstree-loading'; - } - if(obj.state.loaded && !has_children) { - c += ' jstree-leaf'; - } - else { - c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed'; - node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) ); - } - if(last_sibling === obj.id) { - c += ' jstree-last'; - } - node.id = obj.id; - node.className = c; - c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : ''); - for(j in obj.a_attr) { - if(obj.a_attr.hasOwnProperty(j)) { - if(j === 'href' && obj.a_attr[j] === '#') { continue; } - if(j !== 'class') { - node.childNodes[1].setAttribute(j, obj.a_attr[j]); - } - else { - c += ' ' + obj.a_attr[j]; - } - } - } - if(c.length) { - node.childNodes[1].className = 'jstree-anchor ' + c; - } - if((obj.icon && obj.icon !== true) || obj.icon === false) { - if(obj.icon === false) { - node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden'; - } - else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) { - node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom'; - } - else { - node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")'; - node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center'; - node.childNodes[1].childNodes[0].style.backgroundSize = 'auto'; - node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom'; - } - } - - if(this.settings.core.force_text) { - node.childNodes[1].appendChild(d.createTextNode(obj.text)); - } - else { - node.childNodes[1].innerHTML += obj.text; - } - - - if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) { - k = d.createElement('UL'); - k.setAttribute('role', 'group'); - k.className = 'jstree-children'; - for(i = 0, j = obj.children.length; i < j; i++) { - k.appendChild(this.redraw_node(obj.children[i], deep, true)); - } - node.appendChild(k); - } - if(old) { - node.appendChild(old); - } - if(!is_callback) { - // append back using par / ind - if(!par) { - par = this.element[0]; - } - for(i = 0, j = par.childNodes.length; i < j; i++) { - if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) { - tmp = par.childNodes[i]; - break; - } - } - if(!tmp) { - tmp = d.createElement('UL'); - tmp.setAttribute('role', 'group'); - tmp.className = 'jstree-children'; - par.appendChild(tmp); - } - par = tmp; - - if(ind < par.childNodes.length) { - par.insertBefore(node, par.childNodes[ind]); - } - else { - par.appendChild(node); - } - if(f) { - t = this.element[0].scrollTop; - l = this.element[0].scrollLeft; - node.childNodes[1].focus(); - this.element[0].scrollTop = t; - this.element[0].scrollLeft = l; - } - } - if(obj.state.opened && !obj.state.loaded) { - obj.state.opened = false; - setTimeout($.proxy(function () { - this.open_node(obj.id, false, 0); - }, this), 0); - } - return node; - }, - /** - * opens a node, revealing its children. If the node is not loaded it will be loaded and opened once ready. - * @name open_node(obj [, callback, animation]) - * @param {mixed} obj the node to open - * @param {Function} callback a function to execute once the node is opened - * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation. - * @trigger open_node.jstree, after_open.jstree, before_open.jstree - */ - open_node : function (obj, callback, animation) { - var t1, t2, d, t; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.open_node(obj[t1], callback, animation); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - animation = animation === undefined ? this.settings.core.animation : animation; - if(!this.is_closed(obj)) { - if(callback) { - callback.call(this, obj, false); - } - return false; - } - if(!this.is_loaded(obj)) { - if(this.is_loading(obj)) { - return setTimeout($.proxy(function () { - this.open_node(obj, callback, animation); - }, this), 500); - } - this.load_node(obj, function (o, ok) { - return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false); - }); - } - else { - d = this.get_node(obj, true); - t = this; - if(d.length) { - if(animation && d.children(".jstree-children").length) { - d.children(".jstree-children").stop(true, true); - } - if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) { - this.draw_children(obj); - //d = this.get_node(obj, true); - } - if(!animation) { - this.trigger('before_open', { "node" : obj }); - d[0].className = d[0].className.replace('jstree-closed', 'jstree-open'); - d[0].setAttribute("aria-expanded", true); - } - else { - this.trigger('before_open', { "node" : obj }); - d - .children(".jstree-children").css("display","none").end() - .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true) - .children(".jstree-children").stop(true, true) - .slideDown(animation, function () { - this.style.display = ""; - if (t.element) { - t.trigger("after_open", { "node" : obj }); - } - }); - } - } - obj.state.opened = true; - if(callback) { - callback.call(this, obj, true); - } - if(!d.length) { - /** - * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet) - * @event - * @name before_open.jstree - * @param {Object} node the opened node - */ - this.trigger('before_open', { "node" : obj }); - } - /** - * triggered when a node is opened (if there is an animation it will not be completed yet) - * @event - * @name open_node.jstree - * @param {Object} node the opened node - */ - this.trigger('open_node', { "node" : obj }); - if(!animation || !d.length) { - /** - * triggered when a node is opened and the animation is complete - * @event - * @name after_open.jstree - * @param {Object} node the opened node - */ - this.trigger("after_open", { "node" : obj }); - } - return true; - } - }, - /** - * opens every parent of a node (node should be loaded) - * @name _open_to(obj) - * @param {mixed} obj the node to reveal - * @private - */ - _open_to : function (obj) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - var i, j, p = obj.parents; - for(i = 0, j = p.length; i < j; i+=1) { - if(i !== $.jstree.root) { - this.open_node(p[i], false, 0); - } - } - return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); - }, - /** - * closes a node, hiding its children - * @name close_node(obj [, animation]) - * @param {mixed} obj the node to close - * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation. - * @trigger close_node.jstree, after_close.jstree - */ - close_node : function (obj, animation) { - var t1, t2, t, d; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.close_node(obj[t1], animation); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - if(this.is_closed(obj)) { - return false; - } - animation = animation === undefined ? this.settings.core.animation : animation; - t = this; - d = this.get_node(obj, true); - - obj.state.opened = false; - /** - * triggered when a node is closed (if there is an animation it will not be complete yet) - * @event - * @name close_node.jstree - * @param {Object} node the closed node - */ - this.trigger('close_node',{ "node" : obj }); - if(!d.length) { - /** - * triggered when a node is closed and the animation is complete - * @event - * @name after_close.jstree - * @param {Object} node the closed node - */ - this.trigger("after_close", { "node" : obj }); - } - else { - if(!animation) { - d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); - d.attr("aria-expanded", false).children('.jstree-children').remove(); - this.trigger("after_close", { "node" : obj }); - } - else { - d - .children(".jstree-children").attr("style","display:block !important").end() - .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false) - .children(".jstree-children").stop(true, true).slideUp(animation, function () { - this.style.display = ""; - d.children('.jstree-children').remove(); - if (t.element) { - t.trigger("after_close", { "node" : obj }); - } - }); - } - } - }, - /** - * toggles a node - closing it if it is open, opening it if it is closed - * @name toggle_node(obj) - * @param {mixed} obj the node to toggle - */ - toggle_node : function (obj) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.toggle_node(obj[t1]); - } - return true; - } - if(this.is_closed(obj)) { - return this.open_node(obj); - } - if(this.is_open(obj)) { - return this.close_node(obj); - } - }, - /** - * opens all nodes within a node (or the tree), revealing their children. If the node is not loaded it will be loaded and opened once ready. - * @name open_all([obj, animation, original_obj]) - * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree - * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation - * @param {jQuery} reference to the node that started the process (internal use) - * @trigger open_all.jstree - */ - open_all : function (obj, animation, original_obj) { - if(!obj) { obj = $.jstree.root; } - obj = this.get_node(obj); - if(!obj) { return false; } - var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this; - if(!dom.length) { - for(i = 0, j = obj.children_d.length; i < j; i++) { - if(this.is_closed(this._model.data[obj.children_d[i]])) { - this._model.data[obj.children_d[i]].state.opened = true; - } - } - return this.trigger('open_all', { "node" : obj }); - } - original_obj = original_obj || dom; - _this = this; - dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed'); - dom.each(function () { - _this.open_node( - this, - function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } }, - animation || 0 - ); - }); - if(original_obj.find('.jstree-closed').length === 0) { - /** - * triggered when an `open_all` call completes - * @event - * @name open_all.jstree - * @param {Object} node the opened node - */ - this.trigger('open_all', { "node" : this.get_node(original_obj) }); - } - }, - /** - * closes all nodes within a node (or the tree), revealing their children - * @name close_all([obj, animation]) - * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree - * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation - * @trigger close_all.jstree - */ - close_all : function (obj, animation) { - if(!obj) { obj = $.jstree.root; } - obj = this.get_node(obj); - if(!obj) { return false; } - var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), - _this = this, i, j; - if(dom.length) { - dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open'); - $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); }); - } - for(i = 0, j = obj.children_d.length; i < j; i++) { - this._model.data[obj.children_d[i]].state.opened = false; - } - /** - * triggered when an `close_all` call completes - * @event - * @name close_all.jstree - * @param {Object} node the closed node - */ - this.trigger('close_all', { "node" : obj }); - }, - /** - * checks if a node is disabled (not selectable) - * @name is_disabled(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_disabled : function (obj) { - obj = this.get_node(obj); - return obj && obj.state && obj.state.disabled; - }, - /** - * enables a node - so that it can be selected - * @name enable_node(obj) - * @param {mixed} obj the node to enable - * @trigger enable_node.jstree - */ - enable_node : function (obj) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.enable_node(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - obj.state.disabled = false; - this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false); - /** - * triggered when an node is enabled - * @event - * @name enable_node.jstree - * @param {Object} node the enabled node - */ - this.trigger('enable_node', { 'node' : obj }); - }, - /** - * disables a node - so that it can not be selected - * @name disable_node(obj) - * @param {mixed} obj the node to disable - * @trigger disable_node.jstree - */ - disable_node : function (obj) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.disable_node(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - obj.state.disabled = true; - this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true); - /** - * triggered when an node is disabled - * @event - * @name disable_node.jstree - * @param {Object} node the disabled node - */ - this.trigger('disable_node', { 'node' : obj }); - }, - /** - * determines if a node is hidden - * @name is_hidden(obj) - * @param {mixed} obj the node - */ - is_hidden : function (obj) { - obj = this.get_node(obj); - return obj.state.hidden === true; - }, - /** - * hides a node - it is still in the structure but will not be visible - * @name hide_node(obj) - * @param {mixed} obj the node to hide - * @param {Boolean} skip_redraw internal parameter controlling if redraw is called - * @trigger hide_node.jstree - */ - hide_node : function (obj, skip_redraw) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.hide_node(obj[t1], true); - } - if (!skip_redraw) { - this.redraw(); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - if(!obj.state.hidden) { - obj.state.hidden = true; - this._node_changed(obj.parent); - if(!skip_redraw) { - this.redraw(); - } - /** - * triggered when an node is hidden - * @event - * @name hide_node.jstree - * @param {Object} node the hidden node - */ - this.trigger('hide_node', { 'node' : obj }); - } - }, - /** - * shows a node - * @name show_node(obj) - * @param {mixed} obj the node to show - * @param {Boolean} skip_redraw internal parameter controlling if redraw is called - * @trigger show_node.jstree - */ - show_node : function (obj, skip_redraw) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.show_node(obj[t1], true); - } - if (!skip_redraw) { - this.redraw(); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - if(obj.state.hidden) { - obj.state.hidden = false; - this._node_changed(obj.parent); - if(!skip_redraw) { - this.redraw(); - } - /** - * triggered when an node is shown - * @event - * @name show_node.jstree - * @param {Object} node the shown node - */ - this.trigger('show_node', { 'node' : obj }); - } - }, - /** - * hides all nodes - * @name hide_all() - * @trigger hide_all.jstree - */ - hide_all : function (skip_redraw) { - var i, m = this._model.data, ids = []; - for(i in m) { - if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) { - m[i].state.hidden = true; - ids.push(i); - } - } - this._model.force_full_redraw = true; - if(!skip_redraw) { - this.redraw(); - } - /** - * triggered when all nodes are hidden - * @event - * @name hide_all.jstree - * @param {Array} nodes the IDs of all hidden nodes - */ - this.trigger('hide_all', { 'nodes' : ids }); - return ids; - }, - /** - * shows all nodes - * @name show_all() - * @trigger show_all.jstree - */ - show_all : function (skip_redraw) { - var i, m = this._model.data, ids = []; - for(i in m) { - if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) { - m[i].state.hidden = false; - ids.push(i); - } - } - this._model.force_full_redraw = true; - if(!skip_redraw) { - this.redraw(); - } - /** - * triggered when all nodes are shown - * @event - * @name show_all.jstree - * @param {Array} nodes the IDs of all shown nodes - */ - this.trigger('show_all', { 'nodes' : ids }); - return ids; - }, - /** - * called when a node is selected by the user. Used internally. - * @private - * @name activate_node(obj, e) - * @param {mixed} obj the node - * @param {Object} e the related event - * @trigger activate_node.jstree, changed.jstree - */ - activate_node : function (obj, e) { - if(this.is_disabled(obj)) { - return false; - } - if(!e || typeof e !== 'object') { - e = {}; - } - - // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node - this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null; - if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; } - if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); } - - if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) { - if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) { - this.deselect_node(obj, false, e); - } - else { - this.deselect_all(true); - this.select_node(obj, false, false, e); - this._data.core.last_clicked = this.get_node(obj); - } - } - else { - if(e.shiftKey) { - var o = this.get_node(obj).id, - l = this._data.core.last_clicked.id, - p = this.get_node(this._data.core.last_clicked.parent).children, - c = false, - i, j; - for(i = 0, j = p.length; i < j; i += 1) { - // separate IFs work whem o and l are the same - if(p[i] === o) { - c = !c; - } - if(p[i] === l) { - c = !c; - } - if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) { - if (!this.is_hidden(p[i])) { - this.select_node(p[i], true, false, e); - } - } - else { - this.deselect_node(p[i], true, e); - } - } - this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e }); - } - else { - if(!this.is_selected(obj)) { - this.select_node(obj, false, false, e); - } - else { - this.deselect_node(obj, false, e); - } - } - } - /** - * triggered when an node is clicked or intercated with by the user - * @event - * @name activate_node.jstree - * @param {Object} node - * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object) - */ - this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e }); - }, - /** - * applies the hover state on a node, called when a node is hovered by the user. Used internally. - * @private - * @name hover_node(obj) - * @param {mixed} obj - * @trigger hover_node.jstree - */ - hover_node : function (obj) { - obj = this.get_node(obj, true); - if(!obj || !obj.length || obj.children('.jstree-hovered').length) { - return false; - } - var o = this.element.find('.jstree-hovered'), t = this.element; - if(o && o.length) { this.dehover_node(o); } - - obj.children('.jstree-anchor').addClass('jstree-hovered'); - /** - * triggered when an node is hovered - * @event - * @name hover_node.jstree - * @param {Object} node - */ - this.trigger('hover_node', { 'node' : this.get_node(obj) }); - setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0); - }, - /** - * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally. - * @private - * @name dehover_node(obj) - * @param {mixed} obj - * @trigger dehover_node.jstree - */ - dehover_node : function (obj) { - obj = this.get_node(obj, true); - if(!obj || !obj.length || !obj.children('.jstree-hovered').length) { - return false; - } - obj.children('.jstree-anchor').removeClass('jstree-hovered'); - /** - * triggered when an node is no longer hovered - * @event - * @name dehover_node.jstree - * @param {Object} node - */ - this.trigger('dehover_node', { 'node' : this.get_node(obj) }); - }, - /** - * select a node - * @name select_node(obj [, supress_event, prevent_open]) - * @param {mixed} obj an array can be used to select multiple nodes - * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered - * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened - * @trigger select_node.jstree, changed.jstree - */ - select_node : function (obj, supress_event, prevent_open, e) { - var dom, t1, t2, th; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.select_node(obj[t1], supress_event, prevent_open, e); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(!obj.state.selected) { - obj.state.selected = true; - this._data.core.selected.push(obj.id); - if(!prevent_open) { - dom = this._open_to(obj); - } - if(dom && dom.length) { - dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked'); - } - /** - * triggered when an node is selected - * @event - * @name select_node.jstree - * @param {Object} node - * @param {Array} selected the current selection - * @param {Object} event the event (if any) that triggered this select_node - */ - this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); - if(!supress_event) { - /** - * triggered when selection changes - * @event - * @name changed.jstree - * @param {Object} node - * @param {Object} action the action that caused the selection to change - * @param {Array} selected the current selection - * @param {Object} event the event (if any) that triggered this changed event - */ - this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); - } - } - }, - /** - * deselect a node - * @name deselect_node(obj [, supress_event]) - * @param {mixed} obj an array can be used to deselect multiple nodes - * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered - * @trigger deselect_node.jstree, changed.jstree - */ - deselect_node : function (obj, supress_event, e) { - var t1, t2, dom; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.deselect_node(obj[t1], supress_event, e); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(obj.state.selected) { - obj.state.selected = false; - this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id); - if(dom.length) { - dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked'); - } - /** - * triggered when an node is deselected - * @event - * @name deselect_node.jstree - * @param {Object} node - * @param {Array} selected the current selection - * @param {Object} event the event (if any) that triggered this deselect_node - */ - this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); - if(!supress_event) { - this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); - } - } - }, - /** - * select all nodes in the tree - * @name select_all([supress_event]) - * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered - * @trigger select_all.jstree, changed.jstree - */ - select_all : function (supress_event) { - var tmp = this._data.core.selected.concat([]), i, j; - this._data.core.selected = this._model.data[$.jstree.root].children_d.concat(); - for(i = 0, j = this._data.core.selected.length; i < j; i++) { - if(this._model.data[this._data.core.selected[i]]) { - this._model.data[this._data.core.selected[i]].state.selected = true; - } - } - this.redraw(true); - /** - * triggered when all nodes are selected - * @event - * @name select_all.jstree - * @param {Array} selected the current selection - */ - this.trigger('select_all', { 'selected' : this._data.core.selected }); - if(!supress_event) { - this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); - } - }, - /** - * deselect all selected nodes - * @name deselect_all([supress_event]) - * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered - * @trigger deselect_all.jstree, changed.jstree - */ - deselect_all : function (supress_event) { - var tmp = this._data.core.selected.concat([]), i, j; - for(i = 0, j = this._data.core.selected.length; i < j; i++) { - if(this._model.data[this._data.core.selected[i]]) { - this._model.data[this._data.core.selected[i]].state.selected = false; - } - } - this._data.core.selected = []; - this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false); - /** - * triggered when all nodes are deselected - * @event - * @name deselect_all.jstree - * @param {Object} node the previous selection - * @param {Array} selected the current selection - */ - this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp }); - if(!supress_event) { - this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); - } - }, - /** - * checks if a node is selected - * @name is_selected(obj) - * @param {mixed} obj - * @return {Boolean} - */ - is_selected : function (obj) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - return obj.state.selected; - }, - /** - * get an array of all selected nodes - * @name get_selected([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - */ - get_selected : function (full) { - return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice(); - }, - /** - * get an array of all top level selected nodes (ignoring children of selected nodes) - * @name get_top_selected([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - */ - get_top_selected : function (full) { - var tmp = this.get_selected(true), - obj = {}, i, j, k, l; - for(i = 0, j = tmp.length; i < j; i++) { - obj[tmp[i].id] = tmp[i]; - } - for(i = 0, j = tmp.length; i < j; i++) { - for(k = 0, l = tmp[i].children_d.length; k < l; k++) { - if(obj[tmp[i].children_d[k]]) { - delete obj[tmp[i].children_d[k]]; - } - } - } - tmp = []; - for(i in obj) { - if(obj.hasOwnProperty(i)) { - tmp.push(i); - } - } - return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; - }, - /** - * get an array of all bottom level selected nodes (ignoring selected parents) - * @name get_bottom_selected([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - */ - get_bottom_selected : function (full) { - var tmp = this.get_selected(true), - obj = [], i, j; - for(i = 0, j = tmp.length; i < j; i++) { - if(!tmp[i].children.length) { - obj.push(tmp[i].id); - } - } - return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; - }, - /** - * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally. - * @name get_state() - * @private - * @return {Object} - */ - get_state : function () { - var state = { - 'core' : { - 'open' : [], - 'loaded' : [], - 'scroll' : { - 'left' : this.element.scrollLeft(), - 'top' : this.element.scrollTop() - }, - /*! - 'themes' : { - 'name' : this.get_theme(), - 'icons' : this._data.core.themes.icons, - 'dots' : this._data.core.themes.dots - }, - */ - 'selected' : [] - } - }, i; - for(i in this._model.data) { - if(this._model.data.hasOwnProperty(i)) { - if(i !== $.jstree.root) { - if(this._model.data[i].state.loaded && this.settings.core.loaded_state) { - state.core.loaded.push(i); - } - if(this._model.data[i].state.opened) { - state.core.open.push(i); - } - if(this._model.data[i].state.selected) { - state.core.selected.push(i); - } - } - } - } - return state; - }, - /** - * sets the state of the tree. Used internally. - * @name set_state(state [, callback]) - * @private - * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it. - * @param {Function} callback an optional function to execute once the state is restored. - * @trigger set_state.jstree - */ - set_state : function (state, callback) { - if(state) { - if(state.core && state.core.selected && state.core.initial_selection === undefined) { - state.core.initial_selection = this._data.core.selected.concat([]).sort().join(','); - } - if(state.core) { - var res, n, t, _this, i; - if(state.core.loaded) { - if(!this.settings.core.loaded_state || !$.isArray(state.core.loaded) || !state.core.loaded.length) { - delete state.core.loaded; - this.set_state(state, callback); - } - else { - this._load_nodes(state.core.loaded, function (nodes) { - delete state.core.loaded; - this.set_state(state, callback); - }); - } - return false; - } - if(state.core.open) { - if(!$.isArray(state.core.open) || !state.core.open.length) { - delete state.core.open; - this.set_state(state, callback); - } - else { - this._load_nodes(state.core.open, function (nodes) { - this.open_node(nodes, false, 0); - delete state.core.open; - this.set_state(state, callback); - }); - } - return false; - } - if(state.core.scroll) { - if(state.core.scroll && state.core.scroll.left !== undefined) { - this.element.scrollLeft(state.core.scroll.left); - } - if(state.core.scroll && state.core.scroll.top !== undefined) { - this.element.scrollTop(state.core.scroll.top); - } - delete state.core.scroll; - this.set_state(state, callback); - return false; - } - if(state.core.selected) { - _this = this; - if (state.core.initial_selection === undefined || - state.core.initial_selection === this._data.core.selected.concat([]).sort().join(',') - ) { - this.deselect_all(); - $.each(state.core.selected, function (i, v) { - _this.select_node(v, false, true); - }); - } - delete state.core.initial_selection; - delete state.core.selected; - this.set_state(state, callback); - return false; - } - for(i in state) { - if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) { - delete state[i]; - } - } - if($.isEmptyObject(state.core)) { - delete state.core; - this.set_state(state, callback); - return false; - } - } - if($.isEmptyObject(state)) { - state = null; - if(callback) { callback.call(this); } - /** - * triggered when a `set_state` call completes - * @event - * @name set_state.jstree - */ - this.trigger('set_state'); - return false; - } - return true; - } - return false; - }, - /** - * refreshes the tree - all nodes are reloaded with calls to `load_node`. - * @name refresh() - * @param {Boolean} skip_loading an option to skip showing the loading indicator - * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state - * @trigger refresh.jstree - */ - refresh : function (skip_loading, forget_state) { - this._data.core.state = forget_state === true ? {} : this.get_state(); - if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); } - this._cnt = 0; - this._model.data = {}; - this._model.data[$.jstree.root] = { - id : $.jstree.root, - parent : null, - parents : [], - children : [], - children_d : [], - state : { loaded : false } - }; - this._data.core.selected = []; - this._data.core.last_clicked = null; - this._data.core.focused = null; - - var c = this.get_container_ul()[0].className; - if(!skip_loading) { - this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><"+"a class='jstree-anchor' href='#'>" + this.get_string("Loading ...") + ""); - this.element.attr('aria-activedescendant','j'+this._id+'_loading'); - } - this.load_node($.jstree.root, function (o, s) { - if(s) { - this.get_container_ul()[0].className = c; - if(this._firstChild(this.get_container_ul()[0])) { - this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); - } - this.set_state($.extend(true, {}, this._data.core.state), function () { - /** - * triggered when a `refresh` call completes - * @event - * @name refresh.jstree - */ - this.trigger('refresh'); - }); - } - this._data.core.state = null; - }); - }, - /** - * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`. - * @name refresh_node(obj) - * @param {mixed} obj the node - * @trigger refresh_node.jstree - */ - refresh_node : function (obj) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - var opened = [], to_load = [], s = this._data.core.selected.concat([]); - to_load.push(obj.id); - if(obj.state.opened === true) { opened.push(obj.id); } - this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); }); - this._load_nodes(to_load, $.proxy(function (nodes) { - this.open_node(opened, false, 0); - this.select_node(s); - /** - * triggered when a node is refreshed - * @event - * @name refresh_node.jstree - * @param {Object} node - the refreshed node - * @param {Array} nodes - an array of the IDs of the nodes that were reloaded - */ - this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes }); - }, this), false, true); - }, - /** - * set (change) the ID of a node - * @name set_id(obj, id) - * @param {mixed} obj the node - * @param {String} id the new ID - * @return {Boolean} - * @trigger set_id.jstree - */ - set_id : function (obj, id) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - var i, j, m = this._model.data, old = obj.id; - id = id.toString(); - // update parents (replace current ID with new one in children and children_d) - m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id; - for(i = 0, j = obj.parents.length; i < j; i++) { - m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id; - } - // update children (replace current ID with new one in parent and parents) - for(i = 0, j = obj.children.length; i < j; i++) { - m[obj.children[i]].parent = id; - } - for(i = 0, j = obj.children_d.length; i < j; i++) { - m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id; - } - i = $.inArray(obj.id, this._data.core.selected); - if(i !== -1) { this._data.core.selected[i] = id; } - // update model and obj itself (obj.id, this._model.data[KEY]) - i = this.get_node(obj.id, true); - if(i) { - i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor'); - if(this.element.attr('aria-activedescendant') === obj.id) { - this.element.attr('aria-activedescendant', id); - } - } - delete m[obj.id]; - obj.id = id; - obj.li_attr.id = id; - m[id] = obj; - /** - * triggered when a node id value is changed - * @event - * @name set_id.jstree - * @param {Object} node - * @param {String} old the old id - */ - this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old }); - return true; - }, - /** - * get the text value of a node - * @name get_text(obj) - * @param {mixed} obj the node - * @return {String} - */ - get_text : function (obj) { - obj = this.get_node(obj); - return (!obj || obj.id === $.jstree.root) ? false : obj.text; - }, - /** - * set the text value of a node. Used internally, please use `rename_node(obj, val)`. - * @private - * @name set_text(obj, val) - * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes - * @param {String} val the new text value - * @return {Boolean} - * @trigger set_text.jstree - */ - set_text : function (obj, val) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.set_text(obj[t1], val); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - obj.text = val; - if(this.get_node(obj, true).length) { - this.redraw_node(obj.id); - } - /** - * triggered when a node text value is changed - * @event - * @name set_text.jstree - * @param {Object} obj - * @param {String} text the new value - */ - this.trigger('set_text',{ "obj" : obj, "text" : val }); - return true; - }, - /** - * gets a JSON representation of a node (or the whole tree) - * @name get_json([obj, options]) - * @param {mixed} obj - * @param {Object} options - * @param {Boolean} options.no_state do not return state information - * @param {Boolean} options.no_id do not return ID - * @param {Boolean} options.no_children do not include children - * @param {Boolean} options.no_data do not include node data - * @param {Boolean} options.no_li_attr do not include LI attributes - * @param {Boolean} options.no_a_attr do not include A attributes - * @param {Boolean} options.flat return flat JSON instead of nested - * @return {Object} - */ - get_json : function (obj, options, flat) { - obj = this.get_node(obj || $.jstree.root); - if(!obj) { return false; } - if(options && options.flat && !flat) { flat = []; } - var tmp = { - 'id' : obj.id, - 'text' : obj.text, - 'icon' : this.get_icon(obj), - 'li_attr' : $.extend(true, {}, obj.li_attr), - 'a_attr' : $.extend(true, {}, obj.a_attr), - 'state' : {}, - 'data' : options && options.no_data ? false : $.extend(true, $.isArray(obj.data)?[]:{}, obj.data) - //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ), - }, i, j; - if(options && options.flat) { - tmp.parent = obj.parent; - } - else { - tmp.children = []; - } - if(!options || !options.no_state) { - for(i in obj.state) { - if(obj.state.hasOwnProperty(i)) { - tmp.state[i] = obj.state[i]; - } - } - } else { - delete tmp.state; - } - if(options && options.no_li_attr) { - delete tmp.li_attr; - } - if(options && options.no_a_attr) { - delete tmp.a_attr; - } - if(options && options.no_id) { - delete tmp.id; - if(tmp.li_attr && tmp.li_attr.id) { - delete tmp.li_attr.id; - } - if(tmp.a_attr && tmp.a_attr.id) { - delete tmp.a_attr.id; - } - } - if(options && options.flat && obj.id !== $.jstree.root) { - flat.push(tmp); - } - if(!options || !options.no_children) { - for(i = 0, j = obj.children.length; i < j; i++) { - if(options && options.flat) { - this.get_json(obj.children[i], options, flat); - } - else { - tmp.children.push(this.get_json(obj.children[i], options)); - } - } - } - return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp); - }, - /** - * create a new node (do not confuse with load_node) - * @name create_node([par, node, pos, callback, is_loaded]) - * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`) - * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name) - * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last" - * @param {Function} callback a function to be called once the node is created - * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded - * @return {String} the ID of the newly create node - * @trigger model.jstree, create_node.jstree - */ - create_node : function (par, node, pos, callback, is_loaded) { - if(par === null) { par = $.jstree.root; } - par = this.get_node(par); - if(!par) { return false; } - pos = pos === undefined ? "last" : pos; - if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { - return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); }); - } - if(!node) { node = { "text" : this.get_string('New node') }; } - if(typeof node === "string") { - node = { "text" : node }; - } else { - node = $.extend(true, {}, node); - } - if(node.text === undefined) { node.text = this.get_string('New node'); } - var tmp, dpc, i, j; - - if(par.id === $.jstree.root) { - if(pos === "before") { pos = "first"; } - if(pos === "after") { pos = "last"; } - } - switch(pos) { - case "before": - tmp = this.get_node(par.parent); - pos = $.inArray(par.id, tmp.children); - par = tmp; - break; - case "after" : - tmp = this.get_node(par.parent); - pos = $.inArray(par.id, tmp.children) + 1; - par = tmp; - break; - case "inside": - case "first": - pos = 0; - break; - case "last": - pos = par.children.length; - break; - default: - if(!pos) { pos = 0; } - break; - } - if(pos > par.children.length) { pos = par.children.length; } - if(!node.id) { node.id = true; } - if(!this.check("create_node", node, par, pos)) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - if(node.id === true) { delete node.id; } - node = this._parse_model_from_json(node, par.id, par.parents.concat()); - if(!node) { return false; } - tmp = this.get_node(node); - dpc = []; - dpc.push(node); - dpc = dpc.concat(tmp.children_d); - this.trigger('model', { "nodes" : dpc, "parent" : par.id }); - - par.children_d = par.children_d.concat(dpc); - for(i = 0, j = par.parents.length; i < j; i++) { - this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc); - } - node = tmp; - tmp = []; - for(i = 0, j = par.children.length; i < j; i++) { - tmp[i >= pos ? i+1 : i] = par.children[i]; - } - tmp[pos] = node.id; - par.children = tmp; - - this.redraw_node(par, true); - /** - * triggered when a node is created - * @event - * @name create_node.jstree - * @param {Object} node - * @param {String} parent the parent's ID - * @param {Number} position the position of the new node among the parent's children - */ - this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos }); - if(callback) { callback.call(this, this.get_node(node)); } - return node.id; - }, - /** - * set the text value of a node - * @name rename_node(obj, val) - * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name - * @param {String} val the new text value - * @return {Boolean} - * @trigger rename_node.jstree - */ - rename_node : function (obj, val) { - var t1, t2, old; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.rename_node(obj[t1], val); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - old = obj.text; - if(!this.check("rename_node", obj, this.get_parent(obj), val)) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments)) - /** - * triggered when a node is renamed - * @event - * @name rename_node.jstree - * @param {Object} node - * @param {String} text the new value - * @param {String} old the old value - */ - this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old }); - return true; - }, - /** - * remove a node - * @name delete_node(obj) - * @param {mixed} obj the node, you can pass an array to delete multiple nodes - * @return {Boolean} - * @trigger delete_node.jstree, changed.jstree - */ - delete_node : function (obj) { - var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.delete_node(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - par = this.get_node(obj.parent); - pos = $.inArray(obj.id, par.children); - c = false; - if(!this.check("delete_node", obj, par, pos)) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - if(pos !== -1) { - par.children = $.vakata.array_remove(par.children, pos); - } - tmp = obj.children_d.concat([]); - tmp.push(obj.id); - for(i = 0, j = obj.parents.length; i < j; i++) { - this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { - return $.inArray(v, tmp) === -1; - }); - } - for(k = 0, l = tmp.length; k < l; k++) { - if(this._model.data[tmp[k]].state.selected) { - c = true; - break; - } - } - if (c) { - this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { - return $.inArray(v, tmp) === -1; - }); - } - /** - * triggered when a node is deleted - * @event - * @name delete_node.jstree - * @param {Object} node - * @param {String} parent the parent's ID - */ - this.trigger('delete_node', { "node" : obj, "parent" : par.id }); - if(c) { - this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id }); - } - for(k = 0, l = tmp.length; k < l; k++) { - delete this._model.data[tmp[k]]; - } - if($.inArray(this._data.core.focused, tmp) !== -1) { - this._data.core.focused = null; - top = this.element[0].scrollTop; - lft = this.element[0].scrollLeft; - if(par.id === $.jstree.root) { - if (this._model.data[$.jstree.root].children[0]) { - this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus(); - } - } - else { - this.get_node(par, true).children('.jstree-anchor').focus(); - } - this.element[0].scrollTop = top; - this.element[0].scrollLeft = lft; - } - this.redraw_node(par, true); - return true; - }, - /** - * check if an operation is premitted on the tree. Used internally. - * @private - * @name check(chk, obj, par, pos) - * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node" - * @param {mixed} obj the node - * @param {mixed} par the parent - * @param {mixed} pos the position to insert at, or if "rename_node" - the new name - * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node - * @return {Boolean} - */ - check : function (chk, obj, par, pos, more) { - obj = obj && obj.id ? obj : this.get_node(obj); - par = par && par.id ? par : this.get_node(par); - var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj, - chc = this.settings.core.check_callback; - if(chk === "move_node" || chk === "copy_node") { - if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - return false; - } - } - if(tmp && tmp.data) { tmp = tmp.data; } - if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) { - if(tmp.functions[chk] === false) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - } - return tmp.functions[chk]; - } - if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - return false; - } - return true; - }, - /** - * get the last error - * @name last_error() - * @return {Object} - */ - last_error : function () { - return this._data.core.last_error; - }, - /** - * move a node to a new parent - * @name move_node(obj, par [, pos, callback, is_loaded]) - * @param {mixed} obj the node to move, pass an array to move multiple nodes - * @param {mixed} par the new parent - * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` - * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position - * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded - * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn - * @param {Boolean} instance internal parameter indicating if the node comes from another instance - * @trigger move_node.jstree - */ - move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { - var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p; - - par = this.get_node(par); - pos = pos === undefined ? 0 : pos; - if(!par) { return false; } - if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { - return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); }); - } - - if($.isArray(obj)) { - if(obj.length === 1) { - obj = obj[0]; - } - else { - //obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) { - par = tmp; - pos = "after"; - } - } - this.redraw(); - return true; - } - } - obj = obj && obj.id ? obj : this.get_node(obj); - - if(!obj || obj.id === $.jstree.root) { return false; } - - old_par = (obj.parent || $.jstree.root).toString(); - new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); - old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); - is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); - old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1; - if(old_ins && old_ins._id) { - obj = old_ins._model.data[obj.id]; - } - - if(is_multi) { - if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) { - if(old_ins) { old_ins.delete_node(obj); } - return tmp; - } - return false; - } - //var m = this._model.data; - if(par.id === $.jstree.root) { - if(pos === "before") { pos = "first"; } - if(pos === "after") { pos = "last"; } - } - switch(pos) { - case "before": - pos = $.inArray(par.id, new_par.children); - break; - case "after" : - pos = $.inArray(par.id, new_par.children) + 1; - break; - case "inside": - case "first": - pos = 0; - break; - case "last": - pos = new_par.children.length; - break; - default: - if(!pos) { pos = 0; } - break; - } - if(pos > new_par.children.length) { pos = new_par.children.length; } - if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - if(obj.parent === new_par.id) { - dpc = new_par.children.concat(); - tmp = $.inArray(obj.id, dpc); - if(tmp !== -1) { - dpc = $.vakata.array_remove(dpc, tmp); - if(pos > tmp) { pos--; } - } - tmp = []; - for(i = 0, j = dpc.length; i < j; i++) { - tmp[i >= pos ? i+1 : i] = dpc[i]; - } - tmp[pos] = obj.id; - new_par.children = tmp; - this._node_changed(new_par.id); - this.redraw(new_par.id === $.jstree.root); - } - else { - // clean old parent and up - tmp = obj.children_d.concat(); - tmp.push(obj.id); - for(i = 0, j = obj.parents.length; i < j; i++) { - dpc = []; - p = old_ins._model.data[obj.parents[i]].children_d; - for(k = 0, l = p.length; k < l; k++) { - if($.inArray(p[k], tmp) === -1) { - dpc.push(p[k]); - } - } - old_ins._model.data[obj.parents[i]].children_d = dpc; - } - old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id); - - // insert into new parent and up - for(i = 0, j = new_par.parents.length; i < j; i++) { - this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp); - } - dpc = []; - for(i = 0, j = new_par.children.length; i < j; i++) { - dpc[i >= pos ? i+1 : i] = new_par.children[i]; - } - dpc[pos] = obj.id; - new_par.children = dpc; - new_par.children_d.push(obj.id); - new_par.children_d = new_par.children_d.concat(obj.children_d); - - // update object - obj.parent = new_par.id; - tmp = new_par.parents.concat(); - tmp.unshift(new_par.id); - p = obj.parents.length; - obj.parents = tmp; - - // update object children - tmp = tmp.concat(); - for(i = 0, j = obj.children_d.length; i < j; i++) { - this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1); - Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp); - } - - if(old_par === $.jstree.root || new_par.id === $.jstree.root) { - this._model.force_full_redraw = true; - } - if(!this._model.force_full_redraw) { - this._node_changed(old_par); - this._node_changed(new_par.id); - } - if(!skip_redraw) { - this.redraw(); - } - } - if(callback) { callback.call(this, obj, new_par, pos); } - /** - * triggered when a node is moved - * @event - * @name move_node.jstree - * @param {Object} node - * @param {String} parent the parent's ID - * @param {Number} position the position of the node among the parent's children - * @param {String} old_parent the old parent of the node - * @param {Number} old_position the old position of the node - * @param {Boolean} is_multi do the node and new parent belong to different instances - * @param {jsTree} old_instance the instance the node came from - * @param {jsTree} new_instance the instance of the new parent - */ - this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); - return obj.id; - }, - /** - * copy a node to a new parent - * @name copy_node(obj, par [, pos, callback, is_loaded]) - * @param {mixed} obj the node to copy, pass an array to copy multiple nodes - * @param {mixed} par the new parent - * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` - * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position - * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded - * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn - * @param {Boolean} instance internal parameter indicating if the node comes from another instance - * @trigger model.jstree copy_node.jstree - */ - copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { - var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi; - - par = this.get_node(par); - pos = pos === undefined ? 0 : pos; - if(!par) { return false; } - if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { - return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); }); - } - - if($.isArray(obj)) { - if(obj.length === 1) { - obj = obj[0]; - } - else { - //obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) { - par = tmp; - pos = "after"; - } - } - this.redraw(); - return true; - } - } - obj = obj && obj.id ? obj : this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - - old_par = (obj.parent || $.jstree.root).toString(); - new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); - old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); - is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); - - if(old_ins && old_ins._id) { - obj = old_ins._model.data[obj.id]; - } - - if(par.id === $.jstree.root) { - if(pos === "before") { pos = "first"; } - if(pos === "after") { pos = "last"; } - } - switch(pos) { - case "before": - pos = $.inArray(par.id, new_par.children); - break; - case "after" : - pos = $.inArray(par.id, new_par.children) + 1; - break; - case "inside": - case "first": - pos = 0; - break; - case "last": - pos = new_par.children.length; - break; - default: - if(!pos) { pos = 0; } - break; - } - if(pos > new_par.children.length) { pos = new_par.children.length; } - if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj; - if(!node) { return false; } - if(node.id === true) { delete node.id; } - node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat()); - if(!node) { return false; } - tmp = this.get_node(node); - if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; } - dpc = []; - dpc.push(node); - dpc = dpc.concat(tmp.children_d); - this.trigger('model', { "nodes" : dpc, "parent" : new_par.id }); - - // insert into new parent and up - for(i = 0, j = new_par.parents.length; i < j; i++) { - this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc); - } - dpc = []; - for(i = 0, j = new_par.children.length; i < j; i++) { - dpc[i >= pos ? i+1 : i] = new_par.children[i]; - } - dpc[pos] = tmp.id; - new_par.children = dpc; - new_par.children_d.push(tmp.id); - new_par.children_d = new_par.children_d.concat(tmp.children_d); - - if(new_par.id === $.jstree.root) { - this._model.force_full_redraw = true; - } - if(!this._model.force_full_redraw) { - this._node_changed(new_par.id); - } - if(!skip_redraw) { - this.redraw(new_par.id === $.jstree.root); - } - if(callback) { callback.call(this, tmp, new_par, pos); } - /** - * triggered when a node is copied - * @event - * @name copy_node.jstree - * @param {Object} node the copied node - * @param {Object} original the original node - * @param {String} parent the parent's ID - * @param {Number} position the position of the node among the parent's children - * @param {String} old_parent the old parent of the node - * @param {Number} old_position the position of the original node - * @param {Boolean} is_multi do the node and new parent belong to different instances - * @param {jsTree} old_instance the instance the node came from - * @param {jsTree} new_instance the instance of the new parent - */ - this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); - return tmp.id; - }, - /** - * cut a node (a later call to `paste(obj)` would move the node) - * @name cut(obj) - * @param {mixed} obj multiple objects can be passed using an array - * @trigger cut.jstree - */ - cut : function (obj) { - if(!obj) { obj = this._data.core.selected.concat(); } - if(!$.isArray(obj)) { obj = [obj]; } - if(!obj.length) { return false; } - var tmp = [], o, t1, t2; - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - o = this.get_node(obj[t1]); - if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } - } - if(!tmp.length) { return false; } - ccp_node = tmp; - ccp_inst = this; - ccp_mode = 'move_node'; - /** - * triggered when nodes are added to the buffer for moving - * @event - * @name cut.jstree - * @param {Array} node - */ - this.trigger('cut', { "node" : obj }); - }, - /** - * copy a node (a later call to `paste(obj)` would copy the node) - * @name copy(obj) - * @param {mixed} obj multiple objects can be passed using an array - * @trigger copy.jstree - */ - copy : function (obj) { - if(!obj) { obj = this._data.core.selected.concat(); } - if(!$.isArray(obj)) { obj = [obj]; } - if(!obj.length) { return false; } - var tmp = [], o, t1, t2; - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - o = this.get_node(obj[t1]); - if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } - } - if(!tmp.length) { return false; } - ccp_node = tmp; - ccp_inst = this; - ccp_mode = 'copy_node'; - /** - * triggered when nodes are added to the buffer for copying - * @event - * @name copy.jstree - * @param {Array} node - */ - this.trigger('copy', { "node" : obj }); - }, - /** - * get the current buffer (any nodes that are waiting for a paste operation) - * @name get_buffer() - * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance) - */ - get_buffer : function () { - return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst }; - }, - /** - * check if there is something in the buffer to paste - * @name can_paste() - * @return {Boolean} - */ - can_paste : function () { - return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node]; - }, - /** - * copy or move the previously cut or copied nodes to a new parent - * @name paste(obj [, pos]) - * @param {mixed} obj the new parent - * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0` - * @trigger paste.jstree - */ - paste : function (obj, pos) { - obj = this.get_node(obj); - if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; } - if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) { - /** - * triggered when paste is invoked - * @event - * @name paste.jstree - * @param {String} parent the ID of the receiving node - * @param {Array} node the nodes in the buffer - * @param {String} mode the performed operation - "copy_node" or "move_node" - */ - this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode }); - } - ccp_node = false; - ccp_mode = false; - ccp_inst = false; - }, - /** - * clear the buffer of previously copied or cut nodes - * @name clear_buffer() - * @trigger clear_buffer.jstree - */ - clear_buffer : function () { - ccp_node = false; - ccp_mode = false; - ccp_inst = false; - /** - * triggered when the copy / cut buffer is cleared - * @event - * @name clear_buffer.jstree - */ - this.trigger('clear_buffer'); - }, - /** - * put a node in edit mode (input field to rename the node) - * @name edit(obj [, default_text, callback]) - * @param {mixed} obj - * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used) - * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise) and a boolean indicating if the user cancelled the edit. You can access the node's title using .text - */ - edit : function (obj, default_text, callback) { - var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false; - obj = this.get_node(obj); - if(!obj) { return false; } - if(!this.check("edit", obj, this.get_parent(obj))) { - this.settings.core.error.call(this, this._data.core.last_error); - return false; - } - tmp = obj; - default_text = typeof default_text === 'string' ? default_text : obj.text; - this.set_text(obj, ""); - obj = this._open_to(obj); - tmp.text = default_text; - - rtl = this._data.core.rtl; - w = this.element.width(); - this._data.core.focused = tmp.id; - a = obj.children('.jstree-anchor').focus(); - s = $(''); - /*! - oi = obj.children("i:visible"), - ai = a.children("i:visible"), - w1 = oi.width() * oi.length, - w2 = ai.width() * ai.length, - */ - t = default_text; - h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo(document.body); - h2 = $("<"+"input />", { - "value" : t, - "class" : "jstree-rename-input", - // "size" : t.length, - "css" : { - "padding" : "0", - "border" : "1px solid silver", - "box-sizing" : "border-box", - "display" : "inline-block", - "height" : (this._data.core.li_height) + "px", - "lineHeight" : (this._data.core.li_height) + "px", - "width" : "150px" // will be set a bit further down - }, - "blur" : $.proxy(function (e) { - e.stopImmediatePropagation(); - e.preventDefault(); - var i = s.children(".jstree-rename-input"), - v = i.val(), - f = this.settings.core.force_text, - nv; - if(v === "") { v = t; } - h1.remove(); - s.replaceWith(a); - s.remove(); - t = f ? t : $('
').append($.parseHTML(t)).html(); - obj = this.get_node(obj); - this.set_text(obj, t); - nv = !!this.rename_node(obj, f ? $('
').text(v).text() : $('
').append($.parseHTML(v)).html()); - if(!nv) { - this.set_text(obj, t); // move this up? and fix #483 - } - this._data.core.focused = tmp.id; - setTimeout($.proxy(function () { - var node = this.get_node(tmp.id, true); - if(node.length) { - this._data.core.focused = tmp.id; - node.children('.jstree-anchor').focus(); - } - }, this), 0); - if(callback) { - callback.call(this, tmp, nv, cancel); - } - h2 = null; - }, this), - "keydown" : function (e) { - var key = e.which; - if(key === 27) { - cancel = true; - this.value = t; - } - if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { - e.stopImmediatePropagation(); - } - if(key === 27 || key === 13) { - e.preventDefault(); - this.blur(); - } - }, - "click" : function (e) { e.stopImmediatePropagation(); }, - "mousedown" : function (e) { e.stopImmediatePropagation(); }, - "keyup" : function (e) { - h2.width(Math.min(h1.text("pW" + this.value).width(),w)); - }, - "keypress" : function(e) { - if(e.which === 13) { return false; } - } - }); - fn = { - fontFamily : a.css('fontFamily') || '', - fontSize : a.css('fontSize') || '', - fontWeight : a.css('fontWeight') || '', - fontStyle : a.css('fontStyle') || '', - fontStretch : a.css('fontStretch') || '', - fontVariant : a.css('fontVariant') || '', - letterSpacing : a.css('letterSpacing') || '', - wordSpacing : a.css('wordSpacing') || '' - }; - s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2); - a.replaceWith(s); - h1.css(fn); - h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); - $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) { - if (h2 && e.target !== h2) { - $(h2).blur(); - } - }); - }, - - - /** - * changes the theme - * @name set_theme(theme_name [, theme_url]) - * @param {String} theme_name the name of the new theme to apply - * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory. - * @trigger set_theme.jstree - */ - set_theme : function (theme_name, theme_url) { - if(!theme_name) { return false; } - if(theme_url === true) { - var dir = this.settings.core.themes.dir; - if(!dir) { dir = $.jstree.path + '/themes'; } - theme_url = dir + '/' + theme_name + '/style.css'; - } - if(theme_url && $.inArray(theme_url, themes_loaded) === -1) { - $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />'); - themes_loaded.push(theme_url); - } - if(this._data.core.themes.name) { - this.element.removeClass('jstree-' + this._data.core.themes.name); - } - this._data.core.themes.name = theme_name; - this.element.addClass('jstree-' + theme_name); - this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive'); - /** - * triggered when a theme is set - * @event - * @name set_theme.jstree - * @param {String} theme the new theme - */ - this.trigger('set_theme', { 'theme' : theme_name }); - }, - /** - * gets the name of the currently applied theme name - * @name get_theme() - * @return {String} - */ - get_theme : function () { return this._data.core.themes.name; }, - /** - * changes the theme variant (if the theme has variants) - * @name set_theme_variant(variant_name) - * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed) - */ - set_theme_variant : function (variant_name) { - if(this._data.core.themes.variant) { - this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); - } - this._data.core.themes.variant = variant_name; - if(variant_name) { - this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); - } - }, - /** - * gets the name of the currently applied theme variant - * @name get_theme() - * @return {String} - */ - get_theme_variant : function () { return this._data.core.themes.variant; }, - /** - * shows a striped background on the container (if the theme supports it) - * @name show_stripes() - */ - show_stripes : function () { - this._data.core.themes.stripes = true; - this.get_container_ul().addClass("jstree-striped"); - /** - * triggered when stripes are shown - * @event - * @name show_stripes.jstree - */ - this.trigger('show_stripes'); - }, - /** - * hides the striped background on the container - * @name hide_stripes() - */ - hide_stripes : function () { - this._data.core.themes.stripes = false; - this.get_container_ul().removeClass("jstree-striped"); - /** - * triggered when stripes are hidden - * @event - * @name hide_stripes.jstree - */ - this.trigger('hide_stripes'); - }, - /** - * toggles the striped background on the container - * @name toggle_stripes() - */ - toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } }, - /** - * shows the connecting dots (if the theme supports it) - * @name show_dots() - */ - show_dots : function () { - this._data.core.themes.dots = true; - this.get_container_ul().removeClass("jstree-no-dots"); - /** - * triggered when dots are shown - * @event - * @name show_dots.jstree - */ - this.trigger('show_dots'); - }, - /** - * hides the connecting dots - * @name hide_dots() - */ - hide_dots : function () { - this._data.core.themes.dots = false; - this.get_container_ul().addClass("jstree-no-dots"); - /** - * triggered when dots are hidden - * @event - * @name hide_dots.jstree - */ - this.trigger('hide_dots'); - }, - /** - * toggles the connecting dots - * @name toggle_dots() - */ - toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, - /** - * show the node icons - * @name show_icons() - */ - show_icons : function () { - this._data.core.themes.icons = true; - this.get_container_ul().removeClass("jstree-no-icons"); - /** - * triggered when icons are shown - * @event - * @name show_icons.jstree - */ - this.trigger('show_icons'); - }, - /** - * hide the node icons - * @name hide_icons() - */ - hide_icons : function () { - this._data.core.themes.icons = false; - this.get_container_ul().addClass("jstree-no-icons"); - /** - * triggered when icons are hidden - * @event - * @name hide_icons.jstree - */ - this.trigger('hide_icons'); - }, - /** - * toggle the node icons - * @name toggle_icons() - */ - toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }, - /** - * show the node ellipsis - * @name show_icons() - */ - show_ellipsis : function () { - this._data.core.themes.ellipsis = true; - this.get_container_ul().addClass("jstree-ellipsis"); - /** - * triggered when ellisis is shown - * @event - * @name show_ellipsis.jstree - */ - this.trigger('show_ellipsis'); - }, - /** - * hide the node ellipsis - * @name hide_ellipsis() - */ - hide_ellipsis : function () { - this._data.core.themes.ellipsis = false; - this.get_container_ul().removeClass("jstree-ellipsis"); - /** - * triggered when ellisis is hidden - * @event - * @name hide_ellipsis.jstree - */ - this.trigger('hide_ellipsis'); - }, - /** - * toggle the node ellipsis - * @name toggle_icons() - */ - toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } }, - /** - * set the node icon for a node - * @name set_icon(obj, icon) - * @param {mixed} obj - * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class - */ - set_icon : function (obj, icon) { - var t1, t2, dom, old; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.set_icon(obj[t1], icon); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - old = obj.icon; - obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon; - dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon"); - if(icon === false) { - dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); - this.hide_icon(obj); - } - else if(icon === true || icon === null || icon === undefined || icon === '') { - dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); - if(old === false) { this.show_icon(obj); } - } - else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) { - dom.removeClass(old).css("background",""); - dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon); - if(old === false) { this.show_icon(obj); } - } - else { - dom.removeClass(old).css("background",""); - dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon); - if(old === false) { this.show_icon(obj); } - } - return true; - }, - /** - * get the node icon for a node - * @name get_icon(obj) - * @param {mixed} obj - * @return {String} - */ - get_icon : function (obj) { - obj = this.get_node(obj); - return (!obj || obj.id === $.jstree.root) ? false : obj.icon; - }, - /** - * hide the icon on an individual node - * @name hide_icon(obj) - * @param {mixed} obj - */ - hide_icon : function (obj) { - var t1, t2; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.hide_icon(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj === $.jstree.root) { return false; } - obj.icon = false; - this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden'); - return true; - }, - /** - * show the icon on an individual node - * @name show_icon(obj) - * @param {mixed} obj - */ - show_icon : function (obj) { - var t1, t2, dom; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.show_icon(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj === $.jstree.root) { return false; } - dom = this.get_node(obj, true); - obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true; - if(!obj.icon) { obj.icon = true; } - dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden'); - return true; - } - }; - - // helpers - $.vakata = {}; - // collect attributes - $.vakata.attributes = function(node, with_values) { - node = $(node)[0]; - var attr = with_values ? {} : []; - if(node && node.attributes) { - $.each(node.attributes, function (i, v) { - if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; } - if(v.value !== null && $.trim(v.value) !== '') { - if(with_values) { attr[v.name] = v.value; } - else { attr.push(v.name); } - } - }); - } - return attr; - }; - $.vakata.array_unique = function(array) { - var a = [], i, j, l, o = {}; - for(i = 0, l = array.length; i < l; i++) { - if(o[array[i]] === undefined) { - a.push(array[i]); - o[array[i]] = true; - } - } - return a; - }; - // remove item from array - $.vakata.array_remove = function(array, from) { - array.splice(from, 1); - return array; - //var rest = array.slice((to || from) + 1 || array.length); - //array.length = from < 0 ? array.length + from : from; - //array.push.apply(array, rest); - //return array; - }; - // remove item from array - $.vakata.array_remove_item = function(array, item) { - var tmp = $.inArray(item, array); - return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array; - }; - $.vakata.array_filter = function(c,a,b,d,e) { - if (c.filter) { - return c.filter(a, b); - } - d=[]; - for (e in c) { - if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) { - d.push(c[e]); - } - } - return d; - }; - - -/** - * ### Changed plugin - * - * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes. - */ - - $.jstree.plugins.changed = function (options, parent) { - var last = []; - this.trigger = function (ev, data) { - var i, j; - if(!data) { - data = {}; - } - if(ev.replace('.jstree','') === 'changed') { - data.changed = { selected : [], deselected : [] }; - var tmp = {}; - for(i = 0, j = last.length; i < j; i++) { - tmp[last[i]] = 1; - } - for(i = 0, j = data.selected.length; i < j; i++) { - if(!tmp[data.selected[i]]) { - data.changed.selected.push(data.selected[i]); - } - else { - tmp[data.selected[i]] = 2; - } - } - for(i = 0, j = last.length; i < j; i++) { - if(tmp[last[i]] === 1) { - data.changed.deselected.push(last[i]); - } - } - last = data.selected.slice(); - } - /** - * triggered when selection changes (the "changed" plugin enhances the original event with more data) - * @event - * @name changed.jstree - * @param {Object} node - * @param {Object} action the action that caused the selection to change - * @param {Array} selected the current selection - * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event - * @param {Object} event the event (if any) that triggered this changed event - * @plugin changed - */ - parent.trigger.call(this, ev, data); - }; - this.refresh = function (skip_loading, forget_state) { - last = []; - return parent.refresh.apply(this, arguments); - }; - }; - -/** - * ### Checkbox plugin - * - * This plugin renders checkbox icons in front of each node, making multiple selection much easier. - * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up. - */ - - var _i = document.createElement('I'); - _i.className = 'jstree-icon jstree-checkbox'; - _i.setAttribute('role', 'presentation'); - /** - * stores all defaults for the checkbox plugin - * @name $.jstree.defaults.checkbox - * @plugin checkbox - */ - $.jstree.defaults.checkbox = { - /** - * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`. - * @name $.jstree.defaults.checkbox.visible - * @plugin checkbox - */ - visible : true, - /** - * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`. - * @name $.jstree.defaults.checkbox.three_state - * @plugin checkbox - */ - three_state : true, - /** - * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`. - * @name $.jstree.defaults.checkbox.whole_node - * @plugin checkbox - */ - whole_node : true, - /** - * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`. - * @name $.jstree.defaults.checkbox.keep_selected_style - * @plugin checkbox - */ - keep_selected_style : true, - /** - * This setting controls how cascading and undetermined nodes are applied. - * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used. - * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''. - * @name $.jstree.defaults.checkbox.cascade - * @plugin checkbox - */ - cascade : '', - /** - * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing. - * @name $.jstree.defaults.checkbox.tie_selection - * @plugin checkbox - */ - tie_selection : true, - - /** - * This setting controls if cascading down affects disabled checkboxes - * @name $.jstree.defaults.checkbox.cascade_to_disabled - * @plugin checkbox - */ - cascade_to_disabled : true, - - /** - * This setting controls if cascading down affects hidden checkboxes - * @name $.jstree.defaults.checkbox.cascade_to_hidden - * @plugin checkbox - */ - cascade_to_hidden : true - }; - $.jstree.plugins.checkbox = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - this._data.checkbox.uto = false; - this._data.checkbox.selected = []; - if(this.settings.checkbox.three_state) { - this.settings.checkbox.cascade = 'up+down+undetermined'; - } - this.element - .on("init.jstree", $.proxy(function () { - this._data.checkbox.visible = this.settings.checkbox.visible; - if(!this.settings.checkbox.keep_selected_style) { - this.element.addClass('jstree-checkbox-no-clicked'); - } - if(this.settings.checkbox.tie_selection) { - this.element.addClass('jstree-checkbox-selection'); - } - }, this)) - .on("loading.jstree", $.proxy(function () { - this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ](); - }, this)); - if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { - this.element - .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () { - // only if undetermined is in setting - if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } - this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); - }, this)); - } - if(!this.settings.checkbox.tie_selection) { - this.element - .on('model.jstree', $.proxy(function (e, data) { - var m = this._model.data, - p = m[data.parent], - dpc = data.nodes, - i, j; - for(i = 0, j = dpc.length; i < j; i++) { - m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked); - if(m[dpc[i]].state.checked) { - this._data.checkbox.selected.push(dpc[i]); - } - } - }, this)); - } - if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) { - this.element - .on('model.jstree', $.proxy(function (e, data) { - var m = this._model.data, - p = m[data.parent], - dpc = data.nodes, - chd = [], - c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection; - - if(s.indexOf('down') !== -1) { - // apply down - if(p.state[ t ? 'selected' : 'checked' ]) { - for(i = 0, j = dpc.length; i < j; i++) { - m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true; - } - - this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc); - } - else { - for(i = 0, j = dpc.length; i < j; i++) { - if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) { - for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) { - m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true; - } - this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d); - } - } - } - } - - if(s.indexOf('up') !== -1) { - // apply up - for(i = 0, j = p.children_d.length; i < j; i++) { - if(!m[p.children_d[i]].children.length) { - chd.push(m[p.children_d[i]].parent); - } - } - chd = $.vakata.array_unique(chd); - for(k = 0, l = chd.length; k < l; k++) { - p = m[chd[k]]; - while(p && p.id !== $.jstree.root) { - c = 0; - for(i = 0, j = p.children.length; i < j; i++) { - c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; - } - if(c === j) { - p.state[ t ? 'selected' : 'checked' ] = true; - this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); - tmp = this.get_node(p, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - break; - } - p = this.get_node(p.parent); - } - } - } - - this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected); - }, this)) - .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) { - var self = this, - obj = data.node, - m = this._model.data, - par = this.get_node(obj.parent), - i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, - sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected; - - for (i = 0, j = cur.length; i < j; i++) { - sel[cur[i]] = true; - } - - // apply down - if(s.indexOf('down') !== -1) { - //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d)); - var selectedIds = this._cascade_new_checked_state(obj.id, true); - var temp = obj.children_d.concat(obj.id); - for (i = 0, j = temp.length; i < j; i++) { - if (selectedIds.indexOf(temp[i]) > -1) { - sel[temp[i]] = true; - } - else { - delete sel[temp[i]]; - } - } - } - - // apply up - if(s.indexOf('up') !== -1) { - while(par && par.id !== $.jstree.root) { - c = 0; - for(i = 0, j = par.children.length; i < j; i++) { - c += m[par.children[i]].state[ t ? 'selected' : 'checked' ]; - } - if(c === j) { - par.state[ t ? 'selected' : 'checked' ] = true; - sel[par.id] = true; - //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id); - tmp = this.get_node(par, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - break; - } - par = this.get_node(par.parent); - } - } - - cur = []; - for (i in sel) { - if (sel.hasOwnProperty(i)) { - cur.push(i); - } - } - this._data[ t ? 'core' : 'checkbox' ].selected = cur; - }, this)) - .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) { - var obj = this.get_node($.jstree.root), - m = this._model.data, - i, j, tmp; - for(i = 0, j = obj.children_d.length; i < j; i++) { - tmp = m[obj.children_d[i]]; - if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { - tmp.original.state.undetermined = false; - } - } - }, this)) - .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) { - var self = this, - obj = data.node, - dom = this.get_node(obj, true), - i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, - cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {}, - stillSelectedIds = [], - allIds = obj.children_d.concat(obj.id); - - // apply down - if(s.indexOf('down') !== -1) { - var selectedIds = this._cascade_new_checked_state(obj.id, false); - - cur = cur.filter(function(id) { - return allIds.indexOf(id) === -1 || selectedIds.indexOf(id) > -1; - }); - } - - // only apply up if cascade up is enabled and if this node is not selected - // (if all child nodes are disabled and cascade_to_disabled === false then this node will till be selected). - if(s.indexOf('up') !== -1 && cur.indexOf(obj.id) === -1) { - for(i = 0, j = obj.parents.length; i < j; i++) { - tmp = this._model.data[obj.parents[i]]; - tmp.state[ t ? 'selected' : 'checked' ] = false; - if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { - tmp.original.state.undetermined = false; - } - tmp = this.get_node(obj.parents[i], true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - - cur = cur.filter(function(id) { - return obj.parents.indexOf(id) === -1; - }); - } - - this._data[ t ? 'core' : 'checkbox' ].selected = cur; - }, this)); - } - if(this.settings.checkbox.cascade.indexOf('up') !== -1) { - this.element - .on('delete_node.jstree', $.proxy(function (e, data) { - // apply up (whole handler) - var p = this.get_node(data.parent), - m = this._model.data, - i, j, c, tmp, t = this.settings.checkbox.tie_selection; - while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { - c = 0; - for(i = 0, j = p.children.length; i < j; i++) { - c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; - } - if(j > 0 && c === j) { - p.state[ t ? 'selected' : 'checked' ] = true; - this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); - tmp = this.get_node(p, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - break; - } - p = this.get_node(p.parent); - } - }, this)) - .on('move_node.jstree', $.proxy(function (e, data) { - // apply up (whole handler) - var is_multi = data.is_multi, - old_par = data.old_parent, - new_par = this.get_node(data.parent), - m = this._model.data, - p, c, i, j, tmp, t = this.settings.checkbox.tie_selection; - if(!is_multi) { - p = this.get_node(old_par); - while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { - c = 0; - for(i = 0, j = p.children.length; i < j; i++) { - c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; - } - if(j > 0 && c === j) { - p.state[ t ? 'selected' : 'checked' ] = true; - this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); - tmp = this.get_node(p, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - break; - } - p = this.get_node(p.parent); - } - } - p = new_par; - while(p && p.id !== $.jstree.root) { - c = 0; - for(i = 0, j = p.children.length; i < j; i++) { - c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; - } - if(c === j) { - if(!p.state[ t ? 'selected' : 'checked' ]) { - p.state[ t ? 'selected' : 'checked' ] = true; - this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); - tmp = this.get_node(p, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - } - else { - if(p.state[ t ? 'selected' : 'checked' ]) { - p.state[ t ? 'selected' : 'checked' ] = false; - this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id); - tmp = this.get_node(p, true); - if(tmp && tmp.length) { - tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - break; - } - } - p = this.get_node(p.parent); - } - }, this)); - } - }; - /** - * get an array of all nodes whose state is "undetermined" - * @name get_undetermined([full]) - * @param {boolean} full: if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - * @plugin checkbox - */ - this.get_undetermined = function (full) { - if (this.settings.checkbox.cascade.indexOf('undetermined') === -1) { - return []; - } - var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this, r = []; - for(i = 0, j = s.length; i < j; i++) { - if(m[s[i]] && m[s[i]].parents) { - for(k = 0, l = m[s[i]].parents.length; k < l; k++) { - if(o[m[s[i]].parents[k]] !== undefined) { - break; - } - if(m[s[i]].parents[k] !== $.jstree.root) { - o[m[s[i]].parents[k]] = true; - p.push(m[s[i]].parents[k]); - } - } - } - } - // attempt for server side undetermined state - this.element.find('.jstree-closed').not(':has(.jstree-children)') - .each(function () { - var tmp = tt.get_node(this), tmp2; - - if(!tmp) { return; } - - if(!tmp.state.loaded) { - if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) { - if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) { - o[tmp.id] = true; - p.push(tmp.id); - } - for(k = 0, l = tmp.parents.length; k < l; k++) { - if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) { - o[tmp.parents[k]] = true; - p.push(tmp.parents[k]); - } - } - } - } - else { - for(i = 0, j = tmp.children_d.length; i < j; i++) { - tmp2 = m[tmp.children_d[i]]; - if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) { - if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) { - o[tmp2.id] = true; - p.push(tmp2.id); - } - for(k = 0, l = tmp2.parents.length; k < l; k++) { - if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) { - o[tmp2.parents[k]] = true; - p.push(tmp2.parents[k]); - } - } - } - } - } - }); - for (i = 0, j = p.length; i < j; i++) { - if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) { - r.push(full ? m[p[i]] : p[i]); - } - } - return r; - }; - /** - * set the undetermined state where and if necessary. Used internally. - * @private - * @name _undetermined() - * @plugin checkbox - */ - this._undetermined = function () { - if(this.element === null) { return; } - var p = this.get_undetermined(false), i, j, s; - - this.element.find('.jstree-undetermined').removeClass('jstree-undetermined'); - for (i = 0, j = p.length; i < j; i++) { - s = this.get_node(p[i], true); - if(s && s.length) { - s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined'); - } - } - }; - this.redraw_node = function(obj, deep, is_callback, force_render) { - obj = parent.redraw_node.apply(this, arguments); - if(obj) { - var i, j, tmp = null, icon = null; - for(i = 0, j = obj.childNodes.length; i < j; i++) { - if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { - tmp = obj.childNodes[i]; - break; - } - } - if(tmp) { - if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; } - icon = _i.cloneNode(false); - if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; } - tmp.insertBefore(icon, tmp.childNodes[0]); - } - } - if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { - if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } - this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); - } - return obj; - }; - /** - * show the node checkbox icons - * @name show_checkboxes() - * @plugin checkbox - */ - this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); }; - /** - * hide the node checkbox icons - * @name hide_checkboxes() - * @plugin checkbox - */ - this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); }; - /** - * toggle the node icons - * @name toggle_checkboxes() - * @plugin checkbox - */ - this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } }; - /** - * checks if a node is in an undetermined state - * @name is_undetermined(obj) - * @param {mixed} obj - * @return {Boolean} - */ - this.is_undetermined = function (obj) { - obj = this.get_node(obj); - var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data; - if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) { - return false; - } - if(!obj.state.loaded && obj.original.state.undetermined === true) { - return true; - } - for(i = 0, j = obj.children_d.length; i < j; i++) { - if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) { - return true; - } - } - return false; - }; - /** - * disable a node's checkbox - * @name disable_checkbox(obj) - * @param {mixed} obj an array can be used too - * @trigger disable_checkbox.jstree - * @plugin checkbox - */ - this.disable_checkbox = function (obj) { - var t1, t2, dom; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.disable_checkbox(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(!obj.state.checkbox_disabled) { - obj.state.checkbox_disabled = true; - if(dom && dom.length) { - dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled'); - } - /** - * triggered when an node's checkbox is disabled - * @event - * @name disable_checkbox.jstree - * @param {Object} node - * @plugin checkbox - */ - this.trigger('disable_checkbox', { 'node' : obj }); - } - }; - /** - * enable a node's checkbox - * @name disable_checkbox(obj) - * @param {mixed} obj an array can be used too - * @trigger enable_checkbox.jstree - * @plugin checkbox - */ - this.enable_checkbox = function (obj) { - var t1, t2, dom; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.enable_checkbox(obj[t1]); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(obj.state.checkbox_disabled) { - obj.state.checkbox_disabled = false; - if(dom && dom.length) { - dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled'); - } - /** - * triggered when an node's checkbox is enabled - * @event - * @name enable_checkbox.jstree - * @param {Object} node - * @plugin checkbox - */ - this.trigger('enable_checkbox', { 'node' : obj }); - } - }; - - this.activate_node = function (obj, e) { - if($(e.target).hasClass('jstree-checkbox-disabled')) { - return false; - } - if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) { - e.ctrlKey = true; - } - if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) { - return parent.activate_node.call(this, obj, e); - } - if(this.is_disabled(obj)) { - return false; - } - if(this.is_checked(obj)) { - this.uncheck_node(obj, e); - } - else { - this.check_node(obj, e); - } - this.trigger('activate_node', { 'node' : this.get_node(obj) }); - }; - - /** - * Cascades checked state to a node and all its descendants. This function does NOT affect hidden and disabled nodes (or their descendants). - * However if these unaffected nodes are already selected their ids will be included in the returned array. - * @private - * @param {string} id the node ID - * @param {bool} checkedState should the nodes be checked or not - * @returns {Array} Array of all node id's (in this tree branch) that are checked. - */ - this._cascade_new_checked_state = function (id, checkedState) { - var self = this; - var t = this.settings.checkbox.tie_selection; - var node = this._model.data[id]; - var selectedNodeIds = []; - var selectedChildrenIds = [], i, j, selectedChildIds; - - if ( - (this.settings.checkbox.cascade_to_disabled || !node.state.disabled) && - (this.settings.checkbox.cascade_to_hidden || !node.state.hidden) - ) { - //First try and check/uncheck the children - if (node.children) { - for (i = 0, j = node.children.length; i < j; i++) { - var childId = node.children[i]; - selectedChildIds = self._cascade_new_checked_state(childId, checkedState); - selectedNodeIds = selectedNodeIds.concat(selectedChildIds); - if (selectedChildIds.indexOf(childId) > -1) { - selectedChildrenIds.push(childId); - } - } - } - - var dom = self.get_node(node, true); - - //A node's state is undetermined if some but not all of it's children are checked/selected . - var undetermined = selectedChildrenIds.length > 0 && selectedChildrenIds.length < node.children.length; - - if(node.original && node.original.state && node.original.state.undetermined) { - node.original.state.undetermined = undetermined; - } - - //If a node is undetermined then remove selected class - if (undetermined) { - node.state[ t ? 'selected' : 'checked' ] = false; - dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - //Otherwise, if the checkedState === true (i.e. the node is being checked now) and all of the node's children are checked (if it has any children), - //check the node and style it correctly. - else if (checkedState && selectedChildrenIds.length === node.children.length) { - node.state[ t ? 'selected' : 'checked' ] = checkedState; - selectedNodeIds.push(node.id); - - dom.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - else { - node.state[ t ? 'selected' : 'checked' ] = false; - dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); - } - } - else { - selectedChildIds = this.get_checked_descendants(id); - - if (node.state[ t ? 'selected' : 'checked' ]) { - selectedChildIds.push(node.id); - } - - selectedNodeIds = selectedNodeIds.concat(selectedChildIds); - } - - return selectedNodeIds; - }; - - /** - * Gets ids of nodes selected in branch (of tree) specified by id (does not include the node specified by id) - * @name get_checked_descendants(obj) - * @param {string} id the node ID - * @return {Array} array of IDs - * @plugin checkbox - */ - this.get_checked_descendants = function (id) { - var self = this; - var t = self.settings.checkbox.tie_selection; - var node = self._model.data[id]; - - return node.children_d.filter(function(_id) { - return self._model.data[_id].state[ t ? 'selected' : 'checked' ]; - }); - }; - - /** - * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally) - * @name check_node(obj) - * @param {mixed} obj an array can be used to check multiple nodes - * @trigger check_node.jstree - * @plugin checkbox - */ - this.check_node = function (obj, e) { - if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); } - var dom, t1, t2, th; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.check_node(obj[t1], e); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(!obj.state.checked) { - obj.state.checked = true; - this._data.checkbox.selected.push(obj.id); - if(dom && dom.length) { - dom.children('.jstree-anchor').addClass('jstree-checked'); - } - /** - * triggered when an node is checked (only if tie_selection in checkbox settings is false) - * @event - * @name check_node.jstree - * @param {Object} node - * @param {Array} selected the current selection - * @param {Object} event the event (if any) that triggered this check_node - * @plugin checkbox - */ - this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); - } - }; - /** - * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally) - * @name uncheck_node(obj) - * @param {mixed} obj an array can be used to uncheck multiple nodes - * @trigger uncheck_node.jstree - * @plugin checkbox - */ - this.uncheck_node = function (obj, e) { - if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); } - var t1, t2, dom; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.uncheck_node(obj[t1], e); - } - return true; - } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { - return false; - } - dom = this.get_node(obj, true); - if(obj.state.checked) { - obj.state.checked = false; - this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id); - if(dom.length) { - dom.children('.jstree-anchor').removeClass('jstree-checked'); - } - /** - * triggered when an node is unchecked (only if tie_selection in checkbox settings is false) - * @event - * @name uncheck_node.jstree - * @param {Object} node - * @param {Array} selected the current selection - * @param {Object} event the event (if any) that triggered this uncheck_node - * @plugin checkbox - */ - this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); - } - }; - - /** - * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally) - * @name check_all() - * @trigger check_all.jstree, changed.jstree - * @plugin checkbox - */ - this.check_all = function () { - if(this.settings.checkbox.tie_selection) { return this.select_all(); } - var tmp = this._data.checkbox.selected.concat([]), i, j; - this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat(); - for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { - if(this._model.data[this._data.checkbox.selected[i]]) { - this._model.data[this._data.checkbox.selected[i]].state.checked = true; - } - } - this.redraw(true); - /** - * triggered when all nodes are checked (only if tie_selection in checkbox settings is false) - * @event - * @name check_all.jstree - * @param {Array} selected the current selection - * @plugin checkbox - */ - this.trigger('check_all', { 'selected' : this._data.checkbox.selected }); - }; - /** - * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally) - * @name uncheck_all() - * @trigger uncheck_all.jstree - * @plugin checkbox - */ - this.uncheck_all = function () { - if(this.settings.checkbox.tie_selection) { return this.deselect_all(); } - var tmp = this._data.checkbox.selected.concat([]), i, j; - for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { - if(this._model.data[this._data.checkbox.selected[i]]) { - this._model.data[this._data.checkbox.selected[i]].state.checked = false; - } - } - this._data.checkbox.selected = []; - this.element.find('.jstree-checked').removeClass('jstree-checked'); - /** - * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) - * @event - * @name uncheck_all.jstree - * @param {Object} node the previous selection - * @param {Array} selected the current selection - * @plugin checkbox - */ - this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp }); - }; - /** - * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected) - * @name is_checked(obj) - * @param {mixed} obj - * @return {Boolean} - * @plugin checkbox - */ - this.is_checked = function (obj) { - if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); } - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - return obj.state.checked; - }; - /** - * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected) - * @name get_checked([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - * @plugin checkbox - */ - this.get_checked = function (full) { - if(this.settings.checkbox.tie_selection) { return this.get_selected(full); } - return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected; - }; - /** - * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected) - * @name get_top_checked([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - * @plugin checkbox - */ - this.get_top_checked = function (full) { - if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); } - var tmp = this.get_checked(true), - obj = {}, i, j, k, l; - for(i = 0, j = tmp.length; i < j; i++) { - obj[tmp[i].id] = tmp[i]; - } - for(i = 0, j = tmp.length; i < j; i++) { - for(k = 0, l = tmp[i].children_d.length; k < l; k++) { - if(obj[tmp[i].children_d[k]]) { - delete obj[tmp[i].children_d[k]]; - } - } - } - tmp = []; - for(i in obj) { - if(obj.hasOwnProperty(i)) { - tmp.push(i); - } - } - return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; - }; - /** - * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected) - * @name get_bottom_checked([full]) - * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned - * @return {Array} - * @plugin checkbox - */ - this.get_bottom_checked = function (full) { - if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); } - var tmp = this.get_checked(true), - obj = [], i, j; - for(i = 0, j = tmp.length; i < j; i++) { - if(!tmp[i].children.length) { - obj.push(tmp[i].id); - } - } - return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; - }; - this.load_node = function (obj, callback) { - var k, l, i, j, c, tmp; - if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) { - tmp = this.get_node(obj); - if(tmp && tmp.state.loaded) { - for(k = 0, l = tmp.children_d.length; k < l; k++) { - if(this._model.data[tmp.children_d[k]].state.checked) { - c = true; - this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]); - } - } - } - } - return parent.load_node.apply(this, arguments); - }; - this.get_state = function () { - var state = parent.get_state.apply(this, arguments); - if(this.settings.checkbox.tie_selection) { return state; } - state.checkbox = this._data.checkbox.selected.slice(); - return state; - }; - this.set_state = function (state, callback) { - var res = parent.set_state.apply(this, arguments); - if(res && state.checkbox) { - if(!this.settings.checkbox.tie_selection) { - this.uncheck_all(); - var _this = this; - $.each(state.checkbox, function (i, v) { - _this.check_node(v); - }); - } - delete state.checkbox; - this.set_state(state, callback); - return false; - } - return res; - }; - this.refresh = function (skip_loading, forget_state) { - if(this.settings.checkbox.tie_selection) { - this._data.checkbox.selected = []; - } - return parent.refresh.apply(this, arguments); - }; - }; - - // include the checkbox plugin by default - // $.jstree.defaults.plugins.push("checkbox"); - - -/** - * ### Conditionalselect plugin - * - * This plugin allows defining a callback to allow or deny node selection by user input (activate node method). - */ - - /** - * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`. - * @name $.jstree.defaults.checkbox.visible - * @plugin checkbox - */ - $.jstree.defaults.conditionalselect = function () { return true; }; - $.jstree.plugins.conditionalselect = function (options, parent) { - // own function - this.activate_node = function (obj, e) { - if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) { - return parent.activate_node.call(this, obj, e); - } - }; - }; - - -/** - * ### Contextmenu plugin - * - * Shows a context menu when a node is right-clicked. - */ - - /** - * stores all defaults for the contextmenu plugin - * @name $.jstree.defaults.contextmenu - * @plugin contextmenu - */ - $.jstree.defaults.contextmenu = { - /** - * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. - * @name $.jstree.defaults.contextmenu.select_node - * @plugin contextmenu - */ - select_node : true, - /** - * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. - * @name $.jstree.defaults.contextmenu.show_at_node - * @plugin contextmenu - */ - show_at_node : true, - /** - * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). - * - * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. - * - * * `separator_before` - a boolean indicating if there should be a separator before this item - * * `separator_after` - a boolean indicating if there should be a separator after this item - * * `_disabled` - a boolean indicating if this action should be disabled - * * `label` - a string - the name of the action (could be a function returning a string) - * * `title` - a string - an optional tooltip for the item - * * `action` - a function to be executed if this item is chosen, the function will receive - * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class - * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) - * * `shortcut_label` - shortcut label (like for example `F2` for rename) - * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered - * - * @name $.jstree.defaults.contextmenu.items - * @plugin contextmenu - */ - items : function (o, cb) { // Could be an object directly - return { - "create" : { - "separator_before" : false, - "separator_after" : true, - "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), - "label" : "Create", - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - inst.create_node(obj, {}, "last", function (new_node) { - try { - inst.edit(new_node); - } catch (ex) { - setTimeout(function () { inst.edit(new_node); },0); - } - }); - } - }, - "rename" : { - "separator_before" : false, - "separator_after" : false, - "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), - "label" : "Rename", - /*! - "shortcut" : 113, - "shortcut_label" : 'F2', - "icon" : "glyphicon glyphicon-leaf", - */ - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - inst.edit(obj); - } - }, - "remove" : { - "separator_before" : false, - "icon" : false, - "separator_after" : false, - "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), - "label" : "Delete", - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - if(inst.is_selected(obj)) { - inst.delete_node(inst.get_selected()); - } - else { - inst.delete_node(obj); - } - } - }, - "ccp" : { - "separator_before" : true, - "icon" : false, - "separator_after" : false, - "label" : "Edit", - "action" : false, - "submenu" : { - "cut" : { - "separator_before" : false, - "separator_after" : false, - "label" : "Cut", - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - if(inst.is_selected(obj)) { - inst.cut(inst.get_top_selected()); - } - else { - inst.cut(obj); - } - } - }, - "copy" : { - "separator_before" : false, - "icon" : false, - "separator_after" : false, - "label" : "Copy", - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - if(inst.is_selected(obj)) { - inst.copy(inst.get_top_selected()); - } - else { - inst.copy(obj); - } - } - }, - "paste" : { - "separator_before" : false, - "icon" : false, - "_disabled" : function (data) { - return !$.jstree.reference(data.reference).can_paste(); - }, - "separator_after" : false, - "label" : "Paste", - "action" : function (data) { - var inst = $.jstree.reference(data.reference), - obj = inst.get_node(data.reference); - inst.paste(obj); - } - } - } - } - }; - } - }; - - $.jstree.plugins.contextmenu = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - - var last_ts = 0, cto = null, ex, ey; - this.element - .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { - this.get_container_ul().addClass('jstree-contextmenu'); - }, this)) - .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) { - if (e.target.tagName.toLowerCase() === 'input') { - return; - } - e.preventDefault(); - last_ts = e.ctrlKey ? +new Date() : 0; - if(data || cto) { - last_ts = (+new Date()) + 10000; - } - if(cto) { - clearTimeout(cto); - } - if(!this.is_loading(e.currentTarget)) { - this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); - } - }, this)) - .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { - if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click - $.vakata.context.hide(); - } - last_ts = 0; - }, this)) - .on("touchstart.jstree", ".jstree-anchor", function (e) { - if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { - return; - } - ex = e.originalEvent.changedTouches[0].clientX; - ey = e.originalEvent.changedTouches[0].clientY; - cto = setTimeout(function () { - $(e.currentTarget).trigger('contextmenu', true); - }, 750); - }) - .on('touchmove.vakata.jstree', function (e) { - if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 10 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 10)) { - clearTimeout(cto); - $.vakata.context.hide(); - } - }) - .on('touchend.vakata.jstree', function (e) { - if(cto) { - clearTimeout(cto); - } - }); - - /*! - if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { - var el = null, tm = null; - this.element - .on("touchstart", ".jstree-anchor", function (e) { - el = e.currentTarget; - tm = +new Date(); - $(document).one("touchend", function (e) { - e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); - e.currentTarget = e.target; - tm = ((+(new Date())) - tm); - if(e.target === el && tm > 600 && tm < 1000) { - e.preventDefault(); - $(el).trigger('contextmenu', e); - } - el = null; - tm = null; - }); - }); - } - */ - $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) { - this._data.contextmenu.visible = false; - $(data.reference).removeClass('jstree-context'); - }, this)); - }; - this.teardown = function () { - if(this._data.contextmenu.visible) { - $.vakata.context.hide(); - } - parent.teardown.call(this); - }; - - /** - * prepare and show the context menu for a node - * @name show_contextmenu(obj [, x, y]) - * @param {mixed} obj the node - * @param {Number} x the x-coordinate relative to the document to show the menu at - * @param {Number} y the y-coordinate relative to the document to show the menu at - * @param {Object} e the event if available that triggered the contextmenu - * @plugin contextmenu - * @trigger show_contextmenu.jstree - */ - this.show_contextmenu = function (obj, x, y, e) { - obj = this.get_node(obj); - if(!obj || obj.id === $.jstree.root) { return false; } - var s = this.settings.contextmenu, - d = this.get_node(obj, true), - a = d.children(".jstree-anchor"), - o = false, - i = false; - if(s.show_at_node || x === undefined || y === undefined) { - o = a.offset(); - x = o.left; - y = o.top + this._data.core.li_height; - } - if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { - this.activate_node(obj, e); - } - - i = s.items; - if($.isFunction(i)) { - i = i.call(this, obj, $.proxy(function (i) { - this._show_contextmenu(obj, x, y, i); - }, this)); - } - if($.isPlainObject(i)) { - this._show_contextmenu(obj, x, y, i); - } - }; - /** - * show the prepared context menu for a node - * @name _show_contextmenu(obj, x, y, i) - * @param {mixed} obj the node - * @param {Number} x the x-coordinate relative to the document to show the menu at - * @param {Number} y the y-coordinate relative to the document to show the menu at - * @param {Number} i the object of items to show - * @plugin contextmenu - * @trigger show_contextmenu.jstree - * @private - */ - this._show_contextmenu = function (obj, x, y, i) { - var d = this.get_node(obj, true), - a = d.children(".jstree-anchor"); - $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) { - var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; - $(data.element).addClass(cls); - a.addClass('jstree-context'); - }, this)); - this._data.contextmenu.visible = true; - $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); - /** - * triggered when the contextmenu is shown for a node - * @event - * @name show_contextmenu.jstree - * @param {Object} node the node - * @param {Number} x the x-coordinate of the menu relative to the document - * @param {Number} y the y-coordinate of the menu relative to the document - * @plugin contextmenu - */ - this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); - }; - }; - - // contextmenu helper - (function ($) { - var right_to_left = false, - vakata_context = { - element : false, - reference : false, - position_x : 0, - position_y : 0, - items : [], - html : "", - is_visible : false - }; - - $.vakata.context = { - settings : { - hide_onmouseleave : 0, - icons : true - }, - _trigger : function (event_name) { - $(document).triggerHandler("context_" + event_name + ".vakata", { - "reference" : vakata_context.reference, - "element" : vakata_context.element, - "position" : { - "x" : vakata_context.position_x, - "y" : vakata_context.position_y - } - }); - }, - _execute : function (i) { - i = vakata_context.items[i]; - return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { - "item" : i, - "reference" : vakata_context.reference, - "element" : vakata_context.element, - "position" : { - "x" : vakata_context.position_x, - "y" : vakata_context.position_y - } - }) : false; - }, - _parse : function (o, is_callback) { - if(!o) { return false; } - if(!is_callback) { - vakata_context.html = ""; - vakata_context.items = []; - } - var str = "", - sep = false, - tmp; - - if(is_callback) { str += "<"+"ul>"; } - $.each(o, function (i, val) { - if(!val) { return true; } - vakata_context.items.push(val); - if(!sep && val.separator_before) { - str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; - } - sep = false; - str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; - str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; - if($.vakata.context.settings.icons) { - str += "<"+"i "; - if(val.icon) { - if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } - else { str += " class='" + val.icon + "' "; } - } - str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; - } - str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' '+ (val.shortcut_label || '') +'':'') + "<"+"/a>"; - if(val.submenu) { - tmp = $.vakata.context._parse(val.submenu, true); - if(tmp) { str += tmp; } - } - str += "<"+"/li>"; - if(val.separator_after) { - str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; - sep = true; - } - }); - str = str.replace(/
  • <\/li\>$/,""); - if(is_callback) { str += ""; } - /** - * triggered on the document when the contextmenu is parsed (HTML is built) - * @event - * @plugin contextmenu - * @name context_parse.vakata - * @param {jQuery} reference the element that was right clicked - * @param {jQuery} element the DOM element of the menu itself - * @param {Object} position the x & y coordinates of the menu - */ - if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } - return str.length > 10 ? str : false; - }, - _show_submenu : function (o) { - o = $(o); - if(!o.length || !o.children("ul").length) { return; } - var e = o.children("ul"), - xl = o.offset().left, - x = xl + o.outerWidth(), - y = o.offset().top, - w = e.width(), - h = e.height(), - dw = $(window).width() + $(window).scrollLeft(), - dh = $(window).height() + $(window).scrollTop(); - // може да се спести е една проверка - дали няма някой от класовете вече нагоре - if(right_to_left) { - o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); - } - else { - o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); - } - if(y + h + 10 > dh) { - e.css("bottom","-1px"); - } - - //if does not fit - stick it to the side - if (o.hasClass('vakata-context-right')) { - if (xl < w) { - e.css("margin-right", xl - w); - } - } else { - if (dw - x < w) { - e.css("margin-left", dw - x - w); - } - } - - e.show(); - }, - show : function (reference, position, data) { - var o, e, x, y, w, h, dw, dh, cond = true; - if(vakata_context.element && vakata_context.element.length) { - vakata_context.element.width(''); - } - switch(cond) { - case (!position && !reference): - return false; - case (!!position && !!reference): - vakata_context.reference = reference; - vakata_context.position_x = position.x; - vakata_context.position_y = position.y; - break; - case (!position && !!reference): - vakata_context.reference = reference; - o = reference.offset(); - vakata_context.position_x = o.left + reference.outerHeight(); - vakata_context.position_y = o.top; - break; - case (!!position && !reference): - vakata_context.position_x = position.x; - vakata_context.position_y = position.y; - break; - } - if(!!reference && !data && $(reference).data('vakata_contextmenu')) { - data = $(reference).data('vakata_contextmenu'); - } - if($.vakata.context._parse(data)) { - vakata_context.element.html(vakata_context.html); - } - if(vakata_context.items.length) { - vakata_context.element.appendTo(document.body); - e = vakata_context.element; - x = vakata_context.position_x; - y = vakata_context.position_y; - w = e.width(); - h = e.height(); - dw = $(window).width() + $(window).scrollLeft(); - dh = $(window).height() + $(window).scrollTop(); - if(right_to_left) { - x -= (e.outerWidth() - $(reference).outerWidth()); - if(x < $(window).scrollLeft() + 20) { - x = $(window).scrollLeft() + 20; - } - } - if(x + w + 20 > dw) { - x = dw - (w + 20); - } - if(y + h + 20 > dh) { - y = dh - (h + 20); - } - - vakata_context.element - .css({ "left" : x, "top" : y }) - .show() - .find('a').first().focus().parent().addClass("vakata-context-hover"); - vakata_context.is_visible = true; - /** - * triggered on the document when the contextmenu is shown - * @event - * @plugin contextmenu - * @name context_show.vakata - * @param {jQuery} reference the element that was right clicked - * @param {jQuery} element the DOM element of the menu itself - * @param {Object} position the x & y coordinates of the menu - */ - $.vakata.context._trigger("show"); - } - }, - hide : function () { - if(vakata_context.is_visible) { - vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach(); - vakata_context.is_visible = false; - /** - * triggered on the document when the contextmenu is hidden - * @event - * @plugin contextmenu - * @name context_hide.vakata - * @param {jQuery} reference the element that was right clicked - * @param {jQuery} element the DOM element of the menu itself - * @param {Object} position the x & y coordinates of the menu - */ - $.vakata.context._trigger("hide"); - } - } - }; - $(function () { - right_to_left = $(document.body).css("direction") === "rtl"; - var to = false; - - vakata_context.element = $("
      "); - vakata_context.element - .on("mouseenter", "li", function (e) { - e.stopImmediatePropagation(); - - if($.contains(this, e.relatedTarget)) { - // премахнато заради delegate mouseleave по-долу - // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); - return; - } - - if(to) { clearTimeout(to); } - vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); - - $(this) - .siblings().find("ul").hide().end().end() - .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); - $.vakata.context._show_submenu(this); - }) - // тестово - дали не натоварва? - .on("mouseleave", "li", function (e) { - if($.contains(this, e.relatedTarget)) { return; } - $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); - }) - .on("mouseleave", function (e) { - $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); - if($.vakata.context.settings.hide_onmouseleave) { - to = setTimeout( - (function (t) { - return function () { $.vakata.context.hide(); }; - }(this)), $.vakata.context.settings.hide_onmouseleave); - } - }) - .on("click", "a", function (e) { - e.preventDefault(); - //}) - //.on("mouseup", "a", function (e) { - if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { - $.vakata.context.hide(); - } - }) - .on('keydown', 'a', function (e) { - var o = null; - switch(e.which) { - case 13: - case 32: - e.type = "click"; - e.preventDefault(); - $(e.currentTarget).trigger(e); - break; - case 37: - if(vakata_context.is_visible) { - vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus(); - e.stopImmediatePropagation(); - e.preventDefault(); - } - break; - case 38: - if(vakata_context.is_visible) { - o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); - if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } - o.addClass("vakata-context-hover").children('a').focus(); - e.stopImmediatePropagation(); - e.preventDefault(); - } - break; - case 39: - if(vakata_context.is_visible) { - vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus(); - e.stopImmediatePropagation(); - e.preventDefault(); - } - break; - case 40: - if(vakata_context.is_visible) { - o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); - if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } - o.addClass("vakata-context-hover").children('a').focus(); - e.stopImmediatePropagation(); - e.preventDefault(); - } - break; - case 27: - $.vakata.context.hide(); - e.preventDefault(); - break; - default: - //console.log(e.which); - break; - } - }) - .on('keydown', function (e) { - e.preventDefault(); - var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); - if(a.parent().not('.vakata-context-disabled')) { - a.click(); - } - }); - - $(document) - .on("mousedown.vakata.jstree", function (e) { - if(vakata_context.is_visible && vakata_context.element[0] !== e.target && !$.contains(vakata_context.element[0], e.target)) { - $.vakata.context.hide(); - } - }) - .on("context_show.vakata.jstree", function (e, data) { - vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); - if(right_to_left) { - vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); - } - // also apply a RTL class? - vakata_context.element.find("ul").hide().end(); - }); - }); - }($)); - // $.jstree.defaults.plugins.push("contextmenu"); - - -/** - * ### Drag'n'drop plugin - * - * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. - */ - - /** - * stores all defaults for the drag'n'drop plugin - * @name $.jstree.defaults.dnd - * @plugin dnd - */ - $.jstree.defaults.dnd = { - /** - * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. - * @name $.jstree.defaults.dnd.copy - * @plugin dnd - */ - copy : true, - /** - * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. - * @name $.jstree.defaults.dnd.open_timeout - * @plugin dnd - */ - open_timeout : 500, - /** - * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging - * @name $.jstree.defaults.dnd.is_draggable - * @plugin dnd - */ - is_draggable : true, - /** - * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` - * @name $.jstree.defaults.dnd.check_while_dragging - * @plugin dnd - */ - check_while_dragging : true, - /** - * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` - * @name $.jstree.defaults.dnd.always_copy - * @plugin dnd - */ - always_copy : false, - /** - * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` - * @name $.jstree.defaults.dnd.inside_pos - * @plugin dnd - */ - inside_pos : 0, - /** - * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node - * @name $.jstree.defaults.dnd.drag_selection - * @plugin dnd - */ - drag_selection : true, - /** - * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. - * @name $.jstree.defaults.dnd.touch - * @plugin dnd - */ - touch : true, - /** - * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. - * @name $.jstree.defaults.dnd.large_drop_target - * @plugin dnd - */ - large_drop_target : false, - /** - * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". - * @name $.jstree.defaults.dnd.large_drag_target - * @plugin dnd - */ - large_drag_target : false, - /** - * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. - * @reference http://caniuse.com/#feat=dragndrop - * @name $.jstree.defaults.dnd.use_html5 - * @plugin dnd - */ - use_html5: false - }; - var drg, elm; - // TODO: now check works by checking for each node individually, how about max_children, unique, etc? - $.jstree.plugins.dnd = function (options, parent) { - this.init = function (el, options) { - parent.init.call(this, el, options); - this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); - }; - this.bind = function () { - parent.bind.call(this); - - this.element - .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { - if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { - return true; - } - if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { - return true; - } - var obj = this.get_node(e.target), - mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, - txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); - if(this.settings.core.force_text) { - txt = $.vakata.html.escape(txt); - } - if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && - (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) - ) { - drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; - elm = e.currentTarget; - if (this.settings.dnd.use_html5) { - $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); - } else { - this.element.trigger('mousedown.jstree'); - return $.vakata.dnd.start(e, drg, '
      ' + txt + '
      '); - } - } - }, this)); - if (this.settings.dnd.use_html5) { - this.element - .on('dragover.jstree', function (e) { - e.preventDefault(); - $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); - return false; - }) - //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { - // e.preventDefault(); - // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); - // return false; - // }, this)) - .on('drop.jstree', $.proxy(function (e) { - e.preventDefault(); - $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); - return false; - }, this)); - } - }; - this.redraw_node = function(obj, deep, callback, force_render) { - obj = parent.redraw_node.apply(this, arguments); - if (obj && this.settings.dnd.use_html5) { - if (this.settings.dnd.large_drag_target) { - obj.setAttribute('draggable', true); - } else { - var i, j, tmp = null; - for(i = 0, j = obj.childNodes.length; i < j; i++) { - if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { - tmp = obj.childNodes[i]; - break; - } - } - if(tmp) { - tmp.setAttribute('draggable', true); - } - } - } - return obj; - }; - }; - - $(function() { - // bind only once for all instances - var lastmv = false, - laster = false, - lastev = false, - opento = false, - marker = $('
       
      ').hide(); //.appendTo('body'); - - $(document) - .on('dragover.vakata.jstree', function (e) { - if (elm) { - $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); - } - }) - .on('drop.vakata.jstree', function (e) { - if (elm) { - $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); - elm = null; - drg = null; - } - }) - .on('dnd_start.vakata.jstree', function (e, data) { - lastmv = false; - lastev = false; - if(!data || !data.data || !data.data.jstree) { return; } - marker.appendTo(document.body); //.show(); - }) - .on('dnd_move.vakata.jstree', function (e, data) { - var isDifferentNode = data.event.target !== lastev.target; - if(opento) { - if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { - clearTimeout(opento); - } - } - if(!data || !data.data || !data.data.jstree) { return; } - - // if we are hovering the marker image do nothing (can happen on "inside" drags) - if(data.event.target.id && data.event.target.id === 'jstree-marker') { - return; - } - lastev = data.event; - - var ins = $.jstree.reference(data.event.target), - ref = false, - off = false, - rel = false, - tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn; - // if we are over an instance - if(ins && ins._data && ins._data.dnd) { - marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); - is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); - data.helper - .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) - .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); - - // if are hovering the container itself add a new root node - //console.log(data.event); - if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { - ok = true; - for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { - ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); - if(!ok) { break; } - } - if(ok) { - lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; - marker.hide(); - data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); - if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { - data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; - } - return; - } - } - else { - // if we are hovering a tree node - ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); - if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { - off = ref.offset(); - rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; - h = ref.outerHeight(); - if(rel < h / 3) { - o = ['b', 'i', 'a']; - } - else if(rel > h - h / 3) { - o = ['a', 'i', 'b']; - } - else { - o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; - } - $.each(o, function (j, v) { - switch(v) { - case 'b': - l = off.left - 6; - t = off.top; - p = ins.get_parent(ref); - i = ref.parent().index(); - break; - case 'i': - ip = ins.settings.dnd.inside_pos; - tm = ins.get_node(ref.parent()); - l = off.left - 2; - t = off.top + h / 2 + 1; - p = tm.id; - i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); - break; - case 'a': - l = off.left - 6; - t = off.top + h; - p = ins.get_parent(ref); - i = ref.parent().index() + 1; - break; - } - ok = true; - for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { - op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; - ps = i; - if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { - pr = ins.get_node(p); - if(ps > $.inArray(data.data.nodes[t1], pr.children)) { - ps -= 1; - } - } - ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); - if(!ok) { - if(ins && ins.last_error) { laster = ins.last_error(); } - break; - } - } - if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { - if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { - if (opento) { clearTimeout(opento); } - opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); - } - } - if(ok) { - pn = ins.get_node(p, true); - if (!pn.hasClass('.jstree-dnd-parent')) { - $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); - pn.addClass('jstree-dnd-parent'); - } - lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; - marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); - data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); - if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { - data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; - } - laster = {}; - o = true; - return false; - } - }); - if(o === true) { return; } - } - } - } - $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); - lastmv = false; - data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); - if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { - //data.event.originalEvent.dataTransfer.dropEffect = 'none'; - } - marker.hide(); - }) - .on('dnd_scroll.vakata.jstree', function (e, data) { - if(!data || !data.data || !data.data.jstree) { return; } - marker.hide(); - lastmv = false; - lastev = false; - data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); - }) - .on('dnd_stop.vakata.jstree', function (e, data) { - $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); - if(opento) { clearTimeout(opento); } - if(!data || !data.data || !data.data.jstree) { return; } - marker.hide().detach(); - var i, j, nodes = []; - if(lastmv) { - for(i = 0, j = data.data.nodes.length; i < j; i++) { - nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; - } - lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin); - } - else { - i = $(data.event.target).closest('.jstree'); - if(i.length && laster && laster.error && laster.error === 'check') { - i = i.jstree(true); - if(i) { - i.settings.core.error.call(this, laster); - } - } - } - lastev = false; - lastmv = false; - }) - .on('keyup.jstree keydown.jstree', function (e, data) { - data = $.vakata.dnd._get(); - if(data && data.data && data.data.jstree) { - if (e.type === "keyup" && e.which === 27) { - if (opento) { clearTimeout(opento); } - lastmv = false; - laster = false; - lastev = false; - opento = false; - marker.hide().detach(); - $.vakata.dnd._clean(); - } else { - data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); - if(lastev) { - lastev.metaKey = e.metaKey; - lastev.ctrlKey = e.ctrlKey; - $.vakata.dnd._trigger('move', lastev); - } - } - } - }); - }); - - // helpers - (function ($) { - $.vakata.html = { - div : $('
      '), - escape : function (str) { - return $.vakata.html.div.text(str).html(); - }, - strip : function (str) { - return $.vakata.html.div.empty().append($.parseHTML(str)).text(); - } - }; - // private variable - var vakata_dnd = { - element : false, - target : false, - is_down : false, - is_drag : false, - helper : false, - helper_w: 0, - data : false, - init_x : 0, - init_y : 0, - scroll_l: 0, - scroll_t: 0, - scroll_e: false, - scroll_i: false, - is_touch: false - }; - $.vakata.dnd = { - settings : { - scroll_speed : 10, - scroll_proximity : 20, - helper_left : 5, - helper_top : 10, - threshold : 5, - threshold_touch : 10 - }, - _trigger : function (event_name, e, data) { - if (data === undefined) { - data = $.vakata.dnd._get(); - } - data.event = e; - $(document).triggerHandler("dnd_" + event_name + ".vakata", data); - }, - _get : function () { - return { - "data" : vakata_dnd.data, - "element" : vakata_dnd.element, - "helper" : vakata_dnd.helper - }; - }, - _clean : function () { - if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } - if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } - vakata_dnd = { - element : false, - target : false, - is_down : false, - is_drag : false, - helper : false, - helper_w: 0, - data : false, - init_x : 0, - init_y : 0, - scroll_l: 0, - scroll_t: 0, - scroll_e: false, - scroll_i: false, - is_touch: false - }; - $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); - $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); - }, - _scroll : function (init_only) { - if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { - if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } - return false; - } - if(!vakata_dnd.scroll_i) { - vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); - return false; - } - if(init_only === true) { return false; } - - var i = vakata_dnd.scroll_e.scrollTop(), - j = vakata_dnd.scroll_e.scrollLeft(); - vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); - vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); - if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { - /** - * triggered on the document when a drag causes an element to scroll - * @event - * @plugin dnd - * @name dnd_scroll.vakata - * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start - * @param {DOM} element the DOM element being dragged - * @param {jQuery} helper the helper shown next to the mouse - * @param {jQuery} event the element that is scrolling - */ - $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); - } - }, - start : function (e, data, html) { - if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { - e.pageX = e.originalEvent.changedTouches[0].pageX; - e.pageY = e.originalEvent.changedTouches[0].pageY; - e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); - } - if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } - try { - e.currentTarget.unselectable = "on"; - e.currentTarget.onselectstart = function() { return false; }; - if(e.currentTarget.style) { - e.currentTarget.style.touchAction = "none"; - e.currentTarget.style.msTouchAction = "none"; - e.currentTarget.style.MozUserSelect = "none"; - } - } catch(ignore) { } - vakata_dnd.init_x = e.pageX; - vakata_dnd.init_y = e.pageY; - vakata_dnd.data = data; - vakata_dnd.is_down = true; - vakata_dnd.element = e.currentTarget; - vakata_dnd.target = e.target; - vakata_dnd.is_touch = e.type === "touchstart"; - if(html !== false) { - vakata_dnd.helper = $("
      ").html(html).css({ - "display" : "block", - "margin" : "0", - "padding" : "0", - "position" : "absolute", - "top" : "-2000px", - "lineHeight" : "16px", - "zIndex" : "10000" - }); - } - $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); - $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); - return false; - }, - drag : function (e) { - if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { - e.pageX = e.originalEvent.changedTouches[0].pageX; - e.pageY = e.originalEvent.changedTouches[0].pageY; - e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); - } - if(!vakata_dnd.is_down) { return; } - if(!vakata_dnd.is_drag) { - if( - Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || - Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) - ) { - if(vakata_dnd.helper) { - vakata_dnd.helper.appendTo(document.body); - vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); - } - vakata_dnd.is_drag = true; - $(vakata_dnd.target).one('click.vakata', false); - /** - * triggered on the document when a drag starts - * @event - * @plugin dnd - * @name dnd_start.vakata - * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start - * @param {DOM} element the DOM element being dragged - * @param {jQuery} helper the helper shown next to the mouse - * @param {Object} event the event that caused the start (probably mousemove) - */ - $.vakata.dnd._trigger("start", e); - } - else { return; } - } - - var d = false, w = false, - dh = false, wh = false, - dw = false, ww = false, - dt = false, dl = false, - ht = false, hl = false; - - vakata_dnd.scroll_t = 0; - vakata_dnd.scroll_l = 0; - vakata_dnd.scroll_e = false; - $($(e.target).parentsUntil("body").addBack().get().reverse()) - .filter(function () { - return (/^auto|scroll$/).test($(this).css("overflow")) && - (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); - }) - .each(function () { - var t = $(this), o = t.offset(); - if(this.scrollHeight > this.offsetHeight) { - if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } - if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } - } - if(this.scrollWidth > this.offsetWidth) { - if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } - if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } - } - if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { - vakata_dnd.scroll_e = $(this); - return false; - } - }); - - if(!vakata_dnd.scroll_e) { - d = $(document); w = $(window); - dh = d.height(); wh = w.height(); - dw = d.width(); ww = w.width(); - dt = d.scrollTop(); dl = d.scrollLeft(); - if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } - if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } - if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } - if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } - if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { - vakata_dnd.scroll_e = d; - } - } - if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } - - if(vakata_dnd.helper) { - ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); - hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); - if(dh && ht + 25 > dh) { ht = dh - 50; } - if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } - vakata_dnd.helper.css({ - left : hl + "px", - top : ht + "px" - }); - } - /** - * triggered on the document when a drag is in progress - * @event - * @plugin dnd - * @name dnd_move.vakata - * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start - * @param {DOM} element the DOM element being dragged - * @param {jQuery} helper the helper shown next to the mouse - * @param {Object} event the event that caused this to trigger (most likely mousemove) - */ - $.vakata.dnd._trigger("move", e); - return false; - }, - stop : function (e) { - if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { - e.pageX = e.originalEvent.changedTouches[0].pageX; - e.pageY = e.originalEvent.changedTouches[0].pageY; - e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); - } - if(vakata_dnd.is_drag) { - /** - * triggered on the document when a drag stops (the dragged element is dropped) - * @event - * @plugin dnd - * @name dnd_stop.vakata - * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start - * @param {DOM} element the DOM element being dragged - * @param {jQuery} helper the helper shown next to the mouse - * @param {Object} event the event that caused the stop - */ - if (e.target !== vakata_dnd.target) { - $(vakata_dnd.target).off('click.vakata'); - } - $.vakata.dnd._trigger("stop", e); - } - else { - if(e.type === "touchend" && e.target === vakata_dnd.target) { - var to = setTimeout(function () { $(e.target).click(); }, 100); - $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); - } - } - $.vakata.dnd._clean(); - return false; - } - }; - }($)); - - // include the dnd plugin by default - // $.jstree.defaults.plugins.push("dnd"); - - -/** - * ### Massload plugin - * - * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading). - */ - - /** - * massload configuration - * - * It is possible to set this to a standard jQuery-like AJAX config. - * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used. - * - * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result. - * - * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array. - * - * { - * "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }], - * "id2" : [{ "text" : "Child of ID2", "id" : "c3" }] - * } - * - * @name $.jstree.defaults.massload - * @plugin massload - */ - $.jstree.defaults.massload = null; - $.jstree.plugins.massload = function (options, parent) { - this.init = function (el, options) { - this._data.massload = {}; - parent.init.call(this, el, options); - }; - this._load_nodes = function (nodes, callback, is_callback, force_reload) { - var s = this.settings.massload, - nodesString = JSON.stringify(nodes), - toLoad = [], - m = this._model.data, - i, j, dom; - if (!is_callback) { - for(i = 0, j = nodes.length; i < j; i++) { - if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) { - toLoad.push(nodes[i]); - dom = this.get_node(nodes[i], true); - if (dom && dom.length) { - dom.addClass("jstree-loading").attr('aria-busy',true); - } - } - } - this._data.massload = {}; - if (toLoad.length) { - if($.isFunction(s)) { - return s.call(this, toLoad, $.proxy(function (data) { - var i, j; - if(data) { - for(i in data) { - if(data.hasOwnProperty(i)) { - this._data.massload[i] = data[i]; - } - } - } - for(i = 0, j = nodes.length; i < j; i++) { - dom = this.get_node(nodes[i], true); - if (dom && dom.length) { - dom.removeClass("jstree-loading").attr('aria-busy',false); - } - } - parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); - }, this)); - } - if(typeof s === 'object' && s && s.url) { - s = $.extend(true, {}, s); - if($.isFunction(s.url)) { - s.url = s.url.call(this, toLoad); - } - if($.isFunction(s.data)) { - s.data = s.data.call(this, toLoad); - } - return $.ajax(s) - .done($.proxy(function (data,t,x) { - var i, j; - if(data) { - for(i in data) { - if(data.hasOwnProperty(i)) { - this._data.massload[i] = data[i]; - } - } - } - for(i = 0, j = nodes.length; i < j; i++) { - dom = this.get_node(nodes[i], true); - if (dom && dom.length) { - dom.removeClass("jstree-loading").attr('aria-busy',false); - } - } - parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); - }, this)) - .fail($.proxy(function (f) { - parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); - }, this)); - } - } - } - return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); - }; - this._load_node = function (obj, callback) { - var data = this._data.massload[obj.id], - rslt = null, dom; - if(data) { - rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data']( - obj, - typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data, - function (status) { callback.call(this, status); } - ); - dom = this.get_node(obj.id, true); - if (dom && dom.length) { - dom.removeClass("jstree-loading").attr('aria-busy',false); - } - delete this._data.massload[obj.id]; - return rslt; - } - return parent._load_node.call(this, obj, callback); - }; - }; - -/** - * ### Search plugin - * - * Adds search functionality to jsTree. - */ - - /** - * stores all defaults for the search plugin - * @name $.jstree.defaults.search - * @plugin search - */ - $.jstree.defaults.search = { - /** - * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. - * - * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed. - * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to - * @name $.jstree.defaults.search.ajax - * @plugin search - */ - ajax : false, - /** - * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`. - * @name $.jstree.defaults.search.fuzzy - * @plugin search - */ - fuzzy : false, - /** - * Indicates if the search should be case sensitive. Default is `false`. - * @name $.jstree.defaults.search.case_sensitive - * @plugin search - */ - case_sensitive : false, - /** - * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). - * This setting can be changed at runtime when calling the search method. Default is `false`. - * @name $.jstree.defaults.search.show_only_matches - * @plugin search - */ - show_only_matches : false, - /** - * Indicates if the children of matched element are shown (when show_only_matches is true) - * This setting can be changed at runtime when calling the search method. Default is `false`. - * @name $.jstree.defaults.search.show_only_matches_children - * @plugin search - */ - show_only_matches_children : false, - /** - * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`. - * @name $.jstree.defaults.search.close_opened_onclear - * @plugin search - */ - close_opened_onclear : true, - /** - * Indicates if only leaf nodes should be included in search results. Default is `false`. - * @name $.jstree.defaults.search.search_leaves_only - * @plugin search - */ - search_leaves_only : false, - /** - * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution). - * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`. - * @name $.jstree.defaults.search.search_callback - * @plugin search - */ - search_callback : false - }; - - $.jstree.plugins.search = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - - this._data.search.str = ""; - this._data.search.dom = $(); - this._data.search.res = []; - this._data.search.opn = []; - this._data.search.som = false; - this._data.search.smc = false; - this._data.search.hdn = []; - - this.element - .on("search.jstree", $.proxy(function (e, data) { - if(this._data.search.som && data.res.length) { - var m = this._model.data, i, j, p = [], k, l; - for(i = 0, j = data.res.length; i < j; i++) { - if(m[data.res[i]] && !m[data.res[i]].state.hidden) { - p.push(data.res[i]); - p = p.concat(m[data.res[i]].parents); - if(this._data.search.smc) { - for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { - if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { - p.push(m[data.res[i]].children_d[k]); - } - } - } - } - } - p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); - this._data.search.hdn = this.hide_all(true); - this.show_node(p, true); - this.redraw(true); - } - }, this)) - .on("clear_search.jstree", $.proxy(function (e, data) { - if(this._data.search.som && data.res.length) { - this.show_node(this._data.search.hdn, true); - this.redraw(true); - } - }, this)); - }; - /** - * used to search the tree nodes for a given string - * @name search(str [, skip_async]) - * @param {String} str the search string - * @param {Boolean} skip_async if set to true server will not be queried even if configured - * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers) - * @param {mixed} inside an optional node to whose children to limit the search - * @param {Boolean} append if set to true the results of this search are appended to the previous search - * @plugin search - * @trigger search.jstree - */ - this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) { - if(str === false || $.trim(str.toString()) === "") { - return this.clear_search(); - } - inside = this.get_node(inside); - inside = inside && inside.id ? inside.id : null; - str = str.toString(); - var s = this.settings.search, - a = s.ajax ? s.ajax : false, - m = this._model.data, - f = null, - r = [], - p = [], i, j; - if(this._data.search.res.length && !append) { - this.clear_search(); - } - if(show_only_matches === undefined) { - show_only_matches = s.show_only_matches; - } - if(show_only_matches_children === undefined) { - show_only_matches_children = s.show_only_matches_children; - } - if(!skip_async && a !== false) { - if($.isFunction(a)) { - return a.call(this, str, $.proxy(function (d) { - if(d && d.d) { d = d.d; } - this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { - this.search(str, true, show_only_matches, inside, append, show_only_matches_children); - }); - }, this), inside); - } - else { - a = $.extend({}, a); - if(!a.data) { a.data = {}; } - a.data.str = str; - if(inside) { - a.data.inside = inside; - } - if (this._data.search.lastRequest) { - this._data.search.lastRequest.abort(); - } - this._data.search.lastRequest = $.ajax(a) - .fail($.proxy(function () { - this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) }; - this.settings.core.error.call(this, this._data.core.last_error); - }, this)) - .done($.proxy(function (d) { - if(d && d.d) { d = d.d; } - this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { - this.search(str, true, show_only_matches, inside, append, show_only_matches_children); - }); - }, this)); - return this._data.search.lastRequest; - } - } - if(!append) { - this._data.search.str = str; - this._data.search.dom = $(); - this._data.search.res = []; - this._data.search.opn = []; - this._data.search.som = show_only_matches; - this._data.search.smc = show_only_matches_children; - } - - f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); - $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { - var v = m[i]; - if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) { - r.push(i); - p = p.concat(v.parents); - } - }); - if(r.length) { - p = $.vakata.array_unique(p); - for(i = 0, j = p.length; i < j; i++) { - if(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) { - this._data.search.opn.push(p[i]); - } - } - if(!append) { - this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); - this._data.search.res = r; - } - else { - this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')))); - this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r)); - } - this._data.search.dom.children(".jstree-anchor").addClass('jstree-search'); - } - /** - * triggered after search is complete - * @event - * @name search.jstree - * @param {jQuery} nodes a jQuery collection of matching nodes - * @param {String} str the search string - * @param {Array} res a collection of objects represeing the matching nodes - * @plugin search - */ - this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches }); - }; - /** - * used to clear the last search (removes classes and shows all nodes if filtering is on) - * @name clear_search() - * @plugin search - * @trigger clear_search.jstree - */ - this.clear_search = function () { - if(this.settings.search.close_opened_onclear) { - this.close_node(this._data.search.opn, 0); - } - /** - * triggered after search is complete - * @event - * @name clear_search.jstree - * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search) - * @param {String} str the search string (the last search string) - * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search) - * @plugin search - */ - this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res }); - if(this._data.search.res.length) { - this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) { - return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); - }).join(', #'))); - this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"); - } - this._data.search.str = ""; - this._data.search.res = []; - this._data.search.opn = []; - this._data.search.dom = $(); - }; - - this.redraw_node = function(obj, deep, callback, force_render) { - obj = parent.redraw_node.apply(this, arguments); - if(obj) { - if($.inArray(obj.id, this._data.search.res) !== -1) { - var i, j, tmp = null; - for(i = 0, j = obj.childNodes.length; i < j; i++) { - if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { - tmp = obj.childNodes[i]; - break; - } - } - if(tmp) { - tmp.className += ' jstree-search'; - } - } - } - return obj; - }; - }; - - // helpers - (function ($) { - // from http://kiro.me/projects/fuse.html - $.vakata.search = function(pattern, txt, options) { - options = options || {}; - options = $.extend({}, $.vakata.search.defaults, options); - if(options.fuzzy !== false) { - options.fuzzy = true; - } - pattern = options.caseSensitive ? pattern : pattern.toLowerCase(); - var MATCH_LOCATION = options.location, - MATCH_DISTANCE = options.distance, - MATCH_THRESHOLD = options.threshold, - patternLen = pattern.length, - matchmask, pattern_alphabet, match_bitapScore, search; - if(patternLen > 32) { - options.fuzzy = false; - } - if(options.fuzzy) { - matchmask = 1 << (patternLen - 1); - pattern_alphabet = (function () { - var mask = {}, - i = 0; - for (i = 0; i < patternLen; i++) { - mask[pattern.charAt(i)] = 0; - } - for (i = 0; i < patternLen; i++) { - mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1); - } - return mask; - }()); - match_bitapScore = function (e, x) { - var accuracy = e / patternLen, - proximity = Math.abs(MATCH_LOCATION - x); - if(!MATCH_DISTANCE) { - return proximity ? 1.0 : accuracy; - } - return accuracy + (proximity / MATCH_DISTANCE); - }; - } - search = function (text) { - text = options.caseSensitive ? text : text.toLowerCase(); - if(pattern === text || text.indexOf(pattern) !== -1) { - return { - isMatch: true, - score: 0 - }; - } - if(!options.fuzzy) { - return { - isMatch: false, - score: 1 - }; - } - var i, j, - textLen = text.length, - scoreThreshold = MATCH_THRESHOLD, - bestLoc = text.indexOf(pattern, MATCH_LOCATION), - binMin, binMid, - binMax = patternLen + textLen, - lastRd, start, finish, rd, charMatch, - score = 1, - locations = []; - if (bestLoc !== -1) { - scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); - bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen); - if (bestLoc !== -1) { - scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); - } - } - bestLoc = -1; - for (i = 0; i < patternLen; i++) { - binMin = 0; - binMid = binMax; - while (binMin < binMid) { - if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) { - binMin = binMid; - } else { - binMax = binMid; - } - binMid = Math.floor((binMax - binMin) / 2 + binMin); - } - binMax = binMid; - start = Math.max(1, MATCH_LOCATION - binMid + 1); - finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen; - rd = new Array(finish + 2); - rd[finish + 1] = (1 << i) - 1; - for (j = finish; j >= start; j--) { - charMatch = pattern_alphabet[text.charAt(j - 1)]; - if (i === 0) { - rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; - } else { - rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; - } - if (rd[j] & matchmask) { - score = match_bitapScore(i, j - 1); - if (score <= scoreThreshold) { - scoreThreshold = score; - bestLoc = j - 1; - locations.push(bestLoc); - if (bestLoc > MATCH_LOCATION) { - start = Math.max(1, 2 * MATCH_LOCATION - bestLoc); - } else { - break; - } - } - } - } - if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) { - break; - } - lastRd = rd; - } - return { - isMatch: bestLoc >= 0, - score: score - }; - }; - return txt === true ? { 'search' : search } : search(txt); - }; - $.vakata.search.defaults = { - location : 0, - distance : 100, - threshold : 0.6, - fuzzy : false, - caseSensitive : false - }; - }($)); - - // include the search plugin by default - // $.jstree.defaults.plugins.push("search"); - - -/** - * ### Sort plugin - * - * Automatically sorts all siblings in the tree according to a sorting function. - */ - - /** - * the settings function used to sort the nodes. - * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`. - * @name $.jstree.defaults.sort - * @plugin sort - */ - $.jstree.defaults.sort = function (a, b) { - //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b); - return this.get_text(a) > this.get_text(b) ? 1 : -1; - }; - $.jstree.plugins.sort = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - this.element - .on("model.jstree", $.proxy(function (e, data) { - this.sort(data.parent, true); - }, this)) - .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) { - this.sort(data.parent || data.node.parent, false); - this.redraw_node(data.parent || data.node.parent, true); - }, this)) - .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) { - this.sort(data.parent, false); - this.redraw_node(data.parent, true); - }, this)); - }; - /** - * used to sort a node's children - * @private - * @name sort(obj [, deep]) - * @param {mixed} obj the node - * @param {Boolean} deep if set to `true` nodes are sorted recursively. - * @plugin sort - * @trigger search.jstree - */ - this.sort = function (obj, deep) { - var i, j; - obj = this.get_node(obj); - if(obj && obj.children && obj.children.length) { - obj.children.sort($.proxy(this.settings.sort, this)); - if(deep) { - for(i = 0, j = obj.children_d.length; i < j; i++) { - this.sort(obj.children_d[i], false); - } - } - } - }; - }; - - // include the sort plugin by default - // $.jstree.defaults.plugins.push("sort"); - -/** - * ### State plugin - * - * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc) - */ - - var to = false; - /** - * stores all defaults for the state plugin - * @name $.jstree.defaults.state - * @plugin state - */ - $.jstree.defaults.state = { - /** - * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`. - * @name $.jstree.defaults.state.key - * @plugin state - */ - key : 'jstree', - /** - * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`. - * @name $.jstree.defaults.state.events - * @plugin state - */ - events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree', - /** - * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire. - * @name $.jstree.defaults.state.ttl - * @plugin state - */ - ttl : false, - /** - * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state. - * @name $.jstree.defaults.state.filter - * @plugin state - */ - filter : false, - /** - * Should loaded nodes be restored (setting this to true means that it is possible that the whole tree will be loaded for some users - use with caution). Defaults to `false` - * @name $.jstree.defaults.state.preserve_loaded - * @plugin state - */ - preserve_loaded : false - }; - $.jstree.plugins.state = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - var bind = $.proxy(function () { - this.element.on(this.settings.state.events, $.proxy(function () { - if(to) { clearTimeout(to); } - to = setTimeout($.proxy(function () { this.save_state(); }, this), 100); - }, this)); - /** - * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore). - * @event - * @name state_ready.jstree - * @plugin state - */ - this.trigger('state_ready'); - }, this); - this.element - .on("ready.jstree", $.proxy(function (e, data) { - this.element.one("restore_state.jstree", bind); - if(!this.restore_state()) { bind(); } - }, this)); - }; - /** - * save the state - * @name save_state() - * @plugin state - */ - this.save_state = function () { - var tm = this.get_state(); - if (!this.settings.state.preserve_loaded) { - delete tm.core.loaded; - } - var st = { 'state' : tm, 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) }; - $.vakata.storage.set(this.settings.state.key, JSON.stringify(st)); - }; - /** - * restore the state from the user's computer - * @name restore_state() - * @plugin state - */ - this.restore_state = function () { - var k = $.vakata.storage.get(this.settings.state.key); - if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } } - if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; } - if(!!k && k.state) { k = k.state; } - if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); } - if(!!k) { - if (!this.settings.state.preserve_loaded) { - delete k.core.loaded; - } - this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); }); - this.set_state(k); - return true; - } - return false; - }; - /** - * clear the state on the user's computer - * @name clear_state() - * @plugin state - */ - this.clear_state = function () { - return $.vakata.storage.del(this.settings.state.key); - }; - }; - - (function ($, undefined) { - $.vakata.storage = { - // simply specifying the functions in FF throws an error - set : function (key, val) { return window.localStorage.setItem(key, val); }, - get : function (key) { return window.localStorage.getItem(key); }, - del : function (key) { return window.localStorage.removeItem(key); } - }; - }($)); - - // include the state plugin by default - // $.jstree.defaults.plugins.push("state"); - -/** - * ### Types plugin - * - * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group. - */ - - /** - * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional). - * - * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited. - * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited. - * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits. - * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme. - * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data) - * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data) - * - * There are two predefined types: - * - * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes. - * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified. - * - * @name $.jstree.defaults.types - * @plugin types - */ - $.jstree.defaults.types = { - 'default' : {} - }; - $.jstree.defaults.types[$.jstree.root] = {}; - - $.jstree.plugins.types = function (options, parent) { - this.init = function (el, options) { - var i, j; - if(options && options.types && options.types['default']) { - for(i in options.types) { - if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) { - for(j in options.types['default']) { - if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) { - options.types[i][j] = options.types['default'][j]; - } - } - } - } - } - parent.init.call(this, el, options); - this._model.data[$.jstree.root].type = $.jstree.root; - }; - this.refresh = function (skip_loading, forget_state) { - parent.refresh.call(this, skip_loading, forget_state); - this._model.data[$.jstree.root].type = $.jstree.root; - }; - this.bind = function () { - this.element - .on('model.jstree', $.proxy(function (e, data) { - var m = this._model.data, - dpc = data.nodes, - t = this.settings.types, - i, j, c = 'default', k; - for(i = 0, j = dpc.length; i < j; i++) { - c = 'default'; - if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) { - c = m[dpc[i]].original.type; - } - if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) { - c = m[dpc[i]].data.jstree.type; - } - m[dpc[i]].type = c; - if(m[dpc[i]].icon === true && t[c].icon !== undefined) { - m[dpc[i]].icon = t[c].icon; - } - if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') { - for (k in t[c].li_attr) { - if (t[c].li_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (m[dpc[i]].li_attr[k] === undefined) { - m[dpc[i]].li_attr[k] = t[c].li_attr[k]; - } - else if (k === 'class') { - m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class']; - } - } - } - } - if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') { - for (k in t[c].a_attr) { - if (t[c].a_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (m[dpc[i]].a_attr[k] === undefined) { - m[dpc[i]].a_attr[k] = t[c].a_attr[k]; - } - else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') { - m[dpc[i]].a_attr['href'] = t[c].a_attr['href']; - } - else if (k === 'class') { - m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class']; - } - } - } - } - } - m[$.jstree.root].type = $.jstree.root; - }, this)); - parent.bind.call(this); - }; - this.get_json = function (obj, options, flat) { - var i, j, - m = this._model.data, - opt = options ? $.extend(true, {}, options, {no_id:false}) : {}, - tmp = parent.get_json.call(this, obj, opt, flat); - if(tmp === false) { return false; } - if($.isArray(tmp)) { - for(i = 0, j = tmp.length; i < j; i++) { - tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default"; - if(options && options.no_id) { - delete tmp[i].id; - if(tmp[i].li_attr && tmp[i].li_attr.id) { - delete tmp[i].li_attr.id; - } - if(tmp[i].a_attr && tmp[i].a_attr.id) { - delete tmp[i].a_attr.id; - } - } - } - } - else { - tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default"; - if(options && options.no_id) { - tmp = this._delete_ids(tmp); - } - } - return tmp; - }; - this._delete_ids = function (tmp) { - if($.isArray(tmp)) { - for(var i = 0, j = tmp.length; i < j; i++) { - tmp[i] = this._delete_ids(tmp[i]); - } - return tmp; - } - delete tmp.id; - if(tmp.li_attr && tmp.li_attr.id) { - delete tmp.li_attr.id; - } - if(tmp.a_attr && tmp.a_attr.id) { - delete tmp.a_attr.id; - } - if(tmp.children && $.isArray(tmp.children)) { - tmp.children = this._delete_ids(tmp.children); - } - return tmp; - }; - this.check = function (chk, obj, par, pos, more) { - if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } - obj = obj && obj.id ? obj : this.get_node(obj); - par = par && par.id ? par : this.get_node(par); - var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j; - m = m && m._model && m._model.data ? m._model.data : null; - switch(chk) { - case "create_node": - case "move_node": - case "copy_node": - if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) { - tmp = this.get_rules(par); - if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - return false; - } - if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - return false; - } - if(m && obj.children_d && obj.parents) { - d = 0; - for(i = 0, j = obj.children_d.length; i < j; i++) { - d = Math.max(d, m[obj.children_d[i]].parents.length); - } - d = d - obj.parents.length + 1; - } - if(d <= 0 || d === undefined) { d = 1; } - do { - if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - return false; - } - par = this.get_node(par.parent); - tmp = this.get_rules(par); - d++; - } while(par); - } - break; - } - return true; - }; - /** - * used to retrieve the type settings object for a node - * @name get_rules(obj) - * @param {mixed} obj the node to find the rules for - * @return {Object} - * @plugin types - */ - this.get_rules = function (obj) { - obj = this.get_node(obj); - if(!obj) { return false; } - var tmp = this.get_type(obj, true); - if(tmp.max_depth === undefined) { tmp.max_depth = -1; } - if(tmp.max_children === undefined) { tmp.max_children = -1; } - if(tmp.valid_children === undefined) { tmp.valid_children = -1; } - return tmp; - }; - /** - * used to retrieve the type string or settings object for a node - * @name get_type(obj [, rules]) - * @param {mixed} obj the node to find the rules for - * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned - * @return {String|Object} - * @plugin types - */ - this.get_type = function (obj, rules) { - obj = this.get_node(obj); - return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type); - }; - /** - * used to change a node's type - * @name set_type(obj, type) - * @param {mixed} obj the node to change - * @param {String} type the new type - * @plugin types - */ - this.set_type = function (obj, type) { - var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a; - if($.isArray(obj)) { - obj = obj.slice(); - for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { - this.set_type(obj[t1], type); - } - return true; - } - t = this.settings.types; - obj = this.get_node(obj); - if(!t[type] || !obj) { return false; } - d = this.get_node(obj, true); - if (d && d.length) { - a = d.children('.jstree-anchor'); - } - old_type = obj.type; - old_icon = this.get_icon(obj); - obj.type = type; - if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) { - this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true); - } - - // remove old type props - if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') { - for (k in t[old_type].li_attr) { - if (t[old_type].li_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (k === 'class') { - m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], ''); - if (d) { d.removeClass(t[old_type].li_attr[k]); } - } - else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) { - m[obj.id].li_attr[k] = null; - if (d) { d.removeAttr(k); } - } - } - } - } - if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') { - for (k in t[old_type].a_attr) { - if (t[old_type].a_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (k === 'class') { - m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], ''); - if (a) { a.removeClass(t[old_type].a_attr[k]); } - } - else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) { - if (k === 'href') { - m[obj.id].a_attr[k] = '#'; - if (a) { a.attr('href', '#'); } - } - else { - delete m[obj.id].a_attr[k]; - if (a) { a.removeAttr(k); } - } - } - } - } - } - - // add new props - if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') { - for (k in t[type].li_attr) { - if (t[type].li_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (m[obj.id].li_attr[k] === undefined) { - m[obj.id].li_attr[k] = t[type].li_attr[k]; - if (d) { - if (k === 'class') { - d.addClass(t[type].li_attr[k]); - } - else { - d.attr(k, t[type].li_attr[k]); - } - } - } - else if (k === 'class') { - m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class']; - if (d) { d.addClass(t[type].li_attr[k]); } - } - } - } - } - if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') { - for (k in t[type].a_attr) { - if (t[type].a_attr.hasOwnProperty(k)) { - if (k === 'id') { - continue; - } - else if (m[obj.id].a_attr[k] === undefined) { - m[obj.id].a_attr[k] = t[type].a_attr[k]; - if (a) { - if (k === 'class') { - a.addClass(t[type].a_attr[k]); - } - else { - a.attr(k, t[type].a_attr[k]); - } - } - } - else if (k === 'href' && m[obj.id].a_attr[k] === '#') { - m[obj.id].a_attr['href'] = t[type].a_attr['href']; - if (a) { a.attr('href', t[type].a_attr['href']); } - } - else if (k === 'class') { - m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class']; - if (a) { a.addClass(t[type].a_attr[k]); } - } - } - } - } - - return true; - }; - }; - // include the types plugin by default - // $.jstree.defaults.plugins.push("types"); - - -/** - * ### Unique plugin - * - * Enforces that no nodes with the same name can coexist as siblings. - */ - - /** - * stores all defaults for the unique plugin - * @name $.jstree.defaults.unique - * @plugin unique - */ - $.jstree.defaults.unique = { - /** - * Indicates if the comparison should be case sensitive. Default is `false`. - * @name $.jstree.defaults.unique.case_sensitive - * @plugin unique - */ - case_sensitive : false, - /** - * Indicates if white space should be trimmed before the comparison. Default is `false`. - * @name $.jstree.defaults.unique.trim_whitespace - * @plugin unique - */ - trim_whitespace : false, - /** - * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`. - * @name $.jstree.defaults.unique.duplicate - * @plugin unique - */ - duplicate : function (name, counter) { - return name + ' (' + counter + ')'; - } - }; - - $.jstree.plugins.unique = function (options, parent) { - this.check = function (chk, obj, par, pos, more) { - if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } - obj = obj && obj.id ? obj : this.get_node(obj); - par = par && par.id ? par : this.get_node(par); - if(!par || !par.children) { return true; } - var n = chk === "rename_node" ? pos : obj.text, - c = [], - s = this.settings.unique.case_sensitive, - w = this.settings.unique.trim_whitespace, - m = this._model.data, i, j, t; - for(i = 0, j = par.children.length; i < j; i++) { - t = m[par.children[i]].text; - if (!s) { - t = t.toLowerCase(); - } - if (w) { - t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - } - c.push(t); - } - if(!s) { n = n.toLowerCase(); } - if (w) { n = n.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } - switch(chk) { - case "delete_node": - return true; - case "rename_node": - t = obj.text || ''; - if (!s) { - t = t.toLowerCase(); - } - if (w) { - t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - } - i = ($.inArray(n, c) === -1 || (obj.text && t === n)); - if(!i) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - } - return i; - case "create_node": - i = ($.inArray(n, c) === -1); - if(!i) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - } - return i; - case "copy_node": - i = ($.inArray(n, c) === -1); - if(!i) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - } - return i; - case "move_node": - i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1); - if(!i) { - this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; - } - return i; - } - return true; - }; - this.create_node = function (par, node, pos, callback, is_loaded) { - if(!node || node.text === undefined) { - if(par === null) { - par = $.jstree.root; - } - par = this.get_node(par); - if(!par) { - return parent.create_node.call(this, par, node, pos, callback, is_loaded); - } - pos = pos === undefined ? "last" : pos; - if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { - return parent.create_node.call(this, par, node, pos, callback, is_loaded); - } - if(!node) { node = {}; } - var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, w = this.settings.unique.trim_whitespace, cb = this.settings.unique.duplicate, t; - n = tmp = this.get_string('New node'); - dpc = []; - for(i = 0, j = par.children.length; i < j; i++) { - t = m[par.children[i]].text; - if (!s) { - t = t.toLowerCase(); - } - if (w) { - t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - } - dpc.push(t); - } - i = 1; - t = n; - if (!s) { - t = t.toLowerCase(); - } - if (w) { - t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - } - while($.inArray(t, dpc) !== -1) { - n = cb.call(this, tmp, (++i)).toString(); - t = n; - if (!s) { - t = t.toLowerCase(); - } - if (w) { - t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); - } - } - node.text = n; - } - return parent.create_node.call(this, par, node, pos, callback, is_loaded); - }; - }; - - // include the unique plugin by default - // $.jstree.defaults.plugins.push("unique"); - - -/** - * ### Wholerow plugin - * - * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers. - */ - - var div = document.createElement('DIV'); - div.setAttribute('unselectable','on'); - div.setAttribute('role','presentation'); - div.className = 'jstree-wholerow'; - div.innerHTML = ' '; - $.jstree.plugins.wholerow = function (options, parent) { - this.bind = function () { - parent.bind.call(this); - - this.element - .on('ready.jstree set_state.jstree', $.proxy(function () { - this.hide_dots(); - }, this)) - .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { - //div.style.height = this._data.core.li_height + 'px'; - this.get_container_ul().addClass('jstree-wholerow-ul'); - }, this)) - .on("deselect_all.jstree", $.proxy(function (e, data) { - this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); - }, this)) - .on("changed.jstree", $.proxy(function (e, data) { - this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); - var tmp = false, i, j; - for(i = 0, j = data.selected.length; i < j; i++) { - tmp = this.get_node(data.selected[i], true); - if(tmp && tmp.length) { - tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); - } - } - }, this)) - .on("open_node.jstree", $.proxy(function (e, data) { - this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); - }, this)) - .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) { - if(e.type === "hover_node" && this.is_disabled(data.node)) { return; } - this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered'); - }, this)) - .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) { - if (this._data.contextmenu) { - e.preventDefault(); - var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY }); - $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp); - } - }, this)) - /*! - .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) { - if(e.target === e.currentTarget) { - var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor"); - e.target = a[0]; - a.trigger(e); - } - }) - */ - .on("click.jstree", ".jstree-wholerow", function (e) { - e.stopImmediatePropagation(); - var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); - $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); - }) - .on("dblclick.jstree", ".jstree-wholerow", function (e) { - e.stopImmediatePropagation(); - var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); - $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); - }) - .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) { - e.stopImmediatePropagation(); - var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); - $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); - }, this)) - .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) { - e.stopImmediatePropagation(); - if(!this.is_disabled(e.currentTarget)) { - this.hover_node(e.currentTarget); - } - return false; - }, this)) - .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) { - this.dehover_node(e.currentTarget); - }, this)); - }; - this.teardown = function () { - if(this.settings.wholerow) { - this.element.find(".jstree-wholerow").remove(); - } - parent.teardown.call(this); - }; - this.redraw_node = function(obj, deep, callback, force_render) { - obj = parent.redraw_node.apply(this, arguments); - if(obj) { - var tmp = div.cloneNode(true); - //tmp.style.height = this._data.core.li_height + 'px'; - if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; } - if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; } - obj.insertBefore(tmp, obj.childNodes[0]); - } - return obj; - }; - }; - // include the wholerow plugin by default - // $.jstree.defaults.plugins.push("wholerow"); - if(window.customElements && Object && Object.create) { - var proto = Object.create(HTMLElement.prototype); - proto.createdCallback = function () { - var c = { core : {}, plugins : [] }, i; - for(i in $.jstree.plugins) { - if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) { - c.plugins.push(i); - if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) { - c[i] = JSON.parse(this.getAttribute(i)); - } - } - } - for(i in $.jstree.defaults.core) { - if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) { - c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i); - } - } - $(this).jstree(c); - }; - // proto.attributeChangedCallback = function (name, previous, value) { }; - try { - window.customElements.define("vakata-jstree", function() {}, { prototype: proto }); - } catch (ignore) { } - } - -})); \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/jstree.min.js b/src/main/webapp/resources/3rd-party/jstree/jstree.min.js deleted file mode 100644 index 9221c338..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/jstree.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! jsTree - v3.3.7 - 2018-11-06 - (MIT) */ -!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a,b){"use strict";if(!a.jstree){var c=0,d=!1,e=!1,f=!1,g=[],h=a("script:last").attr("src"),i=window.document;a.jstree={version:"3.3.7",defaults:{plugins:[]},plugins:{},path:h&&-1!==h.indexOf("/")?h.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0,loaded_state:!1,restore_focus:!0,keyboard:{"ctrl-space":function(b){b.type="click",a(b.currentTarget).trigger(b)},enter:function(b){b.type="click",a(b.currentTarget).trigger(b)},left:function(b){if(b.preventDefault(),this.is_open(b.currentTarget))this.close_node(b.currentTarget);else{var c=this.get_parent(b.currentTarget);c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus()}},up:function(a){a.preventDefault();var b=this.get_prev_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},right:function(b){if(b.preventDefault(),this.is_closed(b.currentTarget))this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()});else if(this.is_open(b.currentTarget)){var c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0];c&&a(this._firstChild(c)).children(".jstree-anchor").focus()}},down:function(a){a.preventDefault();var b=this.get_next_dom(a.currentTarget);b&&b.length&&b.children(".jstree-anchor").focus()},"*":function(a){this.open_all()},home:function(b){b.preventDefault();var c=this._firstChild(this.get_container_ul()[0]);c&&a(c).children(".jstree-anchor").filter(":visible").focus()},end:function(a){a.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus()},f2:function(a){a.preventDefault(),this.edit(a.currentTarget)}}},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().outerHeight()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this.trigger("destroy"),this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},_create_prototype_node:function(){var a=i.createElement("LI"),b,c;return a.setAttribute("role","treeitem"),b=i.createElement("I"),b.className="jstree-icon jstree-ocl",b.setAttribute("role","presentation"),a.appendChild(b),b=i.createElement("A"),b.className="jstree-anchor",b.setAttribute("href","#"),b.setAttribute("tabindex","-1"),c=i.createElement("I"),c.className="jstree-icon jstree-themeicon",c.setAttribute("role","presentation"),b.appendChild(c),a.appendChild(b),b=c=null,a},_kbevent_to_func:function(a){var b={8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock",16:"Shift",17:"Ctrl",18:"Alt",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*",173:"-"},c=[];a.ctrlKey&&c.push("ctrl"),a.altKey&&c.push("alt"),a.shiftKey&&c.push("shift"),c.push(b[a.which]||a.which),c=c.sort().join("-").toLowerCase();var d=this.settings.core.keyboard,e,f;for(e in d)if(d.hasOwnProperty(e)&&(f=e,"-"!==f&&"+"!==f&&(f=f.replace("--","-MINUS").replace("+-","-MINUS").replace("++","-PLUS").replace("-+","-PLUS"),f=f.split(/-|\+/).sort().join("-").replace("MINUS","-").replace("PLUS","+").toLowerCase()),f===c))return d[e];return null},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;this._data.core.rtl&&(37===a.which?a.which=39:39===a.which&&(a.which=37));var b=this._kbevent_to_func(a);if(b){var c=b.call(this,a);if(c===!1||c===!0)return c}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this._data.core.themes.ellipsis=a.ellipsis,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"](),this[this._data.core.themes.ellipsis?"show_ellipsis":"hide_ellipsis"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").mouseleave(),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).mouseleave(),a(b.currentTarget).mouseenter(),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused&&this.settings.core.restore_focus){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id),b instanceof jQuery&&b.length&&b[0].id&&(b=b[0].id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=this.element.find(b)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=this.element.find(b)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},c.call(this,!1),this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)?a.extend(!0,[],d):a.isPlainObject(d)?a.extend(!0,{},d):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(b){b=this.get_node(b),b&&-1===a.inArray(b.id,this._model.changed)&&this._model.changed.push(b.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],h=a.df,i=a.t_id,j=a.t_cnt,k=a.m,l=k[d],m=a.sel,n,o,p,q,r=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,i,j,l,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(m.state[f]=h[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),k[m.id]=m,f=0,i=m.children.length;i>f;f++)j=r(k[m.children[f]],m.id,d),l=k[j],m.children_d.push(j),l.children_d.length&&(m.children_d=m.children_d.concat(l.children_d));return delete a.data,delete a.children,k[m.id].original=a,m.state.selected&&g.push(m.id),m.id},s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,l,m,n,o;do e="j"+i+"_"+ ++j;while(k[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(o.state[f]=h[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,l=a.children.length;l>f;f++)m=s(a.children[f],o.id,d),n=k[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,k[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(o=0,p=c.length;p>o;o++)c[o].children||(c[o].children=[]),c[o].state||(c[o].state={}),k[c[o].id.toString()]=c[o];for(o=0,p=c.length;p>o;o++)k[c[o].parent.toString()]?(k[c[o].parent.toString()].children.push(c[o].id.toString()),l.children_d.push(c[o].id.toString())):(this._data.core.last_error={error:"parse",plugin:"core",id:"core_07",reason:"Node with invalid parent",data:JSON.stringify({id:c[o].id.toString(),parent:c[o].parent.toString()})},this.settings.core.error.call(this,this._data.core.last_error));for(o=0,p=l.children.length;p>o;o++)n=r(k[l.children[o]],d,l.parents.concat()),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d));for(o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}else{for(o=0,p=c.length;p>o;o++)n=s(c[o],d,l.parents.concat()),n&&(e.push(n),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d)));for(l.children=e,l.children_d=f,o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?q:void postMessage(q)},i=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,h=b.add,i=b.sel,j=this._data.core.selected.slice();if(f=this._model.data,i.length!==j.length||a.vakata.array_unique(i.concat(j)).length!==i.length){for(e=0,g=i.length;g>e;e++)-1===a.inArray(i[e],h)&&-1===a.inArray(i[e],j)&&(f[i[e]].state.selected=!1);for(e=0,g=j.length;g>e;e++)-1===a.inArray(j[e],i)&&(f[j[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+h.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){i.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(j){i.call(this,h(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else i.call(this,h(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("
      ").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()), -l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children_d.concat(l.children)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&this.settings.core.restore_focus&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n="",o=i,p=this._model.data,q=!1,r=!1,s=null,t=0,u=0,v=!1,w=!1;if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(j=b.children(".jstree-children")[0]),q=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&p[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?p[a.jstree.root].children:p[f.parent].children)}b=this._data.core.node.cloneNode(!0),n="jstree-node ";for(k in f.li_attr)if(f.li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"!==k?b.setAttribute(k,f.li_attr[k]):n+=f.li_attr[k]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&b.setAttribute("aria-disabled",!0),k=0,l=f.children.length;l>k;k++)if(!p[f.children[k]].state.hidden){v=!0;break}if(null!==f.parent&&p[f.parent]&&!f.state.hidden&&(k=a.inArray(f.id,p[f.parent].children),w=f.id,-1!==k))for(k++,l=p[f.parent].children.length;l>k;k++)if(p[p[f.parent].children[k]].state.hidden||(w=p[f.parent].children[k]),w!==f.id)break;f.state.hidden&&(n+=" jstree-hidden"),f.state.loading&&(n+=" jstree-loading"),f.state.loaded&&!v?n+=" jstree-leaf":(n+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),w===f.id&&(n+=" jstree-last"),b.id=f.id,b.className=n,n=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(l in f.a_attr)if(f.a_attr.hasOwnProperty(l)){if("href"===l&&"#"===f.a_attr[l])continue;"class"!==l?b.childNodes[1].setAttribute(l,f.a_attr[l]):n+=" "+f.a_attr[l]}if(n.length&&(b.childNodes[1].className="jstree-anchor "+n),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(o.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(m=o.createElement("UL"),m.setAttribute("role","group"),m.className="jstree-children",k=0,l=f.children.length;l>k;k++)m.appendChild(this.redraw_node(f.children[k],c,!0));b.appendChild(m)}if(j&&b.appendChild(j),!d){for(g||(g=this.element[0]),k=0,l=g.childNodes.length;l>k;k++)if(g.childNodes[k]&&g.childNodes[k].className&&-1!==g.childNodes[k].className.indexOf("jstree-children")){s=g.childNodes[k];break}s||(s=o.createElement("UL"),s.setAttribute("role","group"),s.className="jstree-children",g.appendChild(s)),g=s,hf;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked"),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked"),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],loaded:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.loaded&&this.settings.core.loaded_state&&b.core.loaded.push(c),this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core&&c.core.selected&&c.core.initial_selection===b&&(c.core.initial_selection=this._data.core.selected.concat([]).sort().join(",")),c.core){var e,f,g,h,i;if(c.core.loaded)return this.settings.core.loaded_state&&a.isArray(c.core.loaded)&&c.core.loaded.length?this._load_nodes(c.core.loaded,function(a){delete c.core.loaded,this.set_state(c,d)}):(delete c.core.loaded,this.set_state(c,d)),!1;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,(c.core.initial_selection===b||c.core.initial_selection===this._data.core.selected.concat([]).sort().join(","))&&(this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)})),delete c.core.initial_selection,delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,a.isArray(b.data)?[]:{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),d="string"==typeof d?{text:d}:a.extend(!0,{},d),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),f&&f.call(this,this.get_node(d)),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;return"move_node"!==b&&"copy_node"!==b||f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)?(g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0):(this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1)},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()),!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g); -return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.check("edit",b,this.get_parent(b))?(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a(""),j=c,k=a("
      ",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo(i.body),l=a("",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("
      ").append(a.parseHTML(j)).html(),b=this.get_node(b),this.set_text(b,j),m=!!this.rename_node(b,i?a("
      ").text(f).text():a("
      ").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"",fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):(this.settings.core.error.call(this,this._data.core.last_error),!1):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append(''),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),this.hide_icon(c)):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var j=i.createElement("I");j.className="jstree-icon jstree-checkbox",j.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0,cascade_to_disabled:!0,cascade_to_hidden:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=this,e=c.node,f=this._model.data,g=this.get_node(e.parent),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down")){var p=this._cascade_new_checked_state(e.id,!0),q=e.children_d.concat(e.id);for(h=0,i=q.length;i>h;h++)p.indexOf(q[h])>-1?n[q[h]]=!0:delete n[q[h]]}if(-1!==l.indexOf("up"))while(g&&g.id!==a.jstree.root){for(j=0,h=0,i=g.children.length;i>h;h++)j+=f[g.children[h]].state[m?"selected":"checked"];if(j!==i)break;g.state[m?"selected":"checked"]=!0,n[g.id]=!0,k=this.get_node(g,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),g=this.get_node(g.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(a,b){var c=this,d=b.node,e=this.get_node(d,!0),f,g,h,i=this.settings.checkbox.cascade,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l={},m=[],n=d.children_d.concat(d.id);if(-1!==i.indexOf("down")){var o=this._cascade_new_checked_state(d.id,!1);k=k.filter(function(a){return-1===n.indexOf(a)||o.indexOf(a)>-1})}if(-1!==i.indexOf("up")&&-1===k.indexOf(d.id)){for(f=0,g=d.parents.length;g>f;f++)h=this._model.data[d.parents[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1),h=this.get_node(d.parents[f],!0),h&&h.length&&h.attr("aria-selected",!1).children(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked");k=k.filter(function(a){return-1===d.parents.indexOf(a)})}this._data[j?"core":"checkbox"].selected=k},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this.get_undetermined=function(c){if(-1===this.settings.checkbox.cascade.indexOf("undetermined"))return[];var d,e,f,g,h={},i=this._model.data,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l=[],m=this,n=[];for(d=0,e=k.length;e>d;d++)if(i[k[d]]&&i[k[d]].parents)for(f=0,g=i[k[d]].parents.length;g>f;f++){if(h[i[k[d]].parents[f]]!==b)break;i[k[d]].parents[f]!==a.jstree.root&&(h[i[k[d]].parents[f]]=!0,l.push(i[k[d]].parents[f]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var c=m.get_node(this),j;if(c)if(c.state.loaded){for(d=0,e=c.children_d.length;e>d;d++)if(j=i[c.children_d[d]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(h[j.id]===b&&j.id!==a.jstree.root&&(h[j.id]=!0,l.push(j.id)),f=0,g=j.parents.length;g>f;f++)h[j.parents[f]]===b&&j.parents[f]!==a.jstree.root&&(h[j.parents[f]]=!0,l.push(j.parents[f]))}else if(c.original&&c.original.state&&c.original.state.undetermined&&c.original.state.undetermined===!0)for(h[c.id]===b&&c.id!==a.jstree.root&&(h[c.id]=!0,l.push(c.id)),f=0,g=c.parents.length;g>f;f++)h[c.parents[f]]===b&&c.parents[f]!==a.jstree.root&&(h[c.parents[f]]=!0,l.push(c.parents[f]))}),d=0,e=l.length;e>d;d++)i[l[d]].state[j?"selected":"checked"]||n.push(c?i[l[d]]:l[d]);return n},this._undetermined=function(){if(null!==this.element){var a=this.get_undetermined(!1),b,c,d;for(this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),b=0,c=a.length;c>b;b++)d=this.get_node(a[b],!0),d&&d.length&&d.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined")}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,k=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),k=j.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(k.className+=" jstree-checkbox-disabled"),i.insertBefore(k,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this._cascade_new_checked_state=function(a,b){var c=this,d=this.settings.checkbox.tie_selection,e=this._model.data[a],f=[],g=[],h,i,j;if(!this.settings.checkbox.cascade_to_disabled&&e.state.disabled||!this.settings.checkbox.cascade_to_hidden&&e.state.hidden)j=this.get_checked_descendants(a),e.state[d?"selected":"checked"]&&j.push(e.id),f=f.concat(j);else{if(e.children)for(h=0,i=e.children.length;i>h;h++){var k=e.children[h];j=c._cascade_new_checked_state(k,b),f=f.concat(j),j.indexOf(k)>-1&&g.push(k)}var l=c.get_node(e,!0),m=g.length>0&&g.lengthe;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection&&(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){return this.settings.conditionalselect.call(this,this.get_node(a),c)?b.activate_node.call(this,a,c):void 0}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){try{c.edit(a)}catch(b){setTimeout(function(){c.edit(a)},0)}})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-contextmenu")},this)).on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(b){c&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(Math.abs(e-b.originalEvent.changedTouches[0].clientX)>10||Math.abs(f-b.originalEvent.changedTouches[0].clientY)>10)&&(clearTimeout(c),a.vakata.context.hide())}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+=""),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,j,k,l,m,n,o,p=!0;switch(c.element&&c.element.length&&c.element.width(""),p){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo(i.body),h=c.element,j=c.position_x,k=c.position_y,l=h.width(),m=h.height(),n=a(window).width()+a(window).scrollLeft(),o=a(window).height()+a(window).scrollTop(),b&&(j-=h.outerWidth()-a(d).outerWidth(),jn&&(j=n-(l+20)),k+m+20>o&&(k=o-(m+20)),c.element.css({left:j,top:k}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a(i.body).css("direction");var d=!1;c.element=a("
        "),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="click",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&c.element[0]!==b.target&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var k,l;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(k={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},l=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,k,'
        '+e+'
        ');a.vakata.dnd._trigger("start",b,{helper:a(),element:l,data:k})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:l,data:k}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:l,data:k}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('
         
        ').hide();a(i).on("dragover.vakata.jstree",function(b){l&&a.vakata.dnd._trigger("move",b,{helper:a(),element:l,data:k})}).on("drop.vakata.jstree",function(b){l&&(a.vakata.dnd._trigger("stop",b,{helper:a(),element:l,data:k}),l=null,k=null)}).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo(i.body)}).on("dnd_move.vakata.jstree",function(h,i){var j=i.event.target!==e.target;if(f&&(!i.event||"dragover"!==i.event.type||j)&&clearTimeout(f),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var k=a.jstree.reference(i.event.target),l=!1,m=!1,n=!1,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E;if(k&&k._data&&k._data.dnd)if(g.attr("class","jstree-"+k.get_theme()+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")),D=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+k.get_theme()+" jstree-"+k.get_theme()+"-"+k.get_theme_variant()+" "+(k.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[D?"show":"hide"](),i.event.target!==k.element[0]&&i.event.target!==k.get_container_ul()[0]||0!==k.get_container_ul().children().length){if(l=k.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),l&&l.length&&l.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(m=l.offset(),n=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-m.top,r=l.outerHeight(),u=r/3>n?["b","i","a"]:n>r-r/3?["a","i","b"]:n>r/2?["i","a","b"]:["i","b","a"],a.each(u,function(b,e){switch(e){case"b":p=m.left-6,q=m.top,s=k.get_parent(l),t=l.parent().index();break;case"i":B=k.settings.dnd.inside_pos,C=k.get_node(l.parent()),p=m.left-2,q=m.top+r/2+1,s=C.id,t="first"===B?0:"last"===B?C.children.length:Math.min(B,C.children.length);break;case"a":p=m.left-6,q=m.top+r,s=k.get_parent(l),t=l.parent().index()+1}for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(y=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",z=t,"move_node"===y&&"a"===e&&i.data.origin&&i.data.origin===k&&s===k.get_parent(i.data.nodes[w])&&(A=k.get_node(s),z>a.inArray(i.data.nodes[w],A.children)&&(z-=1)),v=v&&(k&&k.settings&&k.settings.dnd&&k.settings.dnd.check_while_dragging===!1||k.check(y,i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],s,z,{dnd:!0,ref:k.get_node(l.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin})),!v){k&&k.last_error&&(d=k.last_error());break}return"i"===e&&l.parent().is(".jstree-closed")&&k.settings.dnd.open_timeout&&(!i.event||"dragover"!==i.event.type||j)&&(f&&clearTimeout(f),f=setTimeout(function(a,b){return function(){a.open_node(b)}}(k,l),k.settings.dnd.open_timeout)),v?(E=k.get_node(s,!0),E.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),E.addClass("jstree-dnd-parent")),c={ins:k,par:s,pos:"i"!==e||"last"!==B||0!==t||k.is_loaded(C)?t:"last"},g.css({left:p+"px",top:q+"px"}).show(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"),d={},u=!0,!1):void 0}),u===!0))return}else{for(v=!0,w=0,x=i.data.nodes.length;x>w;w++)if(v=v&&k.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==k?i.data.origin.get_node(i.data.nodes[w]):i.data.nodes[w],a.jstree.root,"last",{dnd:!0,ref:k.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==k,is_foreign:!i.data.origin}),!v)break;if(v)return c={ins:k,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=D?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer,g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("
        "),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:10},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("
        ").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo(i.body),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageYthis.offsetWidth&&(e.left+d.width()-b.pageXg&&b.pageY-kg&&g-(b.pageY-k)j&&b.pageX-lj&&j-(b.pageX-l)f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=JSON.stringify(b),i=[],j=this._model.data,k,l,m;if(!e){for(k=0,l=b.length;l>k;k++)(!j[b[k]]||!j[b[k]].state.loaded&&!j[b[k]].state.failed||f)&&(i.push(b[k]),m=this.get_node(b[k],!0),m&&m.length&&m.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},i.length){if(a.isFunction(g))return g.call(this,i,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)m=this.get_node(b[g],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,i)),a.isFunction(g.data)&&(g.data=g.data.call(this,i)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)m=this.get_node(b[i],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),this._data.search.lastRequest&&this._data.search.lastRequest.abort(),this._data.search.lastRequest=a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this)),this._data.search.lastRequest);if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var m=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1,preserve_loaded:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){m&&clearTimeout(m),m=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b=this.get_state();this.settings.state.preserve_loaded||delete b.core.loaded;var c={state:b,ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(c))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.settings.state.preserve_loaded||delete b.core.loaded,this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type),e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id, -b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depthg;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||!f[i]||f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i]&&f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i]&&f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,trim_whitespace:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1;if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this.settings.unique.trim_whitespace,l=this._model.data,m,n,o;for(m=0,n=e.children.length;n>m;m++)o=l[e.children[m]].text,j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),i.push(o);switch(j||(h=h.toLowerCase()),k&&(h=h.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),b){case"delete_node":return!0;case"rename_node":return o=c.text||"",j||(o=o.toLowerCase()),k&&(o=o.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),m=-1===a.inArray(h,i)||c.text&&o===h,m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"create_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"copy_node":return m=-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m;case"move_node":return m=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),m||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),m}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.trim_whitespace,q=this.settings.unique.duplicate,r;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)r=n[c.children[l]].text,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")),k.push(r);l=1,r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));while(-1!==a.inArray(r,k))j=q.call(this,i,++l).toString(),r=j,o||(r=r.toLowerCase()),p&&(r=r.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""));e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var n=i.createElement("DIV");if(n.setAttribute("unselectable","on"),n.setAttribute("role","presentation"),n.className="jstree-wholerow",n.innerHTML=" ",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("dblclick.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("dblclick",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=n.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},window.customElements&&Object&&Object.create){var o=Object.create(HTMLElement.prototype);o.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{window.customElements.define("vakata-jstree",function(){},{prototype:o})}catch(p){}}}}); \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/32px.png b/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/32px.png deleted file mode 100644 index 60395729ef6cfda914b211d5a45c9d2c083b3175..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1525 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 C_#XrS diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.css b/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.css deleted file mode 100644 index d8dc188f..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.css +++ /dev/null @@ -1,1146 +0,0 @@ -/* jsTree default dark theme */ -.jstree-node, -.jstree-children, -.jstree-container-ul { - display: block; - margin: 0; - padding: 0; - list-style-type: none; - list-style-image: none; -} -.jstree-node { - white-space: nowrap; -} -.jstree-anchor { - display: inline-block; - color: black; - white-space: nowrap; - padding: 0 4px 0 1px; - margin: 0; - vertical-align: top; -} -.jstree-anchor:focus { - outline: 0; -} -.jstree-anchor, -.jstree-anchor:link, -.jstree-anchor:visited, -.jstree-anchor:hover, -.jstree-anchor:active { - text-decoration: none; - color: inherit; -} -.jstree-icon { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-icon:empty { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-ocl { - cursor: pointer; -} -.jstree-leaf > .jstree-ocl { - cursor: default; -} -.jstree .jstree-open > .jstree-children { - display: block; -} -.jstree .jstree-closed > .jstree-children, -.jstree .jstree-leaf > .jstree-children { - display: none; -} -.jstree-anchor > .jstree-themeicon { - margin-right: 2px; -} -.jstree-no-icons .jstree-themeicon, -.jstree-anchor > .jstree-themeicon-hidden { - display: none; -} -.jstree-hidden, -.jstree-node.jstree-hidden { - display: none; -} -.jstree-rtl .jstree-anchor { - padding: 0 1px 0 4px; -} -.jstree-rtl .jstree-anchor > .jstree-themeicon { - margin-left: 2px; - margin-right: 0; -} -.jstree-rtl .jstree-node { - margin-left: 0; -} -.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; -} -.jstree-wholerow-ul { - position: relative; - display: inline-block; - min-width: 100%; -} -.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { - cursor: pointer; -} -.jstree-wholerow-ul .jstree-anchor, -.jstree-wholerow-ul .jstree-icon { - position: relative; -} -.jstree-wholerow-ul .jstree-wholerow { - width: 100%; - cursor: pointer; - position: absolute; - left: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.jstree-contextmenu .jstree-anchor { - -webkit-user-select: none; - /* disable selection/Copy of UIWebView */ - -webkit-touch-callout: none; - /* disable the IOS popup when long-press on a link */ -} -.vakata-context { - display: none; -} -.vakata-context, -.vakata-context ul { - margin: 0; - padding: 2px; - position: absolute; - background: #f5f5f5; - border: 1px solid #979797; - box-shadow: 2px 2px 2px #999999; -} -.vakata-context ul { - list-style: none; - left: 100%; - margin-top: -2.7em; - margin-left: -4px; -} -.vakata-context .vakata-context-right ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context li { - list-style: none; -} -.vakata-context li > a { - display: block; - padding: 0 2em 0 2em; - text-decoration: none; - width: auto; - color: black; - white-space: nowrap; - line-height: 2.4em; - text-shadow: 1px 1px 0 white; - border-radius: 1px; -} -.vakata-context li > a:hover { - position: relative; - background-color: #e8eff7; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); - background-position: right center; - background-repeat: no-repeat; -} -.vakata-context li > a:focus { - outline: 0; -} -.vakata-context .vakata-context-hover > a { - position: relative; - background-color: #e8eff7; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context .vakata-context-separator > a, -.vakata-context .vakata-context-separator > a:hover { - background: white; - border: 0; - border-top: 1px solid #e2e3e3; - height: 1px; - min-height: 1px; - max-height: 1px; - padding: 0; - margin: 0 0 0 2.4em; - border-left: 1px solid #e0e0e0; - text-shadow: 0 0 0 transparent; - box-shadow: 0 0 0 transparent; - border-radius: 0; -} -.vakata-context .vakata-contextmenu-disabled a, -.vakata-context .vakata-contextmenu-disabled a:hover { - color: silver; - background-color: transparent; - border: 0; - box-shadow: 0 0 0; -} -.vakata-context .vakata-contextmenu-disabled > a > i { - filter: grayscale(100%); -} -.vakata-context li > a > i { - text-decoration: none; - display: inline-block; - width: 2.4em; - height: 2.4em; - background: transparent; - margin: 0 0 0 -2em; - vertical-align: top; - text-align: center; - line-height: 2.4em; -} -.vakata-context li > a > i:empty { - width: 2.4em; - line-height: 2.4em; -} -.vakata-context li > a .vakata-contextmenu-sep { - display: inline-block; - width: 1px; - height: 2.4em; - background: white; - margin: 0 0.5em 0 0; - border-left: 1px solid #e2e3e3; -} -.vakata-context .vakata-contextmenu-shortcut { - font-size: 0.8em; - color: silver; - opacity: 0.5; - display: none; -} -.vakata-context-rtl ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context-rtl li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); - background-position: left center; - background-repeat: no-repeat; -} -.vakata-context-rtl .vakata-context-separator > a { - margin: 0 2.4em 0 0; - border-left: 0; - border-right: 1px solid #e2e3e3; -} -.vakata-context-rtl .vakata-context-left ul { - right: auto; - left: 100%; - margin-left: -4px; - margin-right: auto; -} -.vakata-context-rtl li > a > i { - margin: 0 -2em 0 0; -} -.vakata-context-rtl li > a .vakata-contextmenu-sep { - margin: 0 0 0 0.5em; - border-left-color: white; - background: #e2e3e3; -} -#jstree-marker { - position: absolute; - top: 0; - left: 0; - margin: -5px 0 0 0; - padding: 0; - border-right: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid; - width: 0; - height: 0; - font-size: 0; - line-height: 0; -} -#jstree-dnd { - line-height: 16px; - margin: 0; - padding: 4px; -} -#jstree-dnd .jstree-icon, -#jstree-dnd .jstree-copy { - display: inline-block; - text-decoration: none; - margin: 0 2px 0 0; - padding: 0; - width: 16px; - height: 16px; -} -#jstree-dnd .jstree-ok { - background: green; -} -#jstree-dnd .jstree-er { - background: red; -} -#jstree-dnd .jstree-copy { - margin: 0 2px 0 2px; -} -.jstree-default-dark .jstree-node, -.jstree-default-dark .jstree-icon { - background-repeat: no-repeat; - background-color: transparent; -} -.jstree-default-dark .jstree-anchor, -.jstree-default-dark .jstree-animated, -.jstree-default-dark .jstree-wholerow { - transition: background-color 0.15s, box-shadow 0.15s; -} -.jstree-default-dark .jstree-hovered { - background: #555; - border-radius: 2px; - box-shadow: inset 0 0 1px #555; -} -.jstree-default-dark .jstree-context { - background: #555; - border-radius: 2px; - box-shadow: inset 0 0 1px #555; -} -.jstree-default-dark .jstree-clicked { - background: #5fa2db; - border-radius: 2px; - box-shadow: inset 0 0 1px #666666; -} -.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { - display: none; -} -.jstree-default-dark .jstree-disabled { - background: transparent; - color: #666666; -} -.jstree-default-dark .jstree-disabled.jstree-hovered { - background: transparent; - box-shadow: none; -} -.jstree-default-dark .jstree-disabled.jstree-clicked { - background: #333333; -} -.jstree-default-dark .jstree-disabled > .jstree-icon { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-dark .jstree-search { - font-style: italic; - color: #ffffff; - font-weight: bold; -} -.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { - display: none !important; -} -.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { - background: transparent; - box-shadow: none; -} -.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { - background: #555; -} -.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { - background: transparent; -} -.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { - background: #555; -} -.jstree-default-dark > .jstree-striped { - min-width: 100%; - display: inline-block; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; -} -.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, -.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { - background: transparent; - box-shadow: none; - border-radius: 0; -} -.jstree-default-dark .jstree-wholerow { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.jstree-default-dark .jstree-wholerow-hovered { - background: #555; -} -.jstree-default-dark .jstree-wholerow-clicked { - background: #5fa2db; - background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); - background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); -} -.jstree-default-dark .jstree-node { - min-height: 24px; - line-height: 24px; - margin-left: 24px; - min-width: 24px; -} -.jstree-default-dark .jstree-anchor { - line-height: 24px; - height: 24px; -} -.jstree-default-dark .jstree-icon { - width: 24px; - height: 24px; - line-height: 24px; -} -.jstree-default-dark .jstree-icon:empty { - width: 24px; - height: 24px; - line-height: 24px; -} -.jstree-default-dark.jstree-rtl .jstree-node { - margin-right: 24px; -} -.jstree-default-dark .jstree-wholerow { - height: 24px; -} -.jstree-default-dark .jstree-node, -.jstree-default-dark .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default-dark .jstree-node { - background-position: -292px -4px; - background-repeat: repeat-y; -} -.jstree-default-dark .jstree-last { - background: transparent; -} -.jstree-default-dark .jstree-open > .jstree-ocl { - background-position: -132px -4px; -} -.jstree-default-dark .jstree-closed > .jstree-ocl { - background-position: -100px -4px; -} -.jstree-default-dark .jstree-leaf > .jstree-ocl { - background-position: -68px -4px; -} -.jstree-default-dark .jstree-themeicon { - background-position: -260px -4px; -} -.jstree-default-dark > .jstree-no-dots .jstree-node, -.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -36px -4px; -} -.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -4px -4px; -} -.jstree-default-dark .jstree-disabled { - background: transparent; -} -.jstree-default-dark .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default-dark .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default-dark .jstree-checkbox { - background-position: -164px -4px; -} -.jstree-default-dark .jstree-checkbox:hover { - background-position: -164px -36px; -} -.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default-dark .jstree-checked > .jstree-checkbox { - background-position: -228px -4px; -} -.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { - background-position: -228px -36px; -} -.jstree-default-dark .jstree-anchor > .jstree-undetermined { - background-position: -196px -4px; -} -.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { - background-position: -196px -36px; -} -.jstree-default-dark .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-dark > .jstree-striped { - background-size: auto 48px; -} -.jstree-default-dark.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default-dark.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -132px -36px; -} -.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -100px -36px; -} -.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -68px -36px; -} -.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -36px -36px; -} -.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -4px -36px; -} -.jstree-default-dark .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default-dark .jstree-file { - background: url("32px.png") -100px -68px no-repeat; -} -.jstree-default-dark .jstree-folder { - background: url("32px.png") -260px -4px no-repeat; -} -.jstree-default-dark > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default-dark { - line-height: 24px; - padding: 0 4px; -} -#jstree-dnd.jstree-default-dark .jstree-ok, -#jstree-dnd.jstree-default-dark .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default-dark i { - background: transparent; - width: 24px; - height: 24px; - line-height: 24px; -} -#jstree-dnd.jstree-default-dark .jstree-ok { - background-position: -4px -68px; -} -#jstree-dnd.jstree-default-dark .jstree-er { - background-position: -36px -68px; -} -.jstree-default-dark .jstree-ellipsis { - overflow: hidden; -} -.jstree-default-dark .jstree-ellipsis .jstree-anchor { - width: calc(100% - 29px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default-dark.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); -} -.jstree-default-dark.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-small .jstree-node { - min-height: 18px; - line-height: 18px; - margin-left: 18px; - min-width: 18px; -} -.jstree-default-dark-small .jstree-anchor { - line-height: 18px; - height: 18px; -} -.jstree-default-dark-small .jstree-icon { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-default-dark-small .jstree-icon:empty { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-default-dark-small.jstree-rtl .jstree-node { - margin-right: 18px; -} -.jstree-default-dark-small .jstree-wholerow { - height: 18px; -} -.jstree-default-dark-small .jstree-node, -.jstree-default-dark-small .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default-dark-small .jstree-node { - background-position: -295px -7px; - background-repeat: repeat-y; -} -.jstree-default-dark-small .jstree-last { - background: transparent; -} -.jstree-default-dark-small .jstree-open > .jstree-ocl { - background-position: -135px -7px; -} -.jstree-default-dark-small .jstree-closed > .jstree-ocl { - background-position: -103px -7px; -} -.jstree-default-dark-small .jstree-leaf > .jstree-ocl { - background-position: -71px -7px; -} -.jstree-default-dark-small .jstree-themeicon { - background-position: -263px -7px; -} -.jstree-default-dark-small > .jstree-no-dots .jstree-node, -.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -7px; -} -.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -7px; -} -.jstree-default-dark-small .jstree-disabled { - background: transparent; -} -.jstree-default-dark-small .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default-dark-small .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default-dark-small .jstree-checkbox { - background-position: -167px -7px; -} -.jstree-default-dark-small .jstree-checkbox:hover { - background-position: -167px -39px; -} -.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default-dark-small .jstree-checked > .jstree-checkbox { - background-position: -231px -7px; -} -.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { - background-position: -231px -39px; -} -.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { - background-position: -199px -7px; -} -.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { - background-position: -199px -39px; -} -.jstree-default-dark-small .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-dark-small > .jstree-striped { - background-size: auto 36px; -} -.jstree-default-dark-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default-dark-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -135px -39px; -} -.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -103px -39px; -} -.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -71px -39px; -} -.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -39px; -} -.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -39px; -} -.jstree-default-dark-small .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default-dark-small .jstree-file { - background: url("32px.png") -103px -71px no-repeat; -} -.jstree-default-dark-small .jstree-folder { - background: url("32px.png") -263px -7px no-repeat; -} -.jstree-default-dark-small > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default-dark-small { - line-height: 18px; - padding: 0 4px; -} -#jstree-dnd.jstree-default-dark-small .jstree-ok, -#jstree-dnd.jstree-default-dark-small .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default-dark-small i { - background: transparent; - width: 18px; - height: 18px; - line-height: 18px; -} -#jstree-dnd.jstree-default-dark-small .jstree-ok { - background-position: -7px -71px; -} -#jstree-dnd.jstree-default-dark-small .jstree-er { - background-position: -39px -71px; -} -.jstree-default-dark-small .jstree-ellipsis { - overflow: hidden; -} -.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { - width: calc(100% - 23px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default-dark-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); -} -.jstree-default-dark-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-large .jstree-node { - min-height: 32px; - line-height: 32px; - margin-left: 32px; - min-width: 32px; -} -.jstree-default-dark-large .jstree-anchor { - line-height: 32px; - height: 32px; -} -.jstree-default-dark-large .jstree-icon { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-default-dark-large .jstree-icon:empty { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-default-dark-large.jstree-rtl .jstree-node { - margin-right: 32px; -} -.jstree-default-dark-large .jstree-wholerow { - height: 32px; -} -.jstree-default-dark-large .jstree-node, -.jstree-default-dark-large .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default-dark-large .jstree-node { - background-position: -288px 0px; - background-repeat: repeat-y; -} -.jstree-default-dark-large .jstree-last { - background: transparent; -} -.jstree-default-dark-large .jstree-open > .jstree-ocl { - background-position: -128px 0px; -} -.jstree-default-dark-large .jstree-closed > .jstree-ocl { - background-position: -96px 0px; -} -.jstree-default-dark-large .jstree-leaf > .jstree-ocl { - background-position: -64px 0px; -} -.jstree-default-dark-large .jstree-themeicon { - background-position: -256px 0px; -} -.jstree-default-dark-large > .jstree-no-dots .jstree-node, -.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px 0px; -} -.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px 0px; -} -.jstree-default-dark-large .jstree-disabled { - background: transparent; -} -.jstree-default-dark-large .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default-dark-large .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default-dark-large .jstree-checkbox { - background-position: -160px 0px; -} -.jstree-default-dark-large .jstree-checkbox:hover { - background-position: -160px -32px; -} -.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default-dark-large .jstree-checked > .jstree-checkbox { - background-position: -224px 0px; -} -.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { - background-position: -224px -32px; -} -.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { - background-position: -192px 0px; -} -.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { - background-position: -192px -32px; -} -.jstree-default-dark-large .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-dark-large > .jstree-striped { - background-size: auto 64px; -} -.jstree-default-dark-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default-dark-large.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -128px -32px; -} -.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -96px -32px; -} -.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -64px -32px; -} -.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px -32px; -} -.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px -32px; -} -.jstree-default-dark-large .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default-dark-large .jstree-file { - background: url("32px.png") -96px -64px no-repeat; -} -.jstree-default-dark-large .jstree-folder { - background: url("32px.png") -256px 0px no-repeat; -} -.jstree-default-dark-large > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default-dark-large { - line-height: 32px; - padding: 0 4px; -} -#jstree-dnd.jstree-default-dark-large .jstree-ok, -#jstree-dnd.jstree-default-dark-large .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default-dark-large i { - background: transparent; - width: 32px; - height: 32px; - line-height: 32px; -} -#jstree-dnd.jstree-default-dark-large .jstree-ok { - background-position: 0px -64px; -} -#jstree-dnd.jstree-default-dark-large .jstree-er { - background-position: -32px -64px; -} -.jstree-default-dark-large .jstree-ellipsis { - overflow: hidden; -} -.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { - width: calc(100% - 37px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default-dark-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); -} -.jstree-default-dark-large.jstree-rtl .jstree-last { - background: transparent; -} -@media (max-width: 768px) { - #jstree-dnd.jstree-dnd-responsive { - line-height: 40px; - font-weight: bold; - font-size: 1.1em; - text-shadow: 1px 1px white; - } - #jstree-dnd.jstree-dnd-responsive > i { - background: transparent; - width: 40px; - height: 40px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-ok { - background-image: url("40px.png"); - background-position: 0 -200px; - background-size: 120px 240px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-er { - background-image: url("40px.png"); - background-position: -40px -200px; - background-size: 120px 240px; - } - #jstree-marker.jstree-dnd-responsive { - border-left-width: 10px; - border-top-width: 10px; - border-bottom-width: 10px; - margin-top: -10px; - } -} -@media (max-width: 768px) { - .jstree-default-dark-responsive { - /* - .jstree-open > .jstree-ocl, - .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } - */ - } - .jstree-default-dark-responsive .jstree-icon { - background-image: url("40px.png"); - } - .jstree-default-dark-responsive .jstree-node, - .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-default-dark-responsive .jstree-node { - min-height: 40px; - line-height: 40px; - margin-left: 40px; - min-width: 40px; - white-space: nowrap; - } - .jstree-default-dark-responsive .jstree-anchor { - line-height: 40px; - height: 40px; - } - .jstree-default-dark-responsive .jstree-icon, - .jstree-default-dark-responsive .jstree-icon:empty { - width: 40px; - height: 40px; - line-height: 40px; - } - .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - } - .jstree-default-dark-responsive.jstree-rtl .jstree-node { - margin-left: 0; - margin-right: 40px; - background: transparent; - } - .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; - } - .jstree-default-dark-responsive .jstree-ocl, - .jstree-default-dark-responsive .jstree-themeicon, - .jstree-default-dark-responsive .jstree-checkbox { - background-size: 120px 240px; - } - .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, - .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-default-dark-responsive .jstree-open > .jstree-ocl { - background-position: 0 0 !important; - } - .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { - background-position: 0 -40px !important; - } - .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -40px 0 !important; - } - .jstree-default-dark-responsive .jstree-themeicon { - background-position: -40px -40px; - } - .jstree-default-dark-responsive .jstree-checkbox, - .jstree-default-dark-responsive .jstree-checkbox:hover { - background-position: -40px -80px; - } - .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, - .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, - .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, - .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { - background-position: 0 -80px; - } - .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, - .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { - background-position: 0 -120px; - } - .jstree-default-dark-responsive .jstree-anchor { - font-weight: bold; - font-size: 1.1em; - text-shadow: 1px 1px white; - } - .jstree-default-dark-responsive > .jstree-striped { - background: transparent; - } - .jstree-default-dark-responsive .jstree-wholerow { - border-top: 1px solid #666; - border-bottom: 1px solid #000; - background: #333333; - height: 40px; - } - .jstree-default-dark-responsive .jstree-wholerow-hovered { - background: #555; - } - .jstree-default-dark-responsive .jstree-wholerow-clicked { - background: #5fa2db; - } - .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { - box-shadow: inset 0 -6px 3px -5px #111111; - } - .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { - box-shadow: inset 0 6px 3px -5px #111111; - border-top: 0; - } - .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { - box-shadow: none; - } - .jstree-default-dark-responsive .jstree-node, - .jstree-default-dark-responsive .jstree-icon, - .jstree-default-dark-responsive .jstree-node > .jstree-ocl, - .jstree-default-dark-responsive .jstree-themeicon, - .jstree-default-dark-responsive .jstree-checkbox { - background-image: url("40px.png"); - background-size: 120px 240px; - } - .jstree-default-dark-responsive .jstree-node { - background-position: -80px 0; - background-repeat: repeat-y; - } - .jstree-default-dark-responsive .jstree-last { - background: transparent; - } - .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { - background-position: -40px -120px; - } - .jstree-default-dark-responsive .jstree-last > .jstree-ocl { - background-position: -40px -160px; - } - .jstree-default-dark-responsive .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; - } - .jstree-default-dark-responsive .jstree-file { - background: url("40px.png") 0 -160px no-repeat; - background-size: 120px 240px; - } - .jstree-default-dark-responsive .jstree-folder { - background: url("40px.png") -40px -40px no-repeat; - background-size: 120px 240px; - } - .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; - } -} -.jstree-default-dark { - background: #333; -} -.jstree-default-dark .jstree-anchor { - color: #999; - text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); -} -.jstree-default-dark .jstree-clicked, -.jstree-default-dark .jstree-checked { - color: white; -} -.jstree-default-dark .jstree-hovered { - color: white; -} -#jstree-marker.jstree-default-dark { - border-left-color: #999; - background: transparent; -} -.jstree-default-dark .jstree-anchor > .jstree-icon { - opacity: 0.75; -} -.jstree-default-dark .jstree-clicked > .jstree-icon, -.jstree-default-dark .jstree-hovered > .jstree-icon, -.jstree-default-dark .jstree-checked > .jstree-icon { - opacity: 1; -} -.jstree-default-dark.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); -} -.jstree-default-dark.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); -} -.jstree-default-dark-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-dark-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); -} -.jstree-default-dark-large.jstree-rtl .jstree-last { - background: transparent; -} diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.min.css b/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.min.css deleted file mode 100644 index fb1d236f..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/style.min.css +++ /dev/null @@ -1 +0,0 @@ -.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:transparent;color:#666666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#ffffff;font-weight:bold}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top, #5fa2db 0, #5fa2db 100%);background:linear-gradient(to bottom, #5fa2db 0, #5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url("32px.png")}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background:transparent}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:transparent}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background:transparent}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background:transparent}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-dark-responsive>.jstree-striped{background:transparent}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background:transparent}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,0.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:white}.jstree-default-dark .jstree-hovered{color:white}#jstree-marker.jstree-default-dark{border-left-color:#999;background:transparent}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent} \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/throbber.gif b/src/main/webapp/resources/3rd-party/jstree/themes/default-dark/throbber.gif deleted file mode 100644 index c6a1c8515cab5e97ed98d9fd152eaa1b448c4742..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1464 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 AIsgCw diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default/style.css b/src/main/webapp/resources/3rd-party/jstree/themes/default/style.css deleted file mode 100644 index 0703168b..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/default/style.css +++ /dev/null @@ -1,1102 +0,0 @@ -/* jsTree default theme */ -.jstree-node, -.jstree-children, -.jstree-container-ul { - display: block; - margin: 0; - padding: 0; - list-style-type: none; - list-style-image: none; -} -.jstree-node { - white-space: nowrap; -} -.jstree-anchor { - display: inline-block; - color: black; - white-space: nowrap; - padding: 0 4px 0 1px; - margin: 0; - vertical-align: top; -} -.jstree-anchor:focus { - outline: 0; -} -.jstree-anchor, -.jstree-anchor:link, -.jstree-anchor:visited, -.jstree-anchor:hover, -.jstree-anchor:active { - text-decoration: none; - color: inherit; -} -.jstree-icon { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-icon:empty { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-ocl { - cursor: pointer; -} -.jstree-leaf > .jstree-ocl { - cursor: default; -} -.jstree .jstree-open > .jstree-children { - display: block; -} -.jstree .jstree-closed > .jstree-children, -.jstree .jstree-leaf > .jstree-children { - display: none; -} -.jstree-anchor > .jstree-themeicon { - margin-right: 2px; -} -.jstree-no-icons .jstree-themeicon, -.jstree-anchor > .jstree-themeicon-hidden { - display: none; -} -.jstree-hidden, -.jstree-node.jstree-hidden { - display: none; -} -.jstree-rtl .jstree-anchor { - padding: 0 1px 0 4px; -} -.jstree-rtl .jstree-anchor > .jstree-themeicon { - margin-left: 2px; - margin-right: 0; -} -.jstree-rtl .jstree-node { - margin-left: 0; -} -.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; -} -.jstree-wholerow-ul { - position: relative; - display: inline-block; - min-width: 100%; -} -.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { - cursor: pointer; -} -.jstree-wholerow-ul .jstree-anchor, -.jstree-wholerow-ul .jstree-icon { - position: relative; -} -.jstree-wholerow-ul .jstree-wholerow { - width: 100%; - cursor: pointer; - position: absolute; - left: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.jstree-contextmenu .jstree-anchor { - -webkit-user-select: none; - /* disable selection/Copy of UIWebView */ - -webkit-touch-callout: none; - /* disable the IOS popup when long-press on a link */ -} -.vakata-context { - display: none; -} -.vakata-context, -.vakata-context ul { - margin: 0; - padding: 2px; - position: absolute; - background: #f5f5f5; - border: 1px solid #979797; - box-shadow: 2px 2px 2px #999999; -} -.vakata-context ul { - list-style: none; - left: 100%; - margin-top: -2.7em; - margin-left: -4px; -} -.vakata-context .vakata-context-right ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context li { - list-style: none; -} -.vakata-context li > a { - display: block; - padding: 0 2em 0 2em; - text-decoration: none; - width: auto; - color: black; - white-space: nowrap; - line-height: 2.4em; - text-shadow: 1px 1px 0 white; - border-radius: 1px; -} -.vakata-context li > a:hover { - position: relative; - background-color: #e8eff7; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); - background-position: right center; - background-repeat: no-repeat; -} -.vakata-context li > a:focus { - outline: 0; -} -.vakata-context .vakata-context-hover > a { - position: relative; - background-color: #e8eff7; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context .vakata-context-separator > a, -.vakata-context .vakata-context-separator > a:hover { - background: white; - border: 0; - border-top: 1px solid #e2e3e3; - height: 1px; - min-height: 1px; - max-height: 1px; - padding: 0; - margin: 0 0 0 2.4em; - border-left: 1px solid #e0e0e0; - text-shadow: 0 0 0 transparent; - box-shadow: 0 0 0 transparent; - border-radius: 0; -} -.vakata-context .vakata-contextmenu-disabled a, -.vakata-context .vakata-contextmenu-disabled a:hover { - color: silver; - background-color: transparent; - border: 0; - box-shadow: 0 0 0; -} -.vakata-context .vakata-contextmenu-disabled > a > i { - filter: grayscale(100%); -} -.vakata-context li > a > i { - text-decoration: none; - display: inline-block; - width: 2.4em; - height: 2.4em; - background: transparent; - margin: 0 0 0 -2em; - vertical-align: top; - text-align: center; - line-height: 2.4em; -} -.vakata-context li > a > i:empty { - width: 2.4em; - line-height: 2.4em; -} -.vakata-context li > a .vakata-contextmenu-sep { - display: inline-block; - width: 1px; - height: 2.4em; - background: white; - margin: 0 0.5em 0 0; - border-left: 1px solid #e2e3e3; -} -.vakata-context .vakata-contextmenu-shortcut { - font-size: 0.8em; - color: silver; - opacity: 0.5; - display: none; -} -.vakata-context-rtl ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context-rtl li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); - background-position: left center; - background-repeat: no-repeat; -} -.vakata-context-rtl .vakata-context-separator > a { - margin: 0 2.4em 0 0; - border-left: 0; - border-right: 1px solid #e2e3e3; -} -.vakata-context-rtl .vakata-context-left ul { - right: auto; - left: 100%; - margin-left: -4px; - margin-right: auto; -} -.vakata-context-rtl li > a > i { - margin: 0 -2em 0 0; -} -.vakata-context-rtl li > a .vakata-contextmenu-sep { - margin: 0 0 0 0.5em; - border-left-color: white; - background: #e2e3e3; -} -#jstree-marker { - position: absolute; - top: 0; - left: 0; - margin: -5px 0 0 0; - padding: 0; - border-right: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid; - width: 0; - height: 0; - font-size: 0; - line-height: 0; -} -#jstree-dnd { - line-height: 16px; - margin: 0; - padding: 4px; -} -#jstree-dnd .jstree-icon, -#jstree-dnd .jstree-copy { - display: inline-block; - text-decoration: none; - margin: 0 2px 0 0; - padding: 0; - width: 16px; - height: 16px; -} -#jstree-dnd .jstree-ok { - background: green; -} -#jstree-dnd .jstree-er { - background: red; -} -#jstree-dnd .jstree-copy { - margin: 0 2px 0 2px; -} -.jstree-default .jstree-node, -.jstree-default .jstree-icon { - background-repeat: no-repeat; - background-color: transparent; -} -.jstree-default .jstree-anchor, -.jstree-default .jstree-animated, -.jstree-default .jstree-wholerow { - transition: background-color 0.15s, box-shadow 0.15s; -} -.jstree-default .jstree-hovered { - background: #e7f4f9; - border-radius: 2px; - box-shadow: inset 0 0 1px #cccccc; -} -.jstree-default .jstree-context { - background: #e7f4f9; - border-radius: 2px; - box-shadow: inset 0 0 1px #cccccc; -} -.jstree-default .jstree-clicked { - background: #beebff; - border-radius: 2px; - box-shadow: inset 0 0 1px #999999; -} -.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { - display: none; -} -.jstree-default .jstree-disabled { - background: transparent; - color: #666666; -} -.jstree-default .jstree-disabled.jstree-hovered { - background: transparent; - box-shadow: none; -} -.jstree-default .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default .jstree-disabled > .jstree-icon { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default .jstree-search { - font-style: italic; - color: #8b0000; - font-weight: bold; -} -.jstree-default .jstree-no-checkboxes .jstree-checkbox { - display: none !important; -} -.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { - background: transparent; - box-shadow: none; -} -.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { - background: #e7f4f9; -} -.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { - background: transparent; -} -.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { - background: #e7f4f9; -} -.jstree-default > .jstree-striped { - min-width: 100%; - display: inline-block; - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; -} -.jstree-default > .jstree-wholerow-ul .jstree-hovered, -.jstree-default > .jstree-wholerow-ul .jstree-clicked { - background: transparent; - box-shadow: none; - border-radius: 0; -} -.jstree-default .jstree-wholerow { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.jstree-default .jstree-wholerow-hovered { - background: #e7f4f9; -} -.jstree-default .jstree-wholerow-clicked { - background: #beebff; - background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); - background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); -} -.jstree-default .jstree-node { - min-height: 24px; - line-height: 24px; - margin-left: 24px; - min-width: 24px; -} -.jstree-default .jstree-anchor { - line-height: 24px; - height: 24px; -} -.jstree-default .jstree-icon { - width: 24px; - height: 24px; - line-height: 24px; -} -.jstree-default .jstree-icon:empty { - width: 24px; - height: 24px; - line-height: 24px; -} -.jstree-default.jstree-rtl .jstree-node { - margin-right: 24px; -} -.jstree-default .jstree-wholerow { - height: 24px; -} -.jstree-default .jstree-node, -.jstree-default .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default .jstree-node { - background-position: -292px -4px; - background-repeat: repeat-y; -} -.jstree-default .jstree-last { - background: transparent; -} -.jstree-default .jstree-open > .jstree-ocl { - background-position: -132px -4px; -} -.jstree-default .jstree-closed > .jstree-ocl { - background-position: -100px -4px; -} -.jstree-default .jstree-leaf > .jstree-ocl { - background-position: -68px -4px; -} -.jstree-default .jstree-themeicon { - background-position: -260px -4px; -} -.jstree-default > .jstree-no-dots .jstree-node, -.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -36px -4px; -} -.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -4px -4px; -} -.jstree-default .jstree-disabled { - background: transparent; -} -.jstree-default .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default .jstree-checkbox { - background-position: -164px -4px; -} -.jstree-default .jstree-checkbox:hover { - background-position: -164px -36px; -} -.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default .jstree-checked > .jstree-checkbox { - background-position: -228px -4px; -} -.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default .jstree-checked > .jstree-checkbox:hover { - background-position: -228px -36px; -} -.jstree-default .jstree-anchor > .jstree-undetermined { - background-position: -196px -4px; -} -.jstree-default .jstree-anchor > .jstree-undetermined:hover { - background-position: -196px -36px; -} -.jstree-default .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default > .jstree-striped { - background-size: auto 48px; -} -.jstree-default.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -132px -36px; -} -.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -100px -36px; -} -.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -68px -36px; -} -.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -36px -36px; -} -.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -4px -36px; -} -.jstree-default .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default .jstree-file { - background: url("32px.png") -100px -68px no-repeat; -} -.jstree-default .jstree-folder { - background: url("32px.png") -260px -4px no-repeat; -} -.jstree-default > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default { - line-height: 24px; - padding: 0 4px; -} -#jstree-dnd.jstree-default .jstree-ok, -#jstree-dnd.jstree-default .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default i { - background: transparent; - width: 24px; - height: 24px; - line-height: 24px; -} -#jstree-dnd.jstree-default .jstree-ok { - background-position: -4px -68px; -} -#jstree-dnd.jstree-default .jstree-er { - background-position: -36px -68px; -} -.jstree-default .jstree-ellipsis { - overflow: hidden; -} -.jstree-default .jstree-ellipsis .jstree-anchor { - width: calc(100% - 29px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); -} -.jstree-default.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-small .jstree-node { - min-height: 18px; - line-height: 18px; - margin-left: 18px; - min-width: 18px; -} -.jstree-default-small .jstree-anchor { - line-height: 18px; - height: 18px; -} -.jstree-default-small .jstree-icon { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-default-small .jstree-icon:empty { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-default-small.jstree-rtl .jstree-node { - margin-right: 18px; -} -.jstree-default-small .jstree-wholerow { - height: 18px; -} -.jstree-default-small .jstree-node, -.jstree-default-small .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default-small .jstree-node { - background-position: -295px -7px; - background-repeat: repeat-y; -} -.jstree-default-small .jstree-last { - background: transparent; -} -.jstree-default-small .jstree-open > .jstree-ocl { - background-position: -135px -7px; -} -.jstree-default-small .jstree-closed > .jstree-ocl { - background-position: -103px -7px; -} -.jstree-default-small .jstree-leaf > .jstree-ocl { - background-position: -71px -7px; -} -.jstree-default-small .jstree-themeicon { - background-position: -263px -7px; -} -.jstree-default-small > .jstree-no-dots .jstree-node, -.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -7px; -} -.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -7px; -} -.jstree-default-small .jstree-disabled { - background: transparent; -} -.jstree-default-small .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default-small .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default-small .jstree-checkbox { - background-position: -167px -7px; -} -.jstree-default-small .jstree-checkbox:hover { - background-position: -167px -39px; -} -.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default-small .jstree-checked > .jstree-checkbox { - background-position: -231px -7px; -} -.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default-small .jstree-checked > .jstree-checkbox:hover { - background-position: -231px -39px; -} -.jstree-default-small .jstree-anchor > .jstree-undetermined { - background-position: -199px -7px; -} -.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { - background-position: -199px -39px; -} -.jstree-default-small .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-small > .jstree-striped { - background-size: auto 36px; -} -.jstree-default-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -135px -39px; -} -.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -103px -39px; -} -.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -71px -39px; -} -.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -39px; -} -.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -39px; -} -.jstree-default-small .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default-small .jstree-file { - background: url("32px.png") -103px -71px no-repeat; -} -.jstree-default-small .jstree-folder { - background: url("32px.png") -263px -7px no-repeat; -} -.jstree-default-small > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default-small { - line-height: 18px; - padding: 0 4px; -} -#jstree-dnd.jstree-default-small .jstree-ok, -#jstree-dnd.jstree-default-small .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default-small i { - background: transparent; - width: 18px; - height: 18px; - line-height: 18px; -} -#jstree-dnd.jstree-default-small .jstree-ok { - background-position: -7px -71px; -} -#jstree-dnd.jstree-default-small .jstree-er { - background-position: -39px -71px; -} -.jstree-default-small .jstree-ellipsis { - overflow: hidden; -} -.jstree-default-small .jstree-ellipsis .jstree-anchor { - width: calc(100% - 23px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); -} -.jstree-default-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-large .jstree-node { - min-height: 32px; - line-height: 32px; - margin-left: 32px; - min-width: 32px; -} -.jstree-default-large .jstree-anchor { - line-height: 32px; - height: 32px; -} -.jstree-default-large .jstree-icon { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-default-large .jstree-icon:empty { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-default-large.jstree-rtl .jstree-node { - margin-right: 32px; -} -.jstree-default-large .jstree-wholerow { - height: 32px; -} -.jstree-default-large .jstree-node, -.jstree-default-large .jstree-icon { - background-image: url("32px.png"); -} -.jstree-default-large .jstree-node { - background-position: -288px 0px; - background-repeat: repeat-y; -} -.jstree-default-large .jstree-last { - background: transparent; -} -.jstree-default-large .jstree-open > .jstree-ocl { - background-position: -128px 0px; -} -.jstree-default-large .jstree-closed > .jstree-ocl { - background-position: -96px 0px; -} -.jstree-default-large .jstree-leaf > .jstree-ocl { - background-position: -64px 0px; -} -.jstree-default-large .jstree-themeicon { - background-position: -256px 0px; -} -.jstree-default-large > .jstree-no-dots .jstree-node, -.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px 0px; -} -.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px 0px; -} -.jstree-default-large .jstree-disabled { - background: transparent; -} -.jstree-default-large .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-default-large .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-default-large .jstree-checkbox { - background-position: -160px 0px; -} -.jstree-default-large .jstree-checkbox:hover { - background-position: -160px -32px; -} -.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-default-large .jstree-checked > .jstree-checkbox { - background-position: -224px 0px; -} -.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-default-large .jstree-checked > .jstree-checkbox:hover { - background-position: -224px -32px; -} -.jstree-default-large .jstree-anchor > .jstree-undetermined { - background-position: -192px 0px; -} -.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { - background-position: -192px -32px; -} -.jstree-default-large .jstree-checkbox-disabled { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ */ - filter: gray; - /* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-default-large > .jstree-striped { - background-size: auto 64px; -} -.jstree-default-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-default-large.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -128px -32px; -} -.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -96px -32px; -} -.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -64px -32px; -} -.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px -32px; -} -.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px -32px; -} -.jstree-default-large .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; -} -.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-default-large .jstree-file { - background: url("32px.png") -96px -64px no-repeat; -} -.jstree-default-large .jstree-folder { - background: url("32px.png") -256px 0px no-repeat; -} -.jstree-default-large > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-default-large { - line-height: 32px; - padding: 0 4px; -} -#jstree-dnd.jstree-default-large .jstree-ok, -#jstree-dnd.jstree-default-large .jstree-er { - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-default-large i { - background: transparent; - width: 32px; - height: 32px; - line-height: 32px; -} -#jstree-dnd.jstree-default-large .jstree-ok { - background-position: 0px -64px; -} -#jstree-dnd.jstree-default-large .jstree-er { - background-position: -32px -64px; -} -.jstree-default-large .jstree-ellipsis { - overflow: hidden; -} -.jstree-default-large .jstree-ellipsis .jstree-anchor { - width: calc(100% - 37px); - text-overflow: ellipsis; - overflow: hidden; -} -.jstree-default-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); -} -.jstree-default-large.jstree-rtl .jstree-last { - background: transparent; -} -@media (max-width: 768px) { - #jstree-dnd.jstree-dnd-responsive { - line-height: 40px; - font-weight: bold; - font-size: 1.1em; - text-shadow: 1px 1px white; - } - #jstree-dnd.jstree-dnd-responsive > i { - background: transparent; - width: 40px; - height: 40px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-ok { - background-image: url("40px.png"); - background-position: 0 -200px; - background-size: 120px 240px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-er { - background-image: url("40px.png"); - background-position: -40px -200px; - background-size: 120px 240px; - } - #jstree-marker.jstree-dnd-responsive { - border-left-width: 10px; - border-top-width: 10px; - border-bottom-width: 10px; - margin-top: -10px; - } -} -@media (max-width: 768px) { - .jstree-default-responsive { - /* - .jstree-open > .jstree-ocl, - .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } - */ - } - .jstree-default-responsive .jstree-icon { - background-image: url("40px.png"); - } - .jstree-default-responsive .jstree-node, - .jstree-default-responsive .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-default-responsive .jstree-node { - min-height: 40px; - line-height: 40px; - margin-left: 40px; - min-width: 40px; - white-space: nowrap; - } - .jstree-default-responsive .jstree-anchor { - line-height: 40px; - height: 40px; - } - .jstree-default-responsive .jstree-icon, - .jstree-default-responsive .jstree-icon:empty { - width: 40px; - height: 40px; - line-height: 40px; - } - .jstree-default-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - } - .jstree-default-responsive.jstree-rtl .jstree-node { - margin-left: 0; - margin-right: 40px; - background: transparent; - } - .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; - } - .jstree-default-responsive .jstree-ocl, - .jstree-default-responsive .jstree-themeicon, - .jstree-default-responsive .jstree-checkbox { - background-size: 120px 240px; - } - .jstree-default-responsive .jstree-leaf > .jstree-ocl, - .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-default-responsive .jstree-open > .jstree-ocl { - background-position: 0 0 !important; - } - .jstree-default-responsive .jstree-closed > .jstree-ocl { - background-position: 0 -40px !important; - } - .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -40px 0 !important; - } - .jstree-default-responsive .jstree-themeicon { - background-position: -40px -40px; - } - .jstree-default-responsive .jstree-checkbox, - .jstree-default-responsive .jstree-checkbox:hover { - background-position: -40px -80px; - } - .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, - .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, - .jstree-default-responsive .jstree-checked > .jstree-checkbox, - .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { - background-position: 0 -80px; - } - .jstree-default-responsive .jstree-anchor > .jstree-undetermined, - .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { - background-position: 0 -120px; - } - .jstree-default-responsive .jstree-anchor { - font-weight: bold; - font-size: 1.1em; - text-shadow: 1px 1px white; - } - .jstree-default-responsive > .jstree-striped { - background: transparent; - } - .jstree-default-responsive .jstree-wholerow { - border-top: 1px solid rgba(255, 255, 255, 0.7); - border-bottom: 1px solid rgba(64, 64, 64, 0.2); - background: #ebebeb; - height: 40px; - } - .jstree-default-responsive .jstree-wholerow-hovered { - background: #e7f4f9; - } - .jstree-default-responsive .jstree-wholerow-clicked { - background: #beebff; - } - .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { - box-shadow: inset 0 -6px 3px -5px #666666; - } - .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { - box-shadow: inset 0 6px 3px -5px #666666; - border-top: 0; - } - .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { - box-shadow: none; - } - .jstree-default-responsive .jstree-node, - .jstree-default-responsive .jstree-icon, - .jstree-default-responsive .jstree-node > .jstree-ocl, - .jstree-default-responsive .jstree-themeicon, - .jstree-default-responsive .jstree-checkbox { - background-image: url("40px.png"); - background-size: 120px 240px; - } - .jstree-default-responsive .jstree-node { - background-position: -80px 0; - background-repeat: repeat-y; - } - .jstree-default-responsive .jstree-last { - background: transparent; - } - .jstree-default-responsive .jstree-leaf > .jstree-ocl { - background-position: -40px -120px; - } - .jstree-default-responsive .jstree-last > .jstree-ocl { - background-position: -40px -160px; - } - .jstree-default-responsive .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; - } - .jstree-default-responsive .jstree-file { - background: url("40px.png") 0 -160px no-repeat; - background-size: 120px 240px; - } - .jstree-default-responsive .jstree-folder { - background: url("40px.png") -40px -40px no-repeat; - background-size: 120px 240px; - } - .jstree-default-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; - } -} diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default/style.min.css b/src/main/webapp/resources/3rd-party/jstree/themes/default/style.min.css deleted file mode 100644 index 93f80e91..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/default/style.min.css +++ /dev/null @@ -1 +0,0 @@ -.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:transparent}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:transparent}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:transparent}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:transparent}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/default/throbber.gif b/src/main/webapp/resources/3rd-party/jstree/themes/default/throbber.gif deleted file mode 100644 index 64c8eebb87be51df85e7fe51d80c6a4918feccd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1464 zcmZvbe^8Tk9LK*8dp5SQ!7~^z3FH}!ITG-J1cw?om>b&;=J+8!Aleo`1T_TIT%6c8 z1~~jh1NjxzHYAH94(OM4M&n1oj0+GXOzM`NNuFKvJO#aq9=zzR>;Lcf`~JMX@7E_; zE)~XW5P*OOUZB0boy}%Doz8)Qfr^R>0055TadB~Vb#*S6i^t;?6%|RP((dkV7=~9? zR=6u3N=ashI8h~uiNZ(_ae@11fVjLsbEF_2Jyv|A2-WP@Xb&FJS_GSA*lWq&wS|6Kz&We7i(Rj!J?%GlRQKJ&Z{()`heumO#_HJZsj z#HGMq*)Ql(ltilcV*PsvFJcG)?{PUEkDEMnDk(mcxp84FatgO zM&SAVq5nxl2z~(P5Q)HsM>#ST$^3Zf)v%hDOvy}a111}p)-eo$)jIZzsi-drczong z_oe$qnf0FN`0*a5A#0@4{zW6%cAbn+Owf}qGYY$my3^2v(<^@I)MQ4;zX4Z&8Nj(N zM>zDQ`NF=I&7?)D*9LFDNAGfTHkH zBcyVpNC=&t3gfx<@+!)KDaS9PmibOT>rG>Q7+i~b+D^9iQZFKw*{PFMH7mIjGmn61 zS&Fw?)h)Z3Dr|&F>RD>fF1lTr4~HABq*Rp&5v7kfwC;!Pe$j}=s^yi`W>|FE+}AB5ZL-tb=>B8TB|>BP zS{}g*0f_Kq)s(C$Id`l+^={5@_>G_Ud~=(3k*`vUg$BLMq^lXZU$RuwVs+|76L4&B z)jiop@`3KQp}rezIu*{_nzu}ctKFO})$mISv`iRBZ?=DL1znqK^5FloWOWVFZTOEH zjDgSbbA#NCnKzHpZff2tV4g98b&Lq@S!h$RL?@tca5MBjN@HL>+z!=ZDhD!-rU|ud z-KgO{5cql9XI>M|Rt%a#rcZDJ6ULTM?wvSA{4;QXfctw5h%(d7hW*92=W~``ZRI!G zsY+%{Zl?T$Z@m{h=I;%s{mvl#RI~%A749v+%r||l4^Nx*rb~zQn2-s}#S{#q=p$1O zm$n2M9~G*PVusk;6g~LIou}Qc#o;c8{N*k!KaD&#B=IGun;b4?{{2)#4ofm)GTZh| zIz1@KsAzmS;N2Zn`o3KZb2Hpmn&5dZWY|fH;K90ll(mKG0X6xnZNY#q8_@CVF86bM zpl5$`tvF)ES;ouDXKnq>(&^*rOH|2EG)J-9t@FJcCnI|!*L@g$r&T0UarB>CJ7Y0z vY0OZlvlz7~od)b6Q1;I7Fp4H`1;`;0BrjUuXgq+ diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/30px.png b/src/main/webapp/resources/3rd-party/jstree/themes/proton/30px.png deleted file mode 100644 index 55821540828f5b14e708ecce0d58c6369cede626..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6423 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 diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/32px.png b/src/main/webapp/resources/3rd-party/jstree/themes/proton/32px.png deleted file mode 100644 index eb1db46fb25a553a9628e9be1bc8cb86470c369a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3333 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 diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.eot b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.eot deleted file mode 100644 index ec01fc363d5ad20cb912f09a438a1abf9e02d361..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24108 zcmaHyWl&sC^rmNUm%)7)++9OpaCg_>?(Uhvok0UZf;$8a?(P-{Zh_!V2uVoT{QkAI zwfklJ)aldp_S4NP zG5`SZf6?S{B;vpL{}xJs9>59U`_EnfnG?Vd;PwwU1lR$r|A80)8Gy$>-S%JGA7JoL z^#=I-qdWla|0q5HH-Pt_@c~`|v;eyQ6d{1f|JHc_X^#ImUx3a3(Ek62=l;k1*Xstb z0=WE}@ju4?->Cmqw+8V4YYF|23jqZF&CK_2Wyb$cj^O_*LjXWVS5fQ#eLesH84w8t zNVowcd;kJPpxM)ei9i#>Nk>yJmA8Qqn=Wro2Tu7P%s)_NBep0Khnt)nfAHs2rmj@WLY&0~Ir!s>hlPUqhhe~6SPH%?MZMRh#TRg>Y* z&6oH5Imm1e-b(&%c)6dF=l}k)8Zu3CEou_6!8EjeY!`g#Y#^PNsmC|aRI6=i*}$nEkk zh_27LtwI~z8@;q&9h$sxyOw8c!({2kXZMW1_kLz zu9+r#D$!QmPlAuq!2z)ZVX^r62IQuWxii*J{Ak8qWAR;P4o&a&Seb0&u`|i`zoZw< zZ+AKdMo8sBWC}w?)C46qt%dOPFW5#nlMXfFCi|Usr_8Ggjs2jjCpwqGm9+1cKWn;z z@1pkq336lfP<4SYVSI90c7YUEZ{bDp;m!UTSz2kQW}f~YQ&KW%QGDXY;Otb3ll z;xU`*>BS(zF2*$~;-B;~W0-&-DJp8In*NrucX$438-C)XNn8#Vmn~-y=VxO0%nqPR zU;|jX8SXdjh_AO$DY(aG=QfHL`{gA0Y!$2 z-~4QK$P(0Pbz~y0+@& zIWjn}}jSMpp^gU^7E@~L)V`SB0`FU-6 zjYfzQT(sBTC1ea)ZOWUGLU@fAZLDh0MEk>9OHK3^;vLBO>wOsyW~WvvhU??z>Zh#f zXQt-zkQ@yDx&dX_g*xSTK7osuXL^e`P8E84E7%aQ43b9h zOmm0>-~@vHFsh-v1i)#ofj?fS(Ajur2u*n-k*`ZK^AWsQ&sov6Qj4?iFKU;*oMFc` zXzO13Nw=@c`cYqmm~dtDS*$|P)j-I`N4dMOH>OQ2!RR@wNAwosZEhYCI|M81qVHx*)(RCd@!=g8H^ zx8o41M`n3&=zA9*8_yROYqm3lAK?ihh_go1eMRrCU7TZHlS3*biRDJsE*@i5$#K9G zKgY080L824)2ai;A(LZ3xnVM}7$6=x2AQQaFeoLmt9b=uT8~OVN;qO?1FN(GyD2R3 znR@SR0*M@Bk14W+zTgIB>@`>38ZUm^UI^@-%G4Ir&Z=GzwxDvlOo8S4YWZ*fI{aC9!He$C9lhpKJe) zg}h+2ycc|@%f%z<)mFFC5e5J=_T=x1oCK}*kyq)FcOaGi)Ev%ccP&qsHwZ7zhK`|0 zpIQWJDdA>=uxHD`%xx`{g|Q!k51xh!qp}nA2|gcI3FC_mPSO zJPGTh6&C5NdS&j#;AhGJ%b1VT*pA-shf&`CK8Kh z7(yZ4Q-uL^fXl!Ou?F7PlBMOd(+zp=3BYC3MNpi$!D(wqMJ+IHJObfnvB3x*b_!3Q z7+axiVnmVH6RnOW**%6EmSrnnvE#W}jIY36H_(%JAts5O(E|Nc<%X_;+7b|^*903U z5CQj5VJQHjWl&C7VFZlvQLK|uILZk6Gube2FJkOcA<1q=YTm)YJaiNSYJsBtVGOjz z@ad_X=?jV!WPMSg*({o=!YCwEr2NLi7Y9%v24)8ahCT@jEBsht=x=U=JpdtH(8M{I zOZY%alD9Q?fnW(XW<=U9<}o~dn{8Z_$7;M43N@MgK2xBM)2b}jpn|00WSc0s8!0Di zS^m#CG#~1E&@AUbtG)1kGirDJa8XA`l)o7IKOU=ZyKnnoNI=cWq;50xk4WD8?>q@> zzaV`X|Ml|?NEv~D{`Lo(PsXY5J7b>7k!}@~=n4GZ9kX0@eVV0N`AWz#+mB?25 zN1ILwJL7}sXOjusVw{7n?(_vxrNeoZAz@PMhm}Mn8&bX$YPrdMG#-pLEk;Y4-5PfR z&a`VJpM24~G*Qqsmu`M>GYMxzja->>ewjpco=-uCa@!0@im>CpMy&KSDE7lW{MGq< z?lxuq*8Z1wJn@Qo06QS5z2JwD%nu`7dBnU#C4>ck>D`_wsQ8%KfVN%(c%)4|oTqP$ zM*&dJCKa~SUc)$uhhu6H8wz{11FI=uj(?A^z%H9URD>T1^7;wv3+5Y;ZjUg)Y;GKR zTNMS7mI89eH6rNr9o)ylA(q^~W-x_;!H~zCFocQi2<9C$^6w{;VrD|@`!&(va^-JL zdL>NS!=^L5=Xjn9;7KrltD1?p9A_`uIO83y$x(u?ad6E*5gOTLS1Ex_sG7u)w@MT#8lNB}(!W&}S*%bLRhZU%s93}7c38OJOr5F>!(QjI1X z+e*}7T_#vYDJ+EgcD4+1mk&64ha(Z09B9xszx92r0C>T;fsDi%bA$YBraZqj`rJ!_ zMKizEUDMVBwpCVx%cuQuC|v0s6O75PnTe*a?_$6x$WSN(Xvt6M!9RY@F^bf?jH z&a(~Xk zajN25%R56NLKr?O-K8Y1Q>L=1UV$4&0MvD`FChQ%p`L&`Ui;W0e~-NGlrw0}j*nUe z$5P;yQja;e{kEC(s~xl3q*pV82|z+S<7=`I-fbr?vrza#I&n;sl2^eMwF57nj8Vqm zPn=+ancd6m^+n=hrJ^Mo8MHBLi*hVBm^Tsmytaxsv;FXeZNcs5Z3|QkuD~fJat*zU z5CQY%MerIzj0fQJ7c~k7%3qAYPI37o9r>)H7x_~~2c%gp6Pd3=1=i8B1=MtA%^RDM zQMboc4Hp4x^@92m(svrqcs~}i3A}}In>@AjFd8n+#Q6eUz;oRS?j7j_q>`qoC zlH{nMSIb#dDjW!Px&|maDz40ToOm;S5Qqv;1j<=^6@;mzU2*!LW|;+GeD1z zv}MK$iOUeU8jQ4LX2hL~vh($2fE>`v7B{AhefT&+*B*|2-0u{)PR^U^PLq9!3aphB z@&+d%nQi)0oOongNZc={>c=m;Q6~{!!8V|aU4<1th?{5SIa2Rb&(ey&rS$k;r^pu{ zu&z;c#`|s+iS%v3)V~xvLtV4~R>L+MxRD@kau-_9%)jR|Jr1m~QobT+qIfZg8E8;i z#IBPz&LM=Ni;P~(o3K5T2&+(KWX|bNj$2L>^ID70GYG+CBw5${7&=kr9yV;-?Url<*)#wAMPe%$xwDzEvh55z927rt=9}b_lJiOCBM(eLVX!K zYq3!_eBc?OOpW?+{OcFJG8ebd-z9rF^WHg8zy$Hw( z0JY6nE5-d8OJ@QhKw1o@wE(xB;lo{wxTbMd)pZIsu;zf>(nco&H3B<%N~TI8(zc72 z9#4s-JMj4;`<(!qxMyHjLmvZyH% zCpJm96gNTioyE8yAMy=afkHAW38p0tB@fwq!U;ooT~yOJ5?2_QU6n-iqemQfsW zQU(~kEQk>d|J`TTni5j`gOEilQ7TtWTHCoa7jQup5qNECC&z2^2Xn%R-!f_t>B}j( zK%mx|im^cCmVugU8oncehE^3JUy-%H0KkdrTM8rsx=e}IOV~}tELL*;ihQk6tld6( zo8QMgkKs!wYBDSxkcBSAY_`o2(lLOxq`$(yz=?%C_Ax}xSge3Rb~9Y40p~(f7N)d3 zTcUFEsXt(Lsru_ZH(r#tQqqAnnfxY${FCr7%8fh|@*{IrVFyq~{SD)WO}VNq-uQke z)@LA>jOjZyR`OaHcuNWBC$LM6HKcvY=hCz`JW<~inHEAyMp$=a_a_;IuXLRDz2%^` zE~h;7#z2OYhcA+9(;ByU89@h`cSy}Tf!>h?{X#PSa-}q4E}0&tQ=N^6NZlwoPR#`a zeS$c-1@*ZL6vTPm+8o$peH*es>qh*2pD2@>Rm4bDzxIg@rGYQxPO5zEU7- zS2H)r=-BKdg-F17abL(M7>?xdWv+ zM)B(2A>Oa(KL@^PqM787F$~p?FBIZ`1=?`Cu+qg zT6!yi?slz~hK9_K4F+rZ+sITi%^qgREQ1yVgiOk~YeDr$P$K1kPp$?2XL;_HC>Ou8 zSFH^Un;T2Ik>!}T3_WuzoHu1*I^qZGtk9OCcJ_{^&8GIz!6IfsJ08*eg{=~3OIntNxV26 zk!F-(a8Q+wy>w2g3sRA$52fxfh9P zXDn=yjkV(qWX&9vIpz;L717C(ki`r*yvgM@eK#dYB0=-TEz)&ZD(FD%$iBQQwgFB_ z_F)mn$B*@@q9gePGFa|>SAoTHrVU%MI? z&iJMD!}!CJAMb90vKrSxkX0eOC=;_&hM=Z0a+3go@j8{a+_o6I;6jIbnd7_V)!eVf zMCdBA3`g&jEZCdNDAZ3m4Z@FdvR6g#LaR#w46xR}LdV)Rp@N5!EC2^?9f6;&-GOkw zu9?^=v29KiIhiO6}h!TUX6ol zv@8_^3ubiknvzu)_`W% zgYQo^{Faq%1!4SR?FCrjUew`M(7-;JM2fE6=(xXKicYt(^ztqtt}etaMoT+Qv&vGB z?H_G7WH~oQ-01qPtQA0ZW*+Ro~Cq1j&P1x zQv%0@VthBqhlegOu`KPe18$t3<>DCht*rR;(xPkkvUFDh(G*BXBiI+6WoF;sV!QaS zAYPPKr>xEkY;Srfi2L>wbk`VASj00FkX|X$OKa=?JrqARIQPb7ygi6{QBhG;!Dgv# z*flQwOWR0~k>i615&ytJRxg=-)wJ8q!Zo8>PRikYho2?iqpU4HLeubfp+=rCK`y>7 zMfw#L8Cb!T2?v(V{6s*_dY;Tbg5_;oP&J8KRuHGh>{tzP9(%)&hLl^^|^k2T{Tl zDLgo6gHl&sqK_j`$2jOYlnAFWSVx~IZ$m&$z^2@}zHil{sj=(YA7!J5vb)b@oU*sj zSA&7(6E=qAWQ|NmAWe{|=$4oDVM;BA4UVaSvuL;)A!mz2R&Ns*Y_(+1COcOYty*t& z6G!1MrN?9A8zYX!Am$r5q|$eQk?B|sXGP-YD7i_}_xDlW`+O63c}EsN^RC7{x(J7# z#nXNGghx-&)TM5}db~}QYH22#u>kYZYvZ(5Uyict7zZ|n$n6MCHQu~fDm&TRNm3r$XqRY2eWd1#fl}1i+7vDTWp~1 zV0ePF9+jm$(+`QWM-%sfHl1-}$WTiQ_RRWGwe}516!EQZfh!Uy^KU-alQnpv_(Yq3 z1REy+kc2>8|(G6oQKC(!OWS4)NC;qyP@cdb=eV>RIQ?M`WId% zWu$?!BH6YmX4ml1BD_W3)?>7;jI$!txts-t@pb+WigVh>=&$STrt8$O^l0-dUcPMD zAQymGd`ylaYn7x18e%?oQqzb!$9a4)sHWN=ceyBBeohd5mfC@v+0K6YetPeih{({$ z&so&Jh>7zaeJJwiRhe$gR4);&Rit2HSDVZ)fPbmfGsII|w|f80#%86b{VLp|jGsp4 zV$lP+tOX z`QLhTV~2j#yY5xgx^xn$TG1tRK6tiFRx8m>FZ5Ah7WdPukgiMHIc#LQHn;v}efp;& zk;Hej6w!5z@guNTE8GvW6C!?s~r( z2rF{@<3g=dcYTvdaG-1Q@4i&l312X@Ke$Tc-`6PnzvUcuU&h^u^L<0jN`y4;Z*`l_ zCO_T8Lv%?9A@@Y&*EgO0eq^N6%Vq`#l5M)#A4Fp|2jUp1t~@bND_Bo2>GSR>=r9PJ z7?EAMeyzbUjDr&pZZO?Wc@dK`MBl9inbxKYak+O4HpGbCT%k{#E*^dL2-`gClbm{0 z4*1bpP}$z(zoOE!qukr~d~k^}5~G=LO3kTfrK-)W-BqO$eZ?$In=MzFNZCw}r6v`G zu}jtR-CxUfAUh(+kAHlh#W!SpPBCbmA*sW`X|*-@`~2cn(vX+NbEf+*X-@Y)t*<<~ zf}zg-D3udjTzM+7cTp+BAsH21vu87{ z22SeBe%=^BZ)VZWPTGsv&67fpBNEPvt;X&Vn)j%5f7p({*4_8NCgaxP98s0IJN?dV z5ah5w3#jT^=C+>N&+k;5%-lNd)VgZ`&h(PMKAbqMnB(SL#x9KeNy$31741WdhE804 z6m&8F+Et_LcaY`X1HmPkn#Z;J$S)Jj?TC*RF`E|cgTw-dqb=0|hiE|^=wj{0IgJ`; zPrNUCEOW*Q->`ZtU8eHay_($4hg^4GdnnF*T#R1!eY}N7QFOY=hVuUvvRYOq_ZQVo zO4zdVRRv?)7UYd=(PBQ%nbnk};w{pk-=+suyh9%0p*>S^ojQJRI~oEf7LeG|8|7M{ zyt?_~aV~>0Ko#+IS>Udzh#Q&e+i%g7XTs_|d=N&>Z%k@$Ybj>OD}@=)_?vBm&HKNf zwg)f*oZ!B}2C8Fz=#gxi+;2lWcP+-kJJ_OSj?!k=syxD*QwcH738cQz=0_WSS9cqc z>Yo*)a<|{Sk(nuDS}}7BMop-qTt74+x>`f|cP`NF&1{(ahx(gBC6H>oSU^^eR1pbx z64NEyw9^sH|4O-6jKw{yL$V%rMp*?IL(~5HXrQgBCY~x^ z>CxsiPui(!+iiL1hkhfxfWx2aHF(l6%Z`ZryC@4C*|A2*7hDIQz8(R*hVef+4`T|i zaT-$LG!=-I>V?PTLE*#f7E$N))8*ns}sM?eE>NQUj9Aefdmo9uakrCr>Q>s+R zvNUGAldV&RoP!k|TLkH?Pd0&-HBpd)YgU{0N+sIFtbxFR3tcn-iK)r^9)5 z^M5?#UMuP))IXHWCCqI<3sC69V!N|d>Ed{iX$`5BKvAud&RSX!ELFUJsBziLB@~>*h z7M2QJq!M`hV+NsSiTaUp2AB8oWQXKELiF+r?xmk3&PPN~48b2`{UQKo%ChJcFT=LR zT-iTv#b_Bmtme#qVH{(*viiwmk$gP3HGco+qByqSB3yJnl}T8m8i_%MMe!>WwPX{Y zBvuwnwLyy4FCttPio6TK52fFv5Hx;#^RE~a=)~$3rJC83hwSt%8yaI(yHkbqBFIeU zT;z+LeBe?wj`T@i1^%wx`W;b5SN#S(^jA39#l06Q5@Gzbw~3UH&y;MXv+u~N#VW`f zXqU%+K5sYsG|O9m&=4`L($4rm#uiHO;{!z7EsQE%Mu?kF77eD ztAgJp*XZlKd80@`cSLEPV0eGj`E7oEUHf)gjwx)3f}ToP!>ZWPAZYbqAr>!x{8(gN zWabmlLl3t1)>p-MN#y*S6qrxrS4dKK@ zTo#Zo=2vOT9-$)Gq*qVA7LhAT+|ZfMkcgysW9p=ggP`xW?d7P64G0|+<&*$1m^Qo4 zcKk0|;Nd;0st08M^q9O=1*IwJLWY+h$0o-k-n|{3X+y@z?lLsHfW!(WR5^O@Dj#xB z3P+36YfCiSy%&8iXz}CQURb%e#{iSU&PuFCIbJ{}xKoZd=*?9qV$#`=m5BRl7erdE zyth0EJ3?Up%>NmRgtQ;8eUbT4^rM5fO@?Y)x`HuC$%0q zb@*scL5Sjv6jYHy@cK9OJR7R*iMV=w2Ln4$@9FYVpFImx)fc4E=8|o`ICK`UHj{57 z9(KmDY_KS1^apshuCv^~;48>h2@b{}xMT8@s7dYeMmJU)3Uq`lyADW z@cc9CiTQj#O87;WipB`pGpwR%TEsq0$OR>H)97GCL85OIFP46$Z5U?ClU%y1{rB;J z1R08>G%46H&zLfWWs^jAKBD+HiHYux0k}oq=ZIM=P`iRLt6X3+PMWqbIS16CjPTIG zuyKpAnPjC{JE;<1K?(_#dG=Cm)bU8}s`Lm=u*)0J-nw|snR0?lU@$I&nhVlm6wF9T z#KHnK?TNTqo!Y(;hYHMBgRyRGf6{N!d%C67v-uz@s?$o-&arbdIxV$J(S7A4rGv)W zq$)>?Z1)~JOU5EI=vM7vD>WB%UFh`gEa`O{nGquBGnYfvt$Nv%MsndPcN?hj6RuR) z3?YOv^Salu{-xQf4V5I0lYXB%5vOFf_Gx$r)RXw0}!E^d^HQVIY zoY4nD$qEB4&Z7fC?c&(vHx4H;he;&4b2FyYauCxv`uziQ`J#ns@QiRzlUm(>zQ&S z^lY}iMTI(IpSg#!6G>`7+T+Yxn=#nFnXd^J_(q=%`%@3OR8GVX;Pv#5U6W=e^6SVk zol#pHLsI_8t0DNCvKBh6na!$3OkXGRhawKI|$N;kZi?txkG5x%74N%WUG6742*3R4LEIIGpJr%|0i+v~ zYld13^3A(8HFawJvLn`>x`o$bMMGuzPFmA8HX)MR3vb8a5f@70vGulvPR6kXTni); z{?rcpcwjLsLwR7HJazt>>d2jo)?vSG?0kn9#|CObmib}({6(&3*>UKj9{G@KDDRZ( zTH1h%^Ba z#^v{{Anq4IA!|k@(yw`xR}2IrR8BPd++Xv5O7^&FNk5NTMsFyHDOrsYppIIi+~Lj7 z=<6o$mxMsZ`+qfhX$V{mpN{9A@EGr6!HS(WWPRFDTu`SlCwtvrKNVQQe@|TC{K>#u zj+7zm;w_#Udo3gVAokgwMm#|K_WZL^oIO%>iBj4bJ&!$b^G*haPmn!L9Bx~bv&m+D zCr@9Rwthi8mWgC84!x-N6qlUKU=Cq8Xn)msNJ+u>=m6FpU@i3(@4juG?*Jo#S>sXO zb_wpQZfo~Fo94K_uP+yo?;Xlem`ds?{EU;O!K_G$Mx{J})Er-jGotye?{tNgJ4GyJ zW_^Ji{`E2_?uWmNq?JdX1aQe5U}rOPtVe{A>>7ZI_}0Nd%a8VFWafQxOi< zw*iG6-pj6Ct0c{P6i7RGu6#8flm5_Xxw1Er7;h}N=z*5{rn>VvgT%7jX(ijQ^-n_H zkM;tg79YoKA#fDT3*!-+nV;oR3c35*e=><{Ah6rY!tY45$hvKV17g1&9ryp{c4N>q zX^yO>lc6Q+y)S!?iR|uss3KJ5D?YWB;Y=+EWSDxvB?X4GR=PlLx z^rxB|CXb|(_po@0H=tGUe00{K)rQrE7=k<%{iZ>7f!7JMH?nl&MS#Y0(N{NaVv>Loo*#? zckv!S=_?c|=6FWd-1PN(arUA_gm;LWtHffWe6-}ciWD6~-P=Yw@o=)ccCTHeuYW4Q zCD>ao{EUYu&L+Jc(=hvmK?RUZ*rK9=Z^lS1+Cr0`@bUC3lLdx7)oYkE5w^vygE!*I zQyP~n#MD^)FOwyuUSUWoa*>>WzsjPp*bdco*uvk@R`)W92M+TlsPctY#_@BzffpcY&SPKG{qXUR8D^AFCuT z-So|zP=```176(GGBr4&=ZK7VJ4{E&Hd4Hh>UwLgzn2Hg;S{3rYd2;?!66^q%R>B^ zb(MLm83#K%i24C{jz3SRHOIN zp@If+W?wJswLMZZdwrv!)h@v{!ySP|xDj!<#=M9nPetu|g0`X)sqvQQcsd#enN&Ue z6~K-Tun@Tv@Y#;cnDK%VRsT2Xz8VuYyKcTp`tuJP>MwbJ#pH04v3*9~%4y^X;tiSZ z`72GkR??i$2uSYmh$%0=QxFjy#t-BJ-pPLUA3ZUwwM81Pl`wWWI(jBHw@p@>{cEkv zPV}MDX1Uxu&A11IjhCf|E|kh-EHX`*hn6g2VEtI)A(p8+|C%>q;C*L$PH{4y@@ge^ z5&l}Ap3{{Dsy>7dJc?>Shm=g+Jcs1f)Bnc?Bpr2xs$nmR0zEU|oG*x@VIH6}k&uoU z^oE@<^BB7x@$Zu9(q^@rfiV$HgvEOmKXB+W0=qUjSJP3onQ2t<2 zBDfi0*}&3lynF#GM%fe%4F46D=`>hEvi!0(vC%ZGT@^(2 zHX!u_9Yz-338GCA1!KDHa+dCdh|`~bEG!h}Eq55i7*S7?U5sAiX?yl)6}}OEJy}aU z9f53D95BdtCs%AutzPtA4ofZ@^azB&HJZ+=(w&3>| zZMf3*Ay5?1T1nv=aahZHRE>EO;ZL%_(8LUkvE-Wl-9zZ>*YR_kLM0i4v5G|w@BS8k z_~jP%!CA3zm4KeW)49%BL7i8&k7}E^F)~w+f@M)rQL56no*zdmlTA^B#GUpxfE4;G z?<8Hbcc8#TIHjO@N^enw=2Y+=Tsdut4LHw)vhA(Kdh4*eqbtfEu@_K55uf<+1e=wK zYw|VD6|y5d+*^@us}G3ZF=`n=_532!VfwcW&0v~%!*YG1ZL@?D`&!oLB<&DYd^Xr} zjPl;PUzbvK${SG2*BfQ4>5Zrai5a^0VamCd+;b-LK5F^%2?vM=p+hWRa=P##-Hm~u z#o$$ddHIAc`IEDn486h zOvU+Y9`jeuv>aXuBR-{1CfvVkGBBL?CuDlC!@ty&M00O18Z)ReW0^^BaKV1aImDx; zsSyi_)EoP2KHU9sa>k%qARCHlTWU59bIl(g99vlb9 z;e@!pzWR)x##H4TxmG2zM>1GTcj1&v!~JrF8b0oJcx>bHEEp7N9Nq>hn}#%Mm=?kB zy{0GeKWm?opqE?DKDY(XgkxS^+m``pX2y zP@_F+Pd|jaZC1RK6YqpD}=8ztDK;#Z28j1EfH>P|3{(hAnGs)VThV^B=CFriIlBzja=T zkZqOm1)-<%&)9g%BHs+WV0@8Hnn2ufHCFE385K)819eEzp=Qdxq9v5Gaj7;8tnNrP z(!NG?5%bapu`VXL^bkO+X{$`CY|W6pzLEja?_PCegjI0OgtkT-PT{N0{OR@6NFNa6 zjY0>v0in1v5|51?&4^+$^sOa5PO>T@#cNR9>=YII?qUi_DF#VBp_|>CzHlu_i~L0+ zE{g0r?oKuMg)24<4Sin+&yvYGukh?+VPmt$5wW?mGtL$lYRA88E=i3y4sYrLc+;06 zDU>VVIp$m_`Bq7h`A!uk>g9i|)e>pKO*d|FHJz)I<`wlNI1SAjQ{65xS(0B8P zue}ILysM=b>JxQM8QDdvm!uuvU1CZoQ!ANP>i0FF)v3eY>fI6Qm_80iK;0}w=tV6u zq1+d;6YW>b*xlA94%Vn)1{~K=rbkN!QoMM=I&pG13uVq>-$mtw+-in(3*;Dr+GL(! zljoSef>)aotI@jGOJWi%K*P$RRYbXs?$^eYeVslAv@SBUY3dV%TRTjnQWHw9?rpPDWNk;aY`EC4qmrb2(XQTD=HnIi zGPY+nb$qXOuDBv8fI0g?Ki+PWIk|a7CN_!vYF#?OvN@E4paQ{JLmifE5@uIYC{Fofg=!($SVv{Ow(Pi8o3REEuus6@_dJA=r*W2~;H{D@MmdvJiNCP>LXA64cZ{Teg< z+Jch;){yeP`lEY1B(Epef`>XgRy3PPPG8(@^wp?2i0x+Y%O;w}@vw93&p ztb>F!JaB?f> z00m4MWidU3^fVbMTam^Ui8i-Jylicdeo2)2B-o$R!xmw~$t1skni~0nJ&925_^xR=d^em8}EzM)?Tl&32IAm@augt9%=$=6Z$kINh#(@qXD z^{1dY=weV55I>F@jz<^ zbACV1Y7=oF6zcPu=715qrZf@7GgJ_}PofnC$`bbhQ-Yoz!6P!b|BUbo&A7E+xs!?I zma76Kd0j(y8PNt0eUBu?3MxD&8htU+yrVwZ`2n}=c707*9m%2Z3HdMb8jqePad36E zp0dYKAIJs*lB6(`s*nmPkoAN@q5$>$ zh>Cd8@0(tr9w6shs`|pt%Ccb5og+9XW@@JEd55h>G^&(P)xQjsB@op)eb3=Ft@h0B-q^x zR&!|_UaLhB*YJjUpJ=ifw9nt3HRz!g^}GGzR23){G~~&dP1G1_Zzg6AUzf}O{FL8` zPAxPME2cyo* zf6t`&&IjkzG!J>}vYAOXrNL<8N!G!W0|@CL$NV zelSVGfit6w2AJY<`MPac`kS~c_REpzi`iZuL_eyRRcRr2iULm@3Q3?l@*$T_{OHDNKrL&4_LdGd0F8!dzO1N=E+Os5Mvtywp^^ZN zv0w8v10>6tOZBI0G>J(Lp(Z$ykYwkZz3qoMBMDw8TQu)DHsDLdVG=UbrUxdh!}d9k zdH4|iI{;=pu247MB~0Z@UOy477SEt{kYAs(xb}=bg7c2V2Snvk{IW(fye1JT4toc} zrt66cA1*0R`#QCVGQx+04rvknJMjjZ&Dx(bl3Z+x!^nQ$ex8o_v+hzAPeT2IX7^b?6x_v~dc_RC*^hl_flp<*f(}XK)@J}LB;l7{@ z*$(MUZG{8~_>#UjFydW}nVF1roTEd&KaJ!P6X^9D+Q^wS83s0Oj2?v-)G&rjIPsXX zgaI=lYzA+!%ReQGo9bozkX6tol>GdvJ6uleFrwi4;>xYG^U8(kl~WL7ao74jF2!0ZOS|!N~B3Da@ z@=W{uHDZ9_H$H`5dOBhp*G1)3z_S1&S}_xlm_AEGkl}SS5aogAZg%E9F?ur5mcfap znxAwL#sd-cdC0k28aBq-(w`2iXXw6UEA*-?&G{V%YkQo`W-5`X&OtVFY=|6hC*eRA zncUu0ELQt$sKOc9K!>^UkU}%+1Mk)+dC!-58Cn`bo|8C#Y26Zx%{155D0@M4UU~r5 zu1WP?gw~jj0CT?rF$%Gm?=N=ljz&poULuKF{F>%hXw#u#u$Z%;o${^$TAY_ zktSz1o5D*>3WBytxdX(b`R>UZ^f3wGYu?Q=YXy?O+8TW{c&9mT8xPzO*v8ZX5bR={ zq#Fp9ZC%uTaboA4bm+pU5Qtjhv(BvWES;;)`!4LARW`R8Y*)RE(1b91u6Gxr(yiZC z-tMUdk`mjFpJGoqW3nCfqi4rbz1A}$(vU?T#*A9!b-IzUx~rlL98r_Zl}=^CgdLO- zIFaF!9IEKYn&P$pcO@H$473C=PS*=u<&kC}V|VA(?Rn**%H%8%8vlZb^Z)zpjNkw& z9lwUcNd@ti1%Utbz4zCr6wz`lOUOjqbd2 z%QSf+HMM4_D{EDZWkHw(C2|%;%*O3V+j9@d9n?`y(9vYiILXDIY7MkgZ4=^L z9(-`rLtdq+X%>z<_T%A8-G)`*PvHqpebQ+-;Lx=UDT+aJPZ9YU7`=K4L-r_kh#h^) z?Mx+3^)MW6s9X9s8~E8u{Hca<7v7eD6s6PqyMZAe#iJE@0y&rTd@T$1`pJb?0mxa3 zax|TNeq&??_VwAjwU*avD}2RDUaf7$A#)jXdGhV;_|PC4MX)ZwH}H-jSA7h0ZP7>; zvz{oPu@DqOi3MSonEk<^BRkMV3@iiv;d!OWiQ+5VnE#G(M(uuGH^}EmxPzjZ<$_}S z02Ug4y>K6UjVj`bwjwhWy&DrNcy&!KizEIZs=I$1!$93!&e^Sf{`{nBrUvN1`nZxc z82_YbS@)6B2(m9iZzGtW&d2d+JG03g1oX+mI*6M~dKMfPPP>Z)eax+QiKox75m(C` z7*8PCHWaL3bJ37!v=n=V@@u)pft|BEZM+0`R~~O4G8`Z+JQ(vyU%QxjFuB!KQ$`~Y z>))%cG~x)a%S=5kUe(QIpSF(?hw5mw(@0VBE87S{+eY<)h7-w+;8luj?U(m3;m z_xsX=jo?HY*;Y|`pJQ+rKQ$8{6^O~YB8tWr_x;^MpF^gr_v2qFQr=GG{&8h=Tl2ro zHb+xa2s?CHYp)r&f5pC1fv2{Bp?0Hzg>`;kL@A_}1R@%c=93B=wvHNqagk!XgYdea zjG#tbk0BDFS9~@Q_$$MF`u`Pr9fjgvoqcVCJw&HTEr}tv2b7~iVoKiH=pM>c0J-52 zn-Jic6<(*YVO&Q$*|)GrU|Y2(W;^;wnZJn+27-rSyt2Bc%rT<}Q6Y#Fr(}v5%&BmP zj3O1WA@|1HBZRaGt+LkBv_VkDbn83WoC89j!2~Z(g~Fx4sBLNNCKU&FQV!*AWXaEd)h0f8V%i?I78^}+d4qI+GY`-j8 znAFS&tOzCd42hJmO(UVTB?-|>UN~U|kROAJh5;=KAuX`l^QD(uDIs9SNY0irAB2Ri zpn^C!RFdUF-L@6j70pY_mQh4U5AZ9-l+3d@@=kwgLwu@8caVs%k3yP^LD4FiimteA zfG}LjYYTS_i?D};z0W=ql+mo>7E(Z%&7+I6E@5G8*blUfTtyZV!d!#Nr3#Jqcb6M% zlUp<&AS8s2It{W(v(@65?}{24vuib!7Wq=cakfS{d-3oARmx3iT#X2TJ@vN1!e>#C zYTnS4&knP;hPs{941_8-(M_9ke-#1`*TiCF6@(MY6^NgeS%yGyGO2N>0zorHI3+?RR9}y+i=n?hxW~HM3nD}4?1xOVsxRg& z8~9p4#`#+?z{mj^D>Y?91)8nzkKZ!qUWSU2(cDWz`!E$bjFY3M|ojyL$I_AUt9bmVs&S;Z{m!p$5JiP z3E?9EAw@+J>4?2;#d%8x-}pEK)Cj*WY!K?h;`$)YTJ&GsKot3qbfanFWQ1e$l()4= zYjhNCaT$$$WI4{73aDEUeL?P+j6jd|3v~&1KSJt8K7>@M7euUjKp}|09T~jX_DGt90RHZc zfQ$*wpdFZ&zDzYq_>5js8`Y2kyN4CBDZ$Ndai(93Y z*$FQ5ZWy>4-HEHfYqpH;S@xQ$+u~W*xZkl*gE+Q0q681 zJ`&pdmu;DxU0+RYJbr@Mv1-t5xTNK<-jNFuEK(2IE&;{HJZ5P-M>p)o?VDk@gXc#@ zt`d9^JQka06N#WK>6o#JVzNNf(p1<}4ipMYicnf|0=>Q~I#bpi*!VFHWr9o_1%(Ni z1(+OE?6yIIcyKki8c_&eJXj+zsC};dQxHqGQsDW-glB*%-B&FFLP7F9@jAn{?NWn7 zgQ?XUc8TN4dR#Q}7Mon;V>m#5rMTs0yY=D1JQ04(dISb;T0x0|lZHOIz1R!IPe9(w zvxepqtpb0EXMX78M=YPo&#AoPR(OWL5BMA8(q0z&`3vfuf9k!`ZSkSiVBJc zu6L06(CAz{H@7N-(a;;lbKNKI(`tCFo1 z3H2sKwDYJP27dT8tdF8gH7nsXG~^uApkW3omYu{uYoioxRw1+nUn9`#7?SIf_pAV@ z>bxshM=U`2@KB2Yn1(BiP__*Cc7Uz2PGP_^t&k&M#^WXfBKkluZELg3h=~&g_{ldR zg^JFqB1t~hP#ni1Fa)C_f<1K@Xtm?gUM`Z*T0m%b3rjc5lnx&%TC@t2ls(n$^i%YQ>=K@|LL1dd|<)Wk+zms*BEdsX;_edlG zIY$~e*02{VjzSw`!(}OTYd7lLrWK|1vMQCzV9GSa^`l+9u4pT{4A^bsjdTkuMc;bE z**{DosG4+lKty3tOIR?m#YmWnh({O$BA^~IFqn#j(pLB|OyXBU>-#OxalV0qJ)sL^ z#;d(cD~FRpLcfnDaHe5;ymM72p?FD6MHUGSt~S@!#NPM)%Phv~7!Re0cNmVNodCVbWOyR_& z4_tvLt;|-bF(5eM%uq#iIdSG(N?b=Un`EN}in{=?Vlm3NNM;5j>6lV%j2d8JEa+2p z=Gr?i397xSL@EIw!YlZ6>6DUH!pNJ3={p(7n%*hYE1PxqqmWda4%nki>!e)u>ejX8 z&Np%s#XQCc_J}sNaiVC+P}cIv{;R-y#O;IN_(B6vDS?72H#&8(bR_G}w*n?>j9Gyk zDNRl=zd8~2-q(jKRJ;;5&D|Vs7xQ`Cqw7$(*(Sy?=tQ}!4lEBcAZStJ>|CB;1zA4H zHJ);tF{f5ps3J>Fj)ABVGgvTFywsv60si(#gUf=9D8oJv5ItdFKEGUzt8{Zb^{L=W zRal)cG?r=W06Rg&MdY*$%DPDr*Fdom z(HT~(NYIeVx#n=79WYxKDqIl+X)yW|=stw{51}#~B7sfDqc>IzK2q}X4Udb)F4p@K znBK#nzT;%;)|x5CfkC7l;J4MbVKSgW*;=6tqM$+0pHLNY5^Y|Cg=b5xiU?IBB9A~7 zla7p-)z5>My#vTc8*`OVzOuc>WFX+vsX^0*5wUF!EGR+>v-Tfp+FmqT8!@UENogV^ zC>?K@H?++lRV#N^`*k)FD#?IGIRQ-I#BoR{PKY{bBuyba-5nJLMKQt5U}0HsT3|c> z>3k_UxX(Q#I5Ub#<L_0^J##;}XWh7y+oTY@0-#SQ2t>uFgpy(hzpI7de7jIhisd zBd7t3#IaV=I>t8;s4!qdw*}Ym9(@{4xn4=}Yi*4!3xsJ-3hf})vWV}|2;K#s$1vdC z4?@wzCz1J~w$g&>M8QCbVCKkYLa9$W{`nGSMsrD2tEEeMP}zVws!ly7g%QwwTn&V} z#rvHp^k|(duV@EjidlIG=T|+^*}+j<)A=e%GbSRM{y2spyBUgLA)3v#4W=!`sv$H@ zb_O0Ay9y!%odCJLwCy%5&+MlVPbmnwsNMZy>2?BLxg~&>;_tc1E&tds_tN33!Y zf#fQAbw*ip#ppbf$yZ_= z#mBSKGCz%`4NIS%$<<)ZZo)VBHUxuEgyolVrBig00mJb$dn>cpR$XAR6o!*5tB}l% z3S_|&K$R2IZ!Qv)pN*=bH)vyggKyU;tJ@?AGciBWr8UOV8XXF8f>N* z9L;?8n1+RF)fmOj1;j;rDXe4|={g}{J!=V|3_Oi3kYrcq)k5)FLQlZ)pa$kUq{{nnXdyvlw*H z;Y0BNuMzCW=ErkH8(z31x4~l3QmAhY&;jyA;LAJL;>de_S6~Ki-sYLn|M# z9b6G`iqKrAdYjYXvHOULb}L8;^2siKf1l`$GYpIZYQ$-xiTFtVG%bOOP7}0>tZEwJ zAo=DI+*HIs=dITa_VbGP+iC{(Y zQzZt^0#2aW;7Xtq&p{7wf+o>{NGH5v?qd0!SRZ?zzZXDKAGPFCrVS%dlGy|wYua3E zBZQEPO#+!fBUxh_AA+w-`TQ)5IeH|RP{b1pMvY)VO5de|Mp6B}gT661S6}v9ABZ|uS5mQ}p1zwGN*f}K`R49sR!G11`vdm0imz!n?7XX5;y#0E^H$fB^d;7y~o`U;#QkOaaI8%K-kE01uk3=lHfVAVZG;mlx}w zbZ`eMm8j-ZHDUia2}Ss9#et|<5+sE5I>RNVW!rT%+-A#NHOxYsh6$N=qmcOcTN$hg zFm&+!PCHn5+;SK($Y9MDfs2L3R%vl~>w|RcgiYtu%$bO)jHumaFDMbeYj6RoC&Rf# z+^E1M;{Mr zTU!sML}VA|i=vvk*5mMt>QF#Ih>AQyu-&v5hs#nBAHMC^##H6r8ex}x>!rpTmtTh)+$?M z@-;<}d0r}CtmEr6y+4X>$z}X*(I8F=>Wk6xDR?f5>xI-APNN46(KvFbNY6})OC}p@ zfM{-+QLk0hHfYvbs0vaTmflEM?HXr<%06yL_-W242J$;Di#)D)Gg*X33_cPO9#3-AoY%+tg zMh_hS#H1WWM-Sm-SGuh7d%lrjpsp#R@QU?uA;-d?c2PXh28Hh4T#w0S3e!Rn4Zx}% z^j7B=J@oKtz+f`?OhW{wqbX6GP>UTb!y(3}WJ(EE0M7vvHh|InBoA0`p{GCKfhzTI z4%W^d$bjlCMFw_I*ugZs85hvmz{3+h3CkHAsLj+!r5hgLH(>;iK)Obi8B96fxgl0O)EyIb(Gx0c@5t zM1PtOSq8ghLHdMFaaZsx$Odeh3R1+1e*`CEjCy!nV0D1us1qTF` z;iSza83BOEp6p^fO+lb8frIB{QeOQ9!07495WrglBAt)&wBVR6kZH&{nv#=OMT8H! z%0e|47bZ2y48g0#O&?fP+^VUEnmlyTW=(ddk5@WoL)Z+Q42f(Bda-f>0>MB)rxsBx zFwoVuqR}|m5pt!PK^ASIV1yiP6qJ)mFttY)Hy^5J4|aCXp-UIa?_%A2W~ zO-6cbka|KGM!Oz>dAh$IZit8IY3YSi;Jh z01=BLR~aIoj%QA7A~F>k4j_w<_^kCsz!twYpZnz%$?20f1de^DSo) zvG=u~e7dS4NpN1$P8iY7+6G^N4~%_q9uM=y#q4r7W0QFAE$B@ASD-U^3Ap@#i}|xv zYCeqkV;E;;xWgRQSPaajJqUSn(-XILRVNBhN_sl(bBH?{#={mbt1X4=>C(M_LRcr& z#2#sbLByNVIkzHE|Rpq#%e7d$|B(l!(p@oe#H;)tv zn?!}ra*|wwBn2Z`_jz&*o|@X+&OTqFkMH+3q*1z>?2r$YK|Q{>U&%$rDx6K-zD8oL z3UfMO`Av#-^#EJ0G^w*Xm{15;IBKN_&ceTR-C;%V?Vt_wyBuv)6PX7Fr``1cd1VYZM z9dA3Tzz%2hh$tA%2PbyN#Xf}#H2}lUdhk5I!#2d3i@qg7p_F=CX+o-b^GX#%#e#-H zs15&(8Lbxa6o6tp39|P#EAL_}&Tm|1i}2+~D3gRfxX5Unuk^O_WC=)mmUp-?B}PX4 zy(&+HTb68(vJ^Z;D3r-`F^Snhvn0EFgGE3gTCJL{A*d)p(2~#dI8-a6Lxln0NR-C} zL!x|oMj0-h!? z0E`|>=LsLtVw08j!y}! zRvSi*lVYO7OEcN6WoKuTOrZ-g0*-JtzHlO$#-*Q(?K>OBDtO5kgR@iLbzX7>v@@2& znTuZ$qG;-1kwi`tkY_xPSjjp&J5<6Jsuo-%P&%vfUekRzd~1a3gvke$&$W4B_J#(% zVsmVlX4aoyE^Jy#Pohdqo!g{RKjcWY0{?~_7w{U4%zw7JyI$$ME4(Je);N6rik?mX9>8$qFy5DHSlL2 g`3C7R>DJKmT!b7UXrD}();T>vPCv$$M?MGc9~7&g%K!iX diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.svg b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.svg deleted file mode 100644 index e6308463..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.svg +++ /dev/null @@ -1,2377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.ttf b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.ttf deleted file mode 100644 index ea4ca8038ddbc766263ee5983f71442b930d50b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49936 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 GWB&^yoY;c^ diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.woff b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-bold-webfont.woff deleted file mode 100644 index 35ca59ec5e6bb87b3418d610c174b69dc26b4629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27344 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

        )U10Nm)8 zuxVQHAXVfWfj`-CBop9Y(~Q$&3_Xy`1KjIW<#kLfH6(Yx$50_4GPej~;l5}#S}4YR zKnlD-pAe;85A2E>9zO{dxgc{gw{&5E!bwI`sc*=p$}C0~MRXX8nuk2Y%5$)+=EGL+ z&%m{vkJL`!!kaCxEseUCRi>Ep@XRyK-;5A$ceY%)ij?cYc^d(BgcO)XWg92lDaTbM z%e0P>S?n9}=1T=Nea&e)XcrK)C4|1$#_donoER0FXn-cvV!3<8iO{PT92qmdulp;sc?Ow1pL5u0m1 zk&ogOuZIyU&LKZ8%peV|Y&@=W$XT02p$H?{bE9UAtJst*!w=BR;+7C47FzXcp!S6e zlRPT>NCZ_|&$LU&r=bFk`Ot2A&|((19Io6&9nHb(uiatyB6OqfRrMU&LNJa2cg%Ww zS57L?JqvS}N}3lIz@?{KqNF0M@Q7eA@d;HRT(~m@Bbl=8c|EA_8X1mSPZp}yiP9E4 z21Bl(CjnMm9MUi;=9M%@4^EG;9($xVB`>ygyTpWYgy#hjG8D;%yJwDxQda*)07+TF zCs?&xQ-rza4vgq6AFQ08jfMAlH@kOKfIJ6Azu=2WzBA5oV$%L4;XqXz1F`_AY5eS` zOGV^BF>SO&6Ju=Q*IWR5#++E@kqj^He6JeCJUONm0iRKl5nGS=zbjMwrI~WJnZB@} zVx=#=rP*_RAByzwdzfCFc^|Lx&!0_U#+FdlmL(r`? z<;ef35r^+C0gMi(;%xJ9-yVnBp&>!QbkBbxh^MbrXQ5=QOyP)}|5(%+C(ke1l~0%~2X=cv|aQw;zK%nG$P{=+d937eLoBdSz&%x820!sB^U zGQ}4ZF-3S*tumT@rv*bgL{z zXhX3;wL)>d6rLR5?PZM~EV^GtHmwvj?=ZJ>nu>8-Y_%8b!8CA2pBl6L+XKeRo?aVv zqVHLn{}7u)Za|^(%3CGAI&DphDNDCJuMewsk2`?G4+TkOqjm|zD`e1ag^tOaE2$v4^H9l z zo~8w%%^I=hJ5h=DiqcxGj*jNMXXco+Wl`bggeGgR$=Ne_BMg`ca`EbjybQ>{sKNWJ z9_b6{6Ub=yOY2KNO5bakVBplE6KT~@wK+L4YNU0yRumgK*~tx?GIPzJO(MjOM0HmJ zu_YJ=R(b6acr&Tj>Kq%oyAV+s%u5Wh^Jzxtg;ZlCcvk8?IMUM|W71wq%_opIZ+~w# zSUDJdayD`~q$7|Gc|A?UK+Yy!q zHRsfDF*#8pKFN1J7nwcwKlT^L!#f{Wgu7!t0}G*F5krA< z`)c#qk#rbr2^*x;^EFDc7>2%EjMzX7%=T9B{!riFI7y)-9Z2}DES53ce6=Jh9fvxq z010zYK75sWV-2AD@)Q@!$<$Ce_CDfIX2=6CM(%PUMIM20KrQ{z z53v`*ibF+!L$pRm&>|PTSt&zCnUFNqZM3{{q8PMF5i7Q*`e8m1#Z=C#tsxK6%|XD^ zg4Un|4kPT1QlXF#2XSPWn@{h^X!M)YBpGtZRub&$!@+saN;4O9CG8{Ts+6)8@<7jr zRH0B=+wH-2nm%CmS1rSEwE#ISM!;ZdkXvs&y}XCyd%)ToeD1L=@t)Kp_rZ$bz#Zcj z#Y27LcND4Ug!nKZ$LVy>R(j?vqI-W%svQk2Q+B>Isno`>IjJr#e9Jy%)tM~v%8hK4 zaO-rqVMnbaiEDG*p|}}=^DNK4q;Y8C@Hh(gAl!V|h7@7)F! zO8gE_e|GvSd$mH{0^|*WpU7%CKbsP9;DY%8KareL-$EmQH^+Rhg9c{I)D4NH-#f7u zt8x~#akF@jWhh`tYlc(meGnJ++#+rC{?&$%TS=O>!IdzWa3UjV&@kS9D5RsuUeO_P8{__o5TvDo10*UoBE4P1?o;Pl}(I7s!aTP zEEB|P-M1L=mm;{NppMz664U2*AbkAV(^GtuLXfz7>2Kr3n8zHxvpy&TZhC~DJb$+* z+jwUiWg*!TLJ3W)PkkKO_7Z)LCql|BN1FFDeOj`7!^1uzkh-~zpqKG_KuYn2j4+O+ZUoM)B zEP55#>})S45YVP*hW_Nzj#YS!UU;mzP~IpDTGVixLiPv*74cj2c2@~+9!P~AMt!^- z2Th36RWek#Z97M3c46|?`t9xNpqNA~{cBSQkQ&++APWf9+h~MW4rT_q4eg&?{%slT9^%BseKrTuy1?WQoo6P0is`Tht;bo8eGkVrU zq+p(6mUE}3d;XM|tKn_&!1%NN0=>{m*`r#^!KKI&7&TV*d+{Q4$tZ`o>xT?TE`xp9U+!73V z+y_Zinb`Dj3o5OHfJ?N3tDPGj5nt=h@KyTL^pn16+pV-2;fBqUbBgiyTYsxO73VI; zNKX6(=ADX6^c9uT1zN#;1_R{EhUuF1zJ}9TQL3_S4?u(^)b)2S&HU6M_E^G))Ls;q zX8n6RxZmkM_hFqQ6CbsA=#>n@7safcgbx#rj5ylSVG2DWI-+6O5YbEM8_&q7>74*r zA*aEE9pcDW)th{z>-+EpC7SexCKp=bqk`>aB℘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 l#968dNI+7hfDw0OxW;f - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.ttf b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.ttf deleted file mode 100644 index e0b6ec3303a8925cd381f8caa40b041c42903afc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50224 zcmdqK4SZD9o$!CpowvMBW+v~1z$62SF@~57Aq_7E5krWS(iCZ=lp-QhTVIh<)`zl) zh)5|Sm9mr~#)v7UbY_T1DI$n0OIgcW7FkMJWGN4(i!AFyd6ben&-ZukBm~sj=lSes z|DVr)hF|8+oqNwYznAlSJHK-=lwlZ|{BasLH#AKA;(hhMtS}5UoU?t$jJ~}=W%7%m zTKFCuGvP~LnRx2(qkR9aVU%te^OZYC6*`JThEa9{zd!q>uT)ll=kFfb%=hhlpLWj! zcR&2yyr-@h#*KO0^SgV#^H?zX?zEU;lwaic;WHn;?}4v$RK8*uH{EO)=DqjbJ^NwK z`wU~y8a|Wm`}Vwt0hb+b z@&2{reP@pIZ=I{1+nv95JKZ_%o7|J#kGUs%nmw~TPkDBG{yup?^3W7#%BYl<)JIc0 zQh%G~OzV?2GToi-OCOXzn!mpErqti2e>eTP^ho-nKjz+bz)yhnzzf{}2KVd%-sJbU`2H{SdmI=*@8_=Ry@4La z0F6L1FcD~ppE0I#-BRGQdi^QaZ32D%cBR zMz)vprZEyqO#}KF1LAE)MSPzzB7V%U$8|)HtBGIju^llcao-bMw+MI=SPVP`ECHU5 zFE>7ITrt}FtZ~U09MFD|F*bf4nzzHly7+cu7)N6@7fu;pi*KXtcZ_Ny&~=PaZeWz} z7^AtfA-)Id?PQdDjHdWrV?zA6@nxWy?_c3_BEQ|q=OnIgK?CUes&=^w9X(<-JWc(q%9!*gUwFbbQiueKAJfPbg%CE!V-f+H;gsM%ne^>k>a(xl1 zUO=`l>Xx41zD2;3z+&JjU zpVIvf@XhvrYv-y+~iU@`C%umpHIzLc4Fl9_jc`F?`=euDXag86=e`F;X9*@&EML{2s$ zCmWHIjmXJHoKX2(f)D5E!3S6FLP{Ry`Ypyx z`pealAu?10R}ORiB4p?hxN?XqSHhL!TwQC-iwiFmb;m(I}<^nD5 zGajIwC%AtR@FcJpcnVkoJPj3JpsiNgcnN3&UIsP-uK?}9Pibot@H1dD@N*!>Jso_$ z3Ty*j1GWP@fW5$5{CWPk3oPuBPecDd&1hrL!Nb{e;C2Z*%bYud z^qk|@Gf=n?E1n$R4<%M%X?AkOX|9;c72~0*Se|9Zi`?~cd@>^sbH@sJGJ$Zq#N28D?qbGG1_OKEpJxu7g%f)i?^$C$ct1g#i-0GA#lTa* z65wg@Tgo**r0?f})xeK{HNaY+m1|xC+JKjVjle5FJMdG+vI+PZuo?I{V9$pFXt9I& zuotfFfNMM8+77t31Fr3WYde?^2bd2Bm=6b-52Az4Gat?~AI`wh9dL6y+}sW~7s1U% zaB~sd++&;q7Z=n$2SpDu`n~ixncfa#KYY-s1WC9N`K|^A1HCP96K!`};jhwHi{|S- z=ynjjA(DF#dYytEN1?|N=y3#k9DyE3pvMvDaRi({%`(q{{{tDt1@QeW3w;`VPlNAi z@I4K_`@nY}_#Oe@6X3fEd^dsPK_dhF+QDx=lG1_nor1fqaCRf3I|R-f;KV#QF%ODA z1pZ6ty_VkB)8ZDbD^6*?Z!yLh5oB4kaf6XcuLH0#C2;&kC|nH;28N(jM#ncpsa7Pe z4T)=|&*MnkCM0eX6l+D|HX(6sNZckQZZn#92h?k4Tu`6yUxN=*80*(LKNain1pO=m zo&**HPXSASr_ljR>HmjZ_dKu~_z|!MSPQh$)=NMe@G`Iwcm-$&e#$sD0Y3va13w40 z7^A`N6q2?H%C{nEtw>rclGci(wIXS)NLo9TZ-?^jP`(|?cR;5OD8B>Bw~BU!k|{tf z^STZy4@Dk_^Zlzx*;`m?UbMX7-pi7FG(RJWm4;@Bw^)$jCs(#{<$0(lK3Y4}5lwv@4%(LXELZH}mjmE< z+DPWC_!8T>cNf2GPTcz;SBPd6PvI0kVlsa-1h4oyG*2sXv|saGv`lS$4ZR-*ySEd5 z;8}Qn5}uz$%UpohXW{cnX2NE)#so0+^kg^9KcuCT z+BzQL%Dr55l&dz;T8v-LFoI-y3TVC^0Y&S)`WMU>oonupQU|>;>MU%_HFQE^rKdeh>UB@E&7H0=r{iC$mGWt@x>% z6O=hZ%bmsz(4hmoFM;2F{#^D{!p>D2-?<*d+VA9?nLYE zMCmCQg4lry7!*(!~h)A?<46Pdj({{9O3~bxcx-mH1fj-)c*4=`HZ9^w@AZ22= zcA$0lp>+?z`JHfnC!F62=Xb*Sop4^pxgD*$3$42ot-BMgyA!Ru6Ro=wt-BKnc0j=n zDA)l7JD^|(6zqV49Z;|x3bsSRb|}~m1>2e74PYo*HwGo!p=3LhY=@HVP_i9Lwxe~o zpmn#Pb+@2(x1cw7pf`7*b$3GLc4kBx5-}1APGjUQxW8Caa5!Uq0eB0LIO=Wm^8low z0;r|WI;3D2@?>kU!{EFJocDn99&p|R&U?UF=4VW6DA6>^_!9a+{J=e025oOoe4kF^ zF_M^@tRRzFq}2RzZzbP-7L;SOqm!f$0h)V4Lv_*DnLU4=e|M0IUF> z1y%yj0jq!?g46TBYT!q}8elE(V{lss`~+AJyZ~++xc)`P)e3$u0d2s`z((K|pdI)r zzi$G525bg?4r~E_0Yrc(5W|XX<+B5L71##625bj*0KcN2oxtnBEJqV+dJ#UoJh z2vj@*6^}s0BT(@OR6GdAo9JZ|nr;i4ZVQ@DEYUfm7%$=!Uc@OZ{Ryotq_-jH)LQVW zgGWP=A&GQ{)2nSO_QU^6=(UUR^&|M&2~Q=Gm7K^Kcq)I7?mNYp zk3gmK%!NzLgGQf*Lo;>23(IpS&2|S1h)^t?IO5ItSC|Xc_@7zN}q?)=b`j@D1Bbf%x7qK8Ss5z zIq(Bu1@J7e5_k?+1-w8%8~A*KHunH;@%<>D|3W**!0UG$ALsb@9RDlu2k7jeheyz3 zHAtP<{$yl1fMkTwMNey=dYJwt6^iTvbIF=rV6?j!?Jh>Ui_z|4w7VFs^hD@cdN8Bp4dJobYdA>&5)F$ivC5vkN0Ie4xOWDFaPJB(6h{#2tJ{!BB58~5-Y zK~~`b`13IDdSf2%k;Z)9w;BtL<#6#i-d{3)NDg@dIpm)kcN)Jiwj19xc927!Z5%Ov zZ+y>q&p2f~W&DBn(}wB$f@GD`wtK&8RM4vtKOMgad>CI9zYsqZ$7aUQb95qpn4{Ia z$%n*`V<|u96+c58r>|ZVKg)e@$G61W(9`-wyN7vSxc0iMcXS^?V_wLZ5x<0<{)?~p zN&0#F(=K5q8u4>TL*m7Cr{YH$(MhpS^YMf6_V~JPF2+0K`|&e)byKY8 z;$8>LXG1s^9~eIduN#knTF~^cxfVYHm(L^DC%FC-Jc4%D@v?VocqBb9w8bYz4}Cg&WLwMBr*VM3 zciB|58;h65z0hYi@6yDXj`-yGl=%F3C|-nxHsW*Q!{TA&bxFLcX8;@s$F9B@d$%0- z$awd!woG*Mkvp%s0xQz%#f&@%=MFPBj`TXsoM5J$)?8x+QSk5nYhQ(Itc^>)GVzMf zicgO}5T6l$2(77KXpQypRXD2>ZjGnt zziVmnBC~5bXS95FH`~p{?(d)ViC4^vjL-k`>sr45KR08Dz6I}c{vIO_+UteHoP<-o z=)*NVwCQzWufuqge8G0=*I&b7`^u|-6FTZ~S~(M6a`n6%A$^Pf+BU`3z+Y+SSp0$O z+G&c9W=5XtZp+p_VxvC!!hvoRyo-tRixOzlSk*nXXJ^HWVyYNx8WrAND8TnZ>TN`J3*~e>p=C@Db{(sGQuJ7p+ z-}CXg41C|~U(^ri*91JK(Q+j6!`v)HZm**=d^*kh67RoYC+y~EV;gWDEq)2Tku8s^aR=J@nP3+N5Qu(tE=fY%aZf9?zI+)LBMBi%k+ zZ>!(kh|C+Sr_J6RMbh_nYdg6b&3q(Y#oCnC1Ks!YO>0Ws4!YiciMMq1)!Pbk{UPuh z9iPb2wO47)P1I~yvF>|&_s{jrFa9zD{=UsQP}%VR{36=q6>rgh*CTUC zo#?G=sc1JZp1qb^Eh*PZxvkyEK}u_Fv_UIEpKckpTS&Bn_aHK9_aU-<^_8%L!}#?Q z@x;aWM{&sw^^*Rp*M8=aBAPnE%1Za^>QS+*iFcpA?lX%R>)Myp<~TUz)bW{{oNkgn zO6FWL(HXg7A~suZWDv>qe)-WTnMO7do58wkkm{hmI;IP9T*Pl>MhOwz4SZ5!1(X{% z^}hX6j`Kd{T<=r)y}$GvJBTP9iMK?V@|Jp{#fiW6b$LX?HvjxRH(ovJ1I7FFoWJ&< z9})A_R~}_0ubKE}f0uK@SE&T^07>-Q`z73BJy+X=6fi92UBpO*7G5A3=nuBJ z+>{Aq83ny>|CHm@PdV57RCdpoJSxw+-%=H3V{z@@Zk~#KI>5qyCvk02f=k`p@-klg zEjY;A&^UCT75U9gytBYMi}t+G-G9bZUfB{*T45Z zRx=;H`yNdJQ{UaYLeHlqMuCe7{tnuI%$P$94sej!F7qu9uzd+RFTX#|87I>6J!66K zw}!*3(Px$ zhCv*tmDE~3f{e>%HYu8H-ejsir*6&$t#_^HmK&rwMNhv%nSBSTwB-cS{45j_WI5E!|`!l@vc9< zxBtC2-+SY|UGM$sz3uNs-h1V}Meo&~d^0E&mH!tn#Z2wKK?#lmyPRa7h59Ht*>@$+y2_lU%kG|cyz|S-#qc%7a#uCAHH+H@$_1{h@?&G)-#@}ne z02S!Ro)V5_|9GWhr8~gJ=aa?QzlnL+&4vw)zkDIe0s{1f`~ygo|~cr z^r?|Or;=_8_=9zo6_Mndg7c-5w`e~YaSR+A3PzkIO%Y>4%QN>rb9Yb712rRO~K!4bkc4LRz^JKQ(A(-F`;FXH2)7kn7T=XSxnP z6CCqQ!`-20g3p9>ccF;U+!7hdmEb4cMn>K%U%1Dsdm8a>UQtm&@ZD!112>IjYa(%lS}rN$t2hY<^aX*4Sj zl*&MTo@{q!`PNkZH%LM@0Vv zxYScpQ#-IWCpUADs?Fk~B;-`#pnq^lX`9+mmQ&PN^ilHS$C~!M@(+jl2MQYtt>a1S zmrQsk*0`c$TyD^6SK(6C{M1WMx0+~Pw(@WDC3WpDTGn=ahxtc$@`*m9vy#nwi6*+e%)kpSz(3xRkm}5Ew4bXpMo?59DXxs>xM5jk zG=&durLZ^Rhq(iUxzQxpndFQ5U}q}e;H$$I&El{xhkbp~0Ehj7+(2h^pk{WY1k(8f zgAN$cfPc^dVgHEe`9BH!T@jxzn(6u25y>0`g`=rS(9Z3Giv9a?l;1~4TilPstXxid zQ-rh*o3ufHmb&xTM&fsd81O@7iSpMwsWB1>8-=D|1rUWi;WIu-A`e6C;eKq9_3MHQPA||goCxp zotf32^EHEm)7HgCmAs&a{@ssXQwws--Ho}os(w}0#U<8m%UZtksLG#X^@&WL(iHo? z)%TEE85`XAH&dT_@dfMj#$ndt5${j3F1=#CU!zj256vl7+v}D(RjC$lm@;<6l7(kP z4=T~IMyJ-X{n6fN*bawQuL{izieCAudPkixW$Xnyo%Lj zL(S^l9{s0gcej^0B;YeERk)wxGeb>on144d=HB|?^r~>&*lY&WB=z>QE9&-G`PM3H z+=2xfzeSD|^Ned5WBjENNvn*cR7O3H&WNj04;Y1JR(B-(3=ak+*%yVkXmvpVLDr(} za*JrYUAAZs|J}I?5p8e8<%>AcXKr7_vs+)7mMRyfrr8(nE$O~6%@;}M!c<=*Ww*nK zI@8fcTb-U1J_qS(kt}*gAuuWI+KC$8y1IzR&xwdD5H;=TP+MA?o0;n<$}YrjAu78&u31-(WQuWvnv`9X@k9Z4^rzQI*swAdN%~g|uqkb&F_CQT96XF|+XY+eNk|3Oi@C zac||do(bo>y_BBOFa$@>FvKNU+uYV>%lYWIW$tpVr=6e?BbbA5+O=VZ81HtNy+=@s zrW$S5-qv*>-?g~#@_ZUFjTz|XEPM?=R`@m}MnH-N#mE*`MqPpmJ_Pg#wbpvOI9 z{;0MOHjaE;eXstNGaE-P9RIDFrT_D#dnRwR{=IpNxmaypH=(|M!WygDTC}REenjI+ zwZLj!P(OHzN>?AK(6@%@G`Lb^9?XlbM&j%c-k0b_#kBE=Ll zJbW5pe8Y$p3zr;8om&k@aZ+sApom*EerjJV#724SFAT&di= z&S;5@I2ji=>IyQ_6n~_!F2Xl2rtapddX*C%AYMUHO;Pm_UrDfg;9li%hj1o*1B*+S zq#ga8ni5-UomajYd!Mt`tPiK{RWH9@IVvk)>}!aTCdG?pvWKHia7wC%vqER58($RtDtbKq zT@*z$4MpIoj-{o`&uOAB($nNHT{t2-KI*hNBCe|nt8T9~^w z*NYa8q~l(u?RG_d$+(yP-9|LcFWNON-N&cat}2@25~^p2ui=3mF;{91qN7<598%+R z6}zE*Cc4aVi+F03pBvoT7tI3+!=I{=$n+WE>i)`85;Ps? z1bh6!%z#UTDpc(DJg!pCuUS=<)NU<3Vb%@XH$miTmozm}*fI zyzbEf>piP8KeyWY*5OXGy=%SNqo%f3Ne*}u^Wqfz@{lF8^?)d1nYRRY%v%TZ*6rw- ztU9_gL@zi*S)r3vsjAuJsO>sF#_Z=Z8y5e$ysz^>C9>(Dn)19e%$&7PKzL9)Ig6!O8rqUhBi`xdkS3{^I+|x;ov((mxy!k3=XI@nX5H}O9!da zkQXN;CpUbHV(vC9UAAC>I&oS#mOQ&+opr&gv;H_iskQ^Br-i4Ezp!Fu*1}~MRQ@;>wz^FTb47&7&vfZagbxYCn&dEB zaZo_i?|(JP>&VROr|n86en-Sz7wspKc0C-g>&6rr z2sN?a$GRq(YW-nJr&r3lj5@H zNunz~8<-Kx9QR)NvEyD<)zE+^+aTjs#s;Im(`olrTa&ElZiAzUzGn2Fs8*;I6Rd_N zjo(DWbc}Ls*0~ETm5DPF>TX%sez`0sZ!^>?qVp7%dTf-;JbKNBe^^N~XUrnvF2H zh~PvhbSP%#Ar#sEXi}zVn1Vu)gKPvv+e~K8yf{H(V`4jyjv8&=BGQ2YS1+p^z`uc*qE2DR$bw;WX zdI`@a=*T0C5)J#rRfvuxS{><&HX;B0tE0sPYsEetq`8SEzRU&rVWxsvMbz0e(jVx^ z%IrJ*cG0rM{;mGHp^b7_5!mWTPrF&qkn}GwL%8^k8_>x4{_sf7-dvUAL(luO#Ru~c ztd^FP;*1S))c69TlS$;@l$q58ctiX(`qHdGjx#(k*X=1DP^xT?tzMPX`bASeu68(D z)rv9sm8Bz|o0LQU;obs=9Z5sOsO0`b68Vmx%Hzft=8=6M^*U=HPC%v z`g!a1xoY&ZiV1UejvSGzR?j>1qZB6*xplwQ5VBUztEfy1^vNtQs~VqDci%t$0Pi%p z%sbFx&0=g}I3;ap-69nlsMe{6t+`f_Wo_O+G3&N~y6b*(k9D%8tl*Y@{W}kimoro$-=0}1K9bVw$dNOb+ zd{HMX5C@WILMIGv``~eH&kbKh?dF0=>h2wHzMeSgl*mb}rnx(k;@j%tAqC}Jv(@cM zB}bGbf8~6#oOisYOqW~M9mM|2i^K!5Xc+e-esrCD<&1D|gjiOd0I+4XK=Uc*7C*+tzCb zA2NNa@tu9c7L_)Z-TKXK+pYiH9tl5Ec6-^h16rnp))7tX9AoJ9l+F?I=4!()=-OTJoyB??te{1(bt41As=*5<@+g@L3 z)wtHqKKLKjsmn*_H+*ORNflCQdl?Eeld+h3EMpQQN$%#k6P~-YP}>TfXc?X-Gbjm_ zwF8};Dh_nD9Wy5aWjjcgK)EP;r=y|EX)f$qU|w;pZRpzE(DnU<-lt#3hxD6lj7-cb zEoahal1s~3k`N;0Q~D%yPjpDaP6S;?<RR(={u((7yZZ( z#QKU{WFifcs@KxsacOBt@9ZE`>O#VErRV;-=M21x4BLA2Av7Rz$nGOfUpB#7Gzep| zGcX(}uD%$KNFRSB8C#N@iRR3xi{!E9RToJPM7-L!2-FTK62Emo&`Z)QH>aq&)=wzp zcZP!I;>w}3)rf6x*Sqm9wr`&{u(WEL%3O2G`bRb2`e=uB_?)?)%*D*NOVb)_Cht6L zZTrLISeZGnp=)wjeY=~F?V6AEHa*FH*c!?e?r^XU4qn<@vbmTF7tLxiG!oE?qk)#{ z;U5Gg)gejvolTCGrlu=2+|^>XU!G}h?!xjX`crQDbFfNoYsFsq0j=mn+1Xh%N$>A$ z5|v}$J1~B~TEe{L(%hRW8x~CnRm^X69{F?HhGC)7B(FTzM&z0_x~A|&~uxwWgZtJZAolFB39r(+L& zx~QhnG!cp?@+NNG4KyK{BA7W`V8-f=mS2(JolWMiAkpTl^TTzTw!Eyb>b4^8#Q2@z zXgUTa2?Ime%8c~FOK)N+C{t$+qaGFmqNYZ2cz zEwqyEw~`9!{HUw!@=Vu6{Yfcxw_L4e9H}x-#T#cest2uzD=gW8Zc8UZg+z&^ONdj{ z2`!_hEGWo4#UzPfN#9${OLN2XBMh)tHbRvwf~aK3Vh7T20HE0`2sldX0Wux4EXw)K|DGi z$!Cvy@p<#X^Y3?kZ}y0r#}AzGx*G7S83Xqd&YYfJW$st=)VHnGSGufU?3j*Bebd_b zZ?WcaTh6>n^f)Fq8Ty!7&K`n3WHeb3zd945e$iz1ywjR2pocBmGo@P6uJ{3Zxow+O?^=8G->izR56y{c`Oep542!KZ znr4~Alaq`XWmI^3NS>xyQ21jnb!0=cY@fEwLNgXKqJ`PGf(|n!Jqe<*45SrUJ~}O$ zL{u0F`lCWYTw)=h-)DMA#>$#c@gVhSlzd=Wq$xISg=s!_Y+mJO5!702owfEfTBky4 zV4<4)=BJZ3L0j>?(ufAXcI_+{FQg-t4NEeO1;cDxDj;vVc1UDB$3;>>mLYv&GgGjc z-3X@JGhEz}UPO1vJnuz!^VmDqQ8jv^wa3a)+tt_GU$q)tYxf1%m}}Im zSgSoxW|QAJ?TS$M_n;A@EDO>Swf2#awII3Ej#rR_h*L-LX^fb)Mka3xJW28C1*R;9 zTgq@#WXAR>V7UE>SvF`f zPQ45_V30Xm?O48lbh7pST#anQ9aLkLECc_^l+l?v0l4$Gs8-j%K9KvaTUap>Qi za{eE>9eS2Wl=$vDMzkeP;?O&G%L0mfw_~e`lDg`rXNseat3IMh&0nPEH(3vU(5(|0 z+jt%qw~VoQjbGdJh^3^aGZ-0PjCQJ7SZAuhhNNUYM%yMN#wZkGZ6mR`vt!TKKm6D3 zF?zelc+159oTpDZ$SktHgLNUZn6`Vzp3U|TEaVJ|rl%$8w4+|tcJ1DA%Znc#mb+Xm zp2~7ivc1-W#!Uk?H8R!ININl6Q>Kv9HhP#m{V&8{b;zn} zQJYkIi}eNd4=vVYYofW|Jlr+IT-R06RcEg1dVoGc^bw$sB&znb1=19bIOrgmRi$^M zZb+H}Y26;wwuzB7>;ptk`ch(IC#hET;v}nLERI6ZeDBI{y4IMpY#b)XEeHOCZBsb~ zk6@NFbWWsw)g-KT)4pXXa?3~G9r*sUETSLes*~aXm?8%PtS7MH}z<6`H zb4^vlvwyy?q5*s&ai=-ZWie+fb(Y3Oijgc0^&Z_KO=g5FnD)4&$m433DB)U1)Ew)u zs<`65JnG|TMhPFNkv7k{*5Uu^dy)IR&Ji{8zZ#KFX6kc9fDEG9Gqk6l093;FA z#^I=pIuqj{4x_drrnKTvG7d*iwu)c^SGlM~RWOb@*0LS$?~MA`O`GlJYR4J9UXx)Y zmTE*Vh!&7Zm8{y;BV*N~W|mxEH&>gnuJPuqt~E9vj$t<&*d63xg+>N~60_YWI)W%Xw1mavkUTpj;pCX*Z% zMnW`>`^nvR$`o`)oXlJYB_|;lGk3slW2?g%(nTOD>flqCdKAjKjLw9T@JaIe`iM=* z3`Ft}-_-v2N=AT;7^Yqp>j(C%EQPDX!F-jI>nSe9?weUTk_+{_+|!r*P%VDs(K(0e z-6vmkLan5g&ebE{`NsvLX1w|jL+h+Xa~7-oRo=31Et*@9G5ucQbaw(69IQ+Wy3j&A9D3AanwM;f4RQ&kP_y6R4 zY5d;jm%Q^Q*XHq;kC`o}vPNa^>$-F}b5uanX)gWFhfcDdO8zrhEUzRHqq*JP7s^4Q zjxAW$>Q0LXkRMi9F;Y=iALNH}7o7u5W|=kWNEdR+8f(-*S;_##AHvxq=OLbYjn3}X zcIWMM)^6^u59j<{W8<(RiyQAB9UeEeV#1+E4?V9gkZViLQztH$O)9-LrIzHI zb!<{uK}|t{qhJ0Xd+=DR>6dHVo$yst7`etJ)r+Sjq|9-3b_6^bCf;2@v;%9UFkW@)ax1*FqKnPo!zJTF8Xe%s}oOjoDs_u z>ZeFV;%4YNQ|k?Db>_nd!WGTbRRsYAHN83($P}goe0V~c0XfW+#Y7xaQBpNw%3{K~ z*&+^wEZ~Y;H0%eDKDTpG-2)TUIIClfW7nwpN1u1sJLh#gKI+OS2i1pYpt)AAm zZE`b`$Ws^7g>GM9IDR<@BzNNUOSzjYCIwNnxs}nuBA|6bN-6j#!Hp@=ZXK(9oMc@_4uf;Y7v5G;>5ZtV_kX3Y>VKj+ws%BT zrAp2V)vLQV9I}dk(zH-5Yk$1`qbVc23slX*h1S8gISmCj7tSi2UQ}nPNm*`p<2Y;W zkCNt$C@OTOJYuyyzjW7{2j{4~W_NvyBVxTXca926DL?Zcci*v|d6-RgvmKYGhHYi# z6J_NSa=Em!%F!~LZ7VBCng;z+nSHr@rV)0LVlbjU92LD}D1q^iFzLmde8OYBkeQ+U ztz)+CQtFLGjng+a$11DQOXnu2-&p_Db&eFHcPmQi%0d~JDdS4iGFxTEez(y3CHi$>b9BEw1u?LP0>Fd~7piP&bRE51W{=gKh2APL z9<}d@`ufTm0Hck0_!CJBM~k#ESCLZ9`4XG+OfgA?_vIVKgc7Rwp!*Gc7BZO-f=J)Q zbYNC(kUAXE+eWtKn-W#Vxp5-?!HDqa=AM^Z zqU99>$K12AxxKvHX*8#VY9B1W?W*vE^Ydo>DIrMV{DLd1dw8+|JOfnn_wYnxsV#E4 zsE|yJpJ+GCaKgBVU6Evr*cFV3op}(2Dt`+NT>U*|OS5-5#8NEj(BhhsQjvb7{ z!%S;R z$sfr^q}N4q{4r`NwbMcbo2_~6Gtq$fUo1f<*xWj1*t^Z!H}3!UWlyeuWZ#QRmyVBB zRa<4QqnO-}yN+5`U#q_vDm<<(y;EC2w9c64GUmq_a~gYtprszOubYb`pt6Vf0!1$5Pn2}A)NyLp5JNWiZRJ)~jnBWK z)b7a(Uuxc1UiL!cnKNbuj~KsPW(LM9httYCj`nhlPP6Bhxd2<1#x5&cb6usTt{C~` zy!Z6dn^3AY+skS@^M1siW=uX4;Gf^B#kb5d)kB%_gM#*=Ov8}-S?;QI3uDzhsDpC5!ZNp zk}vi0MTK^fn3d?t)7u?MW`$T*ZnQh1iySj`kz$Z6Z+)El)&c-iMmQYt~T zZ5c5?lEfk9t^?bIW%QEAiDW`WEpvXY0yD%XWjx&?rX5ozM#&nqoM^Yk#=tGH@ozt& z&Y4+V7pxDrqR$-nU(q`6H#V*6vD=Fnmxou$dBZBM!fYO zBjm3CiX2bVIOWVymE%=qu5ymE{(YHs+B&^V6JgVpNkRz6>MQr#ykgDW(EvTJ&GFb` z{kb`wIyKqaI8jxp!4s{Q)Ym3jzp)PC)*G^rY#Elp-&$y1k4{`dAIUt4R!38jBywt> zkO!&!bR)9%I;65G&azF^%^|x$WUWI25mq8~67bXqu5RKdcPH3JxXx|WCt1LEcv!J# z0bkbb$pa=OOJ3}nq*y33R6kBtOjMQQtnzU`oNvp?P|MSDv)3*{VBr!x9=}8+GcqczP`!4VNcIV!W8Pn#>nU=9} z@6M!WS595AV8OtF^A}%SwLJOOBx)Nzo;kbksG?@t zRhLugeJiqD8DO)PjLRiX1M1Q1*IRQUW+0LzYH~kN))%^xn-bY z$>BJdIc%_!AR-qI$kdWlz7#uCHzIKoSf=ijHl=sxv9og0u&J zq~v7#>tmYdlsenywk=-x`u%guoNHQ$2$Iy%gKqYPTnxBJXT5BFdqtYF(PvtgGFitE zx^Dvg1JoY&Wn-fDL-h86JlPNzAy>zCIH`7_6j~gGlte+IH&I1mzAG_Ro|d3ko+&{~ zUJfC@sqB{s?GIm+PQrBybTSDDq^D-G>g?$ zGukuS8_eyueoL8K0`5`yKRkWUtzC`5TL;S6O=G<=!*RmVMkcdAYX(B`f|O2*7^2BS zab__4O4zI?JM)Cb87y2#DO@3Q_%+#?;mgcXkk^RzXLac{<8a1wJU4#) zb2ZO$xMGMLn*M)#@x^~5WL4}IHmHSd#529$&IU#Nl@dz@SUqE*6j#9$mUUkWs${xL z4jxZ6<6W7jUMez@NuFj1vAy>0#8`$`zGXmqHhJlt1zwgjb(TJt;$jY%B|1xwd*dN( zE*TeeV~y0MH%?S9sr8ejYSntYKyUG|rl__8YmS=gYV2BK&g*JxDBF8G{Frn5-ZH&b z&u$NN(q$b_^8aT@W>{~vVX+9Ug4QIZB%;BGo;4KHAm0Xy^D+>BD4#{~SYuN6Xk-@q!*+*}NoGa&m z&1kIhMk=eL1$;xN)xh&|H~j~TsO=kwJ3lft$?MF_FT9~*P<2=)SOLxHxFoH}A9&U2 zE4X2hoM*6u(JLjT_Ie}UEIQpO`wlWxk55}0bl}vM4B;0vWXXWi1+@i*la;z};j*yv z*mUdEV%D%rv$C7EZJxY$nETWts(=lh>ozy8P^0TdsHdz0b>`?1kN594dY!7wcHi3P z)Z!^azVm}&3qu3ztmAE*DOAdwb4S(uD@SKk_P_uAmMT$S(93WYu(n|D$sLaVvR8ye zg%z>Q3Ab0yB))d9dL;Jx>3W48mF7pK6#rHE@^_Ka*^`Lc5WvS;>PS;{pvmwPf%ByBum*@I!m1m+LqmEp2j;jHk6EwapIw#@} zNBe-iuUd+;O=??{P(WVXBiS)x*Zt=~fIOeXz_PsKg$7dhpC>7gBuRNd0}ok{h}RAS z`mqg_bzrHliYAFQ$kdWpkNGVLc}j0lq(E>jN@R6{^dLr{hWeldYyT-+d&IfCtvR>G zIjUme?D`3#U%Dsw_u&f1juq+N%K9PRVLo-|H0yjQtXSI2 zZL#epw!NJiA#A(7rGWTDRF;8>P|}&b(E4J%|sG~+zt#sVoWKM6eCaY=E z-qpQg)N1$I35Hs|MrQl6!zc1dsV%6C%DO>;UN(; zQ|OQIcR--SsnV0OwZ^$#v~e}0Fx!(GDh*|GjP)s3pDx>JyXHOk-NlVdTH6}x#!vc8 z!M?&K(dHSeg8%D-4^&0X5>}UadcaXvNL_YGjecVP9s9wR5QKF>!`^?F)U(p(fa+yt z$Q8QvR_25%bu4sDbZyppqVW^-)&&egQ@ow-8X#tXCD)QRoIINDkXOJIg)FTtW5DiLd&$eV* zQ(*PkTb3b<(%QE3z$m>(mFylqp`?C@Y*Gk2Y$IAzdyDGc371<<$dSQ9O4C1#E+2J6 zaqdd8>bYjiTxE=bO?Q@(7o>6Nw7Wyx2wHPH;THz*?!*XL_W{Rbo+{fbW5jM)0c zeWN9Bd40lWO4muj3k4>1bs3U}mQ`V?XVo@01>Q(?J+-1~?3Ko+P4#sspOK86SID@X z5s?B!kx;$E7;(`NL%4_sOxO>X2o*OUZ#6gUZ?X9y1a=8A<_Rj zv&=ZpVXu9>#6pS3eDtgrT(f~zf}wTIW*PfEDAl!Qs1D|$kKL~lGB_}X;wgALJCdD7 zo`h96x=A2_7G=z=phqQFEXCeBwsW8#J(3L5)x)wKsa6Y6wrIf6Oy}f=>FS;bZ<{^6 z-Fl!dY3iiN+!4)*x`wIDu}9p^*sp7sJ+v(_1|r4S{K*w-jb-5NaFB{D%9d$|O?AaaEJDF-o_&%XswtY_2#vUMqD)w!)^8gh zJJxi^9ZlAeI#+t>*pt91i1wHKMj`0jb9nDGSLkc;pkuxuB?s?E)#AH zt_GX3!E#tu&Y`T(MMI)EgceSuSSrP!jjER2gz#QPYAPei??#JYv0pAKK-U%dqSf&F z#_DJlyuPWLl@@8Ts*)zFtK_hHFtn0&^Q!6uk3+0_v;Dsma#0$BNk}Hrilp;^m419? z24Xo<+SwxmpJy1Z6OXx?f+Id@E&7*fYoR)>ml?<2Puh>L*Viy%m+wkWFEL`?wOEsM z-c_CtM2$%yMC<6Qb3i(*VYgjwrtDYNvP4ROk_?G92{Of-C&ZQQc1b!r80|}FY40%Y zPv$INWTr3fd(80Ji$}SGZ*h!JVZ0iT*Cdh*>+}siyzH@Sk^ObIQ?5PY*JEXW-H24# zbf;D}&%C<9uA(8a!LFfpwew+gF8^mIHe-=z8u}^~jrCe$E$Oe_t%W_28WR}ZYqu8q z?7v~R7Ec?3T4{Fms;-Jm?AvnGx;&rQyY(wwSJrC-mwH=j%>I9gKQ7BB@LwW6%wv>? z_UvF&jR}9In+Ef=3Mw*Bvu0ok-qZcu6$yJbL*OFt_IO|?D=C-h0C!T;0-UCaMk3bND67w$;6Gf?utsjS`_M#_Ptl93d+gx1t` zO46u%mnhqn{~IWKy`-UfCH3_QvUQA6O>BMWHQ}b&iLu0da~~p8;wRUCAwi+!6sb{< zWl4^VjW8sH^bUxaN0M-9UW3BENJd!Fma;v&4@(^4p778MG;lf^I9;y`L<9K7)R#z6 zhlfM-vQ%BOhemSPz3JoSzp`N)t&1CZCdSo$v?S?$yS-AJp2Uwn-_}%L3R`E>eLOG2 z&qAD6{>u3bInSetR1(GOuc@TeG)i|-26bt1LM?|UK?-6H&2^*`{NC+*;Rjk@4dTfE-&rgg}ZBdPVU_! zMvcM_lZ9|^(6LXZ?0eDC54)~Tw<0Rsxc`w=T9$=@iKNL1i=eN4|Y+l*Xb#TLWv+&<#KV|IpuEh=Aqh%hj z-`1L;_uCGVisnylt`#?Q0AbG!tVQsVhc_xKSe3Tpz`hq8hcft?s6LeZQ9ojnoB5Qo zxTum;XqkU&s=r8YfGG&@{2We|_#*@ABK-o96nJsN02D&Mx@aED7SS8a`8n4wPasSF zE4J}^>{yDL;Bd8$&SgLQXKn1=zL`*Kql8`4A3E{C^a693D*Ti^zNO|p#9_%2k*!ag zKl`l2GqM-a#4i!ABvDm$m6_M?vbEiiZr**$E?YbAV&_|I-YL9)zwghI&rVK-}xJmF}j;Jm}F=W%k+huubw`paOIS*K@4M*NlxMBwKWjwt(6CQa>z_SB$@G0v+shLvt{bz=s!`8c|{BJgDF)}6Vwfs-sPO(d}gCwz9t2bcUYqa7+${OuJk%~=CS{y!J zC)!+Og1s*4?Z2v>Ot>pqosdo;{Y{f*XQClf{&x*Z?>mNRe7m*|!->(&I_hTV_&F z+CqdBU9Bx@^yVsu%_nJeN;iLYG<7rPW3~v(7#;Ggf5sTrxTea}#CoumCBdYyWMyQP zCm9=SZ*NZ27A1C~is6uqhg9E^t(KmlvUDpco3t?tn-(;>q3p-wq(?boy4bXFcA$r4 zVdarTtvc4sPDAxY?ecJO2bQeA{hYZ%x@V1pwMo{<{UlKPR>%B0xc2MdT0h#0|0kJ+ zN!z9+vkB8KGVr6sa&)azGAkef65(XfSRbZ(okdG|+D53zpDDZi2M;niWZs9?n^}wA zsGT{hX3xT|b7Sqj{$(vMKE%HNZ&}Zqn;Xpb*)w)ozqd~Q^8*XmxV`o}2Txu)yyIJ4 z>l+d}X|-ntGT&F~@IPZ`@27i#*X{F_-50XYcdMC{CV6`*8b9Hs_1gNIdA*l*buaKY zdwXa36=TIa>)9OazSP@06aQB46-IVtuW&z}IQ?n6h3#$pY1i%+4l-idE&M9QRc3)y z@3Cv2fc5kD3uiK!{=%N&BQnQ6cjK_R-;US*zZgH0_%Doqzgil!=6pT^qk7^k8wdU` zYIsoe89X3kj$d~j56GGK;(`5CroWO0w%Yg$Xe{W~CZCT<|6cKujmr#;OF92D;V0#Z zO}lzC1uhNCX8IwipTw-<8q5YBx z#T@b&A}M^99p?l1EMVS6O_D&-{yYXZ=F5;Jl4uqy+}fr7t0!W@R{jNwywyn5^7&Ml zoLJ*m#zy0Q#}S9@%QR|}75{RR*@mb#s#(^WDm7ExS7ou|yUO}IYwbF|&aAe6q`p~g zt+m!x^KgJ4VKYQ06*&*NC$YZO4?8#|v4^>+`w0eE4TVE2^MNNO^4Mox0U!@-6Hj;` zdh<1h#~Vn>>?4c&Yz2_YYoDx&znYYqY2=r3HsY|e>WGazjhT|1KsHY^pdzO~G)l$U~FgxAwL@IQN!$^QMk(nr2qbv<|;MW9L*=#zPO* z+k_f+CjUPtT5tX@Yo4{GlKh}^f*P(iTi>?+*y!9`H)-1yXSsd=LTni}MDNu`|H{*s zskxBVqv$oewe5iSy4~9NJ$kqH)^xA$|8#dP&`}j>y6X1rPLqVBJL&Wz&(52?Uxe@q zj{qSP0Wrfck%|INH(a0d`j%4Lv#ziJ(S;yfp-J#`VImnERjyQ;pk69n6 z$Z^zxRhFa3I0&8n{;KLuCuttzxO?_&L*?GOef!?3zyA8`@&Et#$5ADvvMAJHo1|=r z)AmJ@szW@tO?L$5wf|$~;EShvanQVWa0`(R%~s*F%FdjC&MY16R0+kt z1hy!!FF`#R0NBK^VkQL#X!5wGWNFY?63d?)bYjcX3QSJ#%O@2c^Uy?%($ zICG&jRsO$W-Aw4IQ@&tCd{ZYjC1vKnog!VFwu2dm1tpb{0vX z02~`>zNe?dZrO?z00b><9S!xKPABi_4BpN|Qcnk5L{-`^Q_cTOaYN!WwHV@}QZFo}3K!fxz|9?ay z>b2LRktW3Pbxz3cn3L665(dI(&&9}{YY|STWEEU6NFrjv^0&7^E^WL*6Eniv<4gg-*FdUY zCzaKt;9A7h$QbuJ2%4*=4nbO85VS17j{3_(XgQQ+2|Kw2LrO&np)d=B>VB>zOWh)j ztwk1Z8BX({k5I#GaAc|cCUnfk#x>Eg$OV znp}+GU|t=>EruZmO+w2(Wx_Ip&-L;WKq>gbYk_c6i zkVN)tkxl`PbNyfg^~`K_$WiT@LI!L;j2b@`cCI)#Nu;k9xN z6=)Y(m(;(ZUF1IP&~_m%475uUb<*o^mnu0ux>9wf(6s2#ufx{ol9~wViqAS#+oZ9r z;W*7j!*WW6&nbsx?E8mBv5_WI{dJ_3Kl$Zgg+h=3X*dN^c>vpnOze{YPY=g?Z2$B` z+F^Kyu69jq8`5cz7U@d$Zl=LBY^`~HVEoi5$}}$#cEut3C5Y{yehJ2&1NBR7#Okfn z1>n`!=>#J}I+RBI(XQ(`0sT^=V6%ehMlw=X57H<~H9vvpkbVjNiBi8L%A@p4C{IAY z1YaL0n1qH&vH+=iX3OU8oUR|2jr(o!kcE1Zcgenjsiw<4lV6J*$NBh69L2~~(zwE{H~Q6Lb6 zMOd2C`~&t7;1D1Wz@49rPRZO{xas)}F^KJePJw+wtU)1o?b2h95T?rQXe;&AOsJ0Z`_AXR-S$XQPy4HR2l#?xXJ2{zFmLP9&iaqN z#~=Hw$nM}1U+S*vm{>fqa>hfW@BHx6yZ-&!GJp4r@Z4J8MB~1|o-yn;_5z0>o875) zDu9ZUB9;g#4lEHeFz662fi%Q~)2%PjZArm6pGf1pM8dRTas@mQTR&1xF6tSLJtaiV zOQG#hxk~~23o<^RqV7SokqE0m^ADZMcTF#^@Xb0d@JHU9 z;K0QFLr1|BSKQoXn7GdZCS`-mRo;(CQj>jYhq1ALs*b3;Xt#slMZzX=QOglGk_$r! zItdJh(RPE-Nd$@njDnvgbP~I4xohK-(D)J#qht;35rhXS(S8!x7x>>UE5?s-Wqp!5 z^_nXb)*uFtfpks20$n9u`yjfK29i);BwfiE`Fe0)lDJqthb!(xDJ;U5m;ZZUnGA^` z>Dw!KA&0FC;e}Me{;5u|KU_D1tl>*ax21yflZf+y6f~4eMhvKp)B}Wai8l$3nVy_6 zo=mIPo~Bl`Lr`souzk3CW(;1nhOetBf=F28~GGVQsv^*Mlf^d{tJG9>9g zs{MLEL`oVak;W0S5*$Opli-Cz0|5mKBte;pZCa%}a!HML8tINesU#~56{4K9s|(c; zJiv%$;6D#MDGUn~cniLhP##s~5H3B3xVw${LqI z>P^@c(r&u&wP>DCI6qjN{asBo zuu0TPZ9ucMPv;ZrLRuvNK>(Qq`;>?j_!irt2ivZqTE|A6mf_=)VPZh$)!xWRv=p7V zp{|UIu@R7B6oG(9ECMIY4$yn3_s7CU4Q{=$!udOPIE7V-B^PiEUbNepLb1`}ZM2kv z3z!GdrQwnbF@~UyggOJE;f;jZR}Xh!5-x@m5#od}lLN+>6e))SE|gbUvmz+mLfQEB zeDW)+4P}>|+U=J+v_D^Zb+7-qw>P9A_`=t3`A=nv$O~q^mg~(g#MNIuP=EQM8J2lR zG#Pv$-e`7lL|zc{F4M!Ii9XD>?z2x*~i)K5~&5S;-hVi%g4MU}H}-T#ljU^WI+imS&#Ik^euc8oF(*cWsIz%(->076JAQ=`}zY&-lhFPJrt zC(?%C13;&()<1g0e_?jEr|aT;d;OM^_fJXa@^5=s`$BsFc(waZXmd|}c_Cyc@WkpC zE$^THZF5=GeUESX{P@Ao#a1BbB{0olLrJ=H3;8*V6*QQNwCMzE4v2$be-XZ^aE8NB zM&Ng%OMq8^cLhmHK3~F3^(yG+G|izshfEn2MY z3&*_^;pXH^%^6!G^|H0WQ9RS zsQa_c8m8goWKM8OH1me@EgmeRAX9A=q7qDP;HoEsoe$9g)zNI(UNF@ubv&~YLzjiZ zXE+eIcQ6*i)o>cF{#}Qr>m6D>S`ZlJ5-&oAp$uY_)6}vE`RW-yFDq zlU~KsjIZMP-wC08Xvkv73v6_7;2vl$wou|8kPMt~BJet}Q!WY;R zLM?nIQMUku;2^36sffD~8$yF?wbW3k%2%LhM9L$J$0>5EGJ>93ohoC!XgOW<8W6R= zd_(D~%IAxa1eZk=(K6*`9yJ}klZgIlknrlAbNXueMRpRj|CZ=N+=TZEZu-p^w}o)i z!3ioKhAz}xRK_`=OE1zv{;2;}O2lX9*(vS3fo#Q#i7M1&@O@VY<+rcoNkFVfRzol@ z>v;{oMqn5G8gaDsON_iqBUn_x8VGha6@toG>3NOADD(z~8G3kN=|`&pIKc*X25}nL z83a@SgeRJ{LdiywkDU$t0R8V4A1XhvXLzsheFu`1sYJof2;Y6kE2D))Q$GQYI|MP} zmco=07#Mi!Kn$87_>Aa#@TceJ#4}~zldkmYnRuAbBpxfCX(I88kQRjOA)M=#SAD>p zp2}F$cTSH4PFfDz#CkBWz~s|-dVhLqCVYblY8)aw5hn3a?g2~&fHoMFBai`fJAe?P zaO?0W3L_n(c0e@jljXoT$BFSaE(t_c=xK?Viom)@0jQDPJY0-vbHu5kjM=i*fKRUi ziW+VDQItMY1ZE#58_hvdaS7=9fTlInY}W4C;&|=z10K^}f1Agu{q*v3P1FAQa;xQ6 zf82T0^z6T$|D%mxn6`Lc!L$n(v!~>~`PQ_8-D%T4`XIX|8w(L`0v$DWOxvTssec8I zuo2!7$puS1{M-l}#yboqU;!i_;O~3QG3BtQ111uJ1sh$Ml7)+hgNQJK>NaSTvGGaf zV}yuAdn2)AOc$wU@euI@T*0js=%6?;WE!l;_@hrv;gw7F?q4$b>FIm*-bs@#pVKUt z&uR^R3qObOL>9k^U%Y%y@Bsek_y>MwW#Du=7uciJo=ktE<^CVUj{lOS5da}$FRwa% zHgN1~_dCoT@a$liI{;@(eDE9drpr$QJ~OMYy>F|zgPt z3DOs=9aukyP{u=AHOtnQvqOgW*df#7?2z#$r0=qJ9p8!LC%FG6wpy=bNybFx)3>o| z)7xy8-oh$yEmOad&C~7#0^A5T4#!5k|4CyiL+DLrGknPw>B%ThE6S3})}s@y*EX|p zI`EnC+b+HhX=~pW!xK0@!Syv2pZ!9OvTw4-4A=obAE+NhG4xE~GlX7g#qRu}vr&GZwLJ+GoJ? z`YXza-w^HT8t?6U6LinTwGE(6J<<# zgz{|y?KktStWowfOw_CGo$v<=9#i@)Oo2>`wTDJ=&gQ@3g<~ z$amc9c*ALOu5cc7nOt*R??|Hz>?uB9GP>mM zk`GFqr3*^`RJN|%T)wNKvBE#HxAN}Fv!mvWI#`uawX5n#)yJc4qi2uyjVT=S<1ufI zEg!pgT-Lb8aYx6ej$bkUch$w!k5zvW8$Srqp$F$ zz8#SJT*pR^(8|hljqS;-xEEf0cd!+}s#yg;n_F26Tf^K~$=?FquA7y^ zey9}Q_eJ8Y45;vK%!@YQ?_}I@3;flZ*<#qUFU6S~=S%Uo23MBj-(qpsDm;&_%J061 zw=6=w74LN8H?6qt1`hZd*u~J3T5+}-SMFd-@OLKO;>KIv z)cZ^E))w5iM$n@bH3-~ajC<(Y+d+-n@I<<234TR2T7-5h##1O&!uF0@aA?VfmYwQO z6sr{_BaR@NF2R%6<1Iu-x4MJgatrdUxSwe11{JAQsb+56-y-h)F4nX&kiQX}M)!t3 zdB%Vz6ym#ZbRpUVC`Tn5_})Ni7J@Dd@x0~uy9j@&oa>RNauC1KdnZHVLFa4OSR9Gp z*Pv8m5s|F~b+`rPUWz>NVKEXts~B}(1@0d}K{pkL2I zO=qJW8o*a`(68pAUo|3%$2_1cG(q1sAE-wQ*g`Dlo?!Q~cJ>V9=AVJS`w%po|H6L3 zy19|v&)#A8U<5Yt2=*X1V+8#zd!G*j{_<1oORPRGur9=jf04a_C^L&d*PntbkAWkO zB7Wm5u%kW>OVrcg>DSpG*sIvPz7?1m53~PZZvdaAh5aY{3>HSq(EhifXDtWM?naxf z1ZPl>U5i#)2hKXfeu#aE4Xlm*2=*4e?B`gA-No)^o3Sr)mL0^(#0zAsw=nOF|4Z&`e3F5j@C zr7U7?>(bKF(y8(|xl|ohzNTE}Ybw;SQXR+8u^c~CNAVow#r-&n`*9qpz8Akkew4~r zspDvM3_NeL%$KR>mX$>=S$gZ*Rg0S!u5OWEmDkE+WvxDK?W#K{GY#bcyY}+Fb`O7$ z-QY3LZp4<>LpOVCO$CkV9?Q))cx(+gx%=i6kEx)k5p#I=G>@TRDgw4n>oH_&Sac&} zL`E-G8Iyb3L1xs`n94^`-o%#$@@C3M@Tfq37=CR2rMfv1nPCsAOcXMa%T*>CnW&j6 zGaQ-d@2E@+GQ;P}41zza0$Ol2cB2MBzuI*uq7_-o1Ho(@6~c-Ieeg;=U5Vqa{wp^8 yB>qV7h6H47-NCFK*@UiO)`6^jcQETj*0C#?bs_8Q31n~f*a{eLm^r4EvHu33Pbt*^ diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.woff b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-extralight-webfont.woff deleted file mode 100644 index 0f297dbe3e6d1d0c7d2574121da85795ac1886bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27108 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 Yu?aTr2}5$l2m8fm%m4vWO*w7=0KcytUH||9 diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.eot b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.eot deleted file mode 100644 index 5c9e81aa14f7bbc580e71c44c048f23357542dea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25059 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 diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.svg b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.svg deleted file mode 100644 index ce508397..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.svg +++ /dev/null @@ -1,2725 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.ttf b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.ttf deleted file mode 100644 index f3adc9f1bc1a7791a752bc2654137ab78391a172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50788 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 JT_YAT_P>37!hZk& diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.woff b/src/main/webapp/resources/3rd-party/jstree/themes/proton/fonts/titillium/titilliumweb-regular-webfont.woff deleted file mode 100644 index 4758678053b7b65a466269603263f2611a26be6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28152 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 diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.css b/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.css deleted file mode 100644 index 5df363a1..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.css +++ /dev/null @@ -1,1122 +0,0 @@ -/* jsTree default theme */ -.jstree-node, -.jstree-children, -.jstree-container-ul { - display: block; - margin: 0; - padding: 0; - list-style-type: none; - list-style-image: none; -} -.jstree-node { - white-space: nowrap; -} -.jstree-anchor { - display: inline-block; - color: #333; - white-space: nowrap; - padding: 0 4px 0 1px; - margin: 0; - vertical-align: top; -} -.jstree-anchor:focus { - outline: 0; -} -.jstree-anchor, -.jstree-anchor:link, -.jstree-anchor:visited, -.jstree-anchor:hover, -.jstree-anchor:active { - text-decoration: none; - color: inherit; -} -.jstree-icon { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-icon:empty { - display: inline-block; - text-decoration: none; - margin: 0; - padding: 0; - vertical-align: top; - text-align: center; -} -.jstree-ocl { - cursor: pointer; -} -.jstree-leaf > .jstree-ocl { - cursor: default; -} -.jstree .jstree-open > .jstree-children { - display: block; -} -.jstree .jstree-closed > .jstree-children, -.jstree .jstree-leaf > .jstree-children { - display: none; -} -.jstree-anchor > .jstree-themeicon { - margin-right: 2px; -} -.jstree-no-icons .jstree-themeicon, -.jstree-anchor > .jstree-themeicon-hidden { - display: none; -} -.jstree-rtl .jstree-anchor { - padding: 0 1px 0 4px; -} -.jstree-rtl .jstree-anchor > .jstree-themeicon { - margin-left: 2px; - margin-right: 0; -} -.jstree-rtl .jstree-node { - margin-left: 0; -} -.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; -} -.jstree-wholerow-ul { - position: relative; - display: inline-block; - min-width: 100%; -} -.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { - cursor: pointer; -} -.jstree-wholerow-ul .jstree-anchor, -.jstree-wholerow-ul .jstree-icon { - position: relative; -} -.jstree-wholerow-ul .jstree-wholerow { - width: 100%; - cursor: pointer; - position: absolute; - left: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.vakata-context { - display: none; -} -.vakata-context, -.vakata-context ul { - margin: 0; - padding: 2px; - position: absolute; - background: #f5f5f5; - border: 1px solid #979797; - -moz-box-shadow: 5px 5px 4px -4px #666666; - -webkit-box-shadow: 2px 2px 2px #999999; - box-shadow: 2px 2px 2px #999999; -} -.vakata-context ul { - list-style: none; - left: 100%; - margin-top: -2.7em; - margin-left: -4px; -} -.vakata-context .vakata-context-right ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context li { - list-style: none; - display: inline; -} -.vakata-context li > a { - display: block; - padding: 0 2em 0 2em; - text-decoration: none; - width: auto; - color: black; - white-space: nowrap; - line-height: 2.4em; - -moz-text-shadow: 1px 1px 0 white; - -webkit-text-shadow: 1px 1px 0 white; - text-shadow: 1px 1px 0 white; - -moz-border-radius: 1px; - -webkit-border-radius: 1px; - border-radius: 1px; -} -.vakata-context li > a:hover { - position: relative; - background-color: #e8eff7; - -moz-box-shadow: 0 0 2px #0a6aa1; - -webkit-box-shadow: 0 0 2px #0a6aa1; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); - background-position: right center; - background-repeat: no-repeat; -} -.vakata-context li > a:focus { - outline: 0; -} -.vakata-context .vakata-context-hover > a { - position: relative; - background-color: #e8eff7; - -moz-box-shadow: 0 0 2px #0a6aa1; - -webkit-box-shadow: 0 0 2px #0a6aa1; - box-shadow: 0 0 2px #0a6aa1; -} -.vakata-context .vakata-context-separator > a, -.vakata-context .vakata-context-separator > a:hover { - background: white; - border: 0; - border-top: 1px solid #e2e3e3; - height: 1px; - min-height: 1px; - max-height: 1px; - padding: 0; - margin: 0 0 0 2.4em; - border-left: 1px solid #e0e0e0; - -moz-text-shadow: 0 0 0 transparent; - -webkit-text-shadow: 0 0 0 transparent; - text-shadow: 0 0 0 transparent; - -moz-box-shadow: 0 0 0 transparent; - -webkit-box-shadow: 0 0 0 transparent; - box-shadow: 0 0 0 transparent; - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; -} -.vakata-context .vakata-contextmenu-disabled a, -.vakata-context .vakata-contextmenu-disabled a:hover { - color: silver; - background-color: transparent; - border: 0; - box-shadow: 0 0 0; -} -.vakata-context li > a > i { - text-decoration: none; - display: inline-block; - width: 2.4em; - height: 2.4em; - background: transparent; - margin: 0 0 0 -2em; - vertical-align: top; - text-align: center; - line-height: 2.4em; -} -.vakata-context li > a > i:empty { - width: 2.4em; - line-height: 2.4em; -} -.vakata-context li > a .vakata-contextmenu-sep { - display: inline-block; - width: 1px; - height: 2.4em; - background: white; - margin: 0 0.5em 0 0; - border-left: 1px solid #e2e3e3; -} -.vakata-context .vakata-contextmenu-shortcut { - font-size: 0.8em; - color: silver; - opacity: 0.5; - display: none; -} -.vakata-context-rtl ul { - left: auto; - right: 100%; - margin-left: auto; - margin-right: -4px; -} -.vakata-context-rtl li > a.vakata-context-parent { - background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); - background-position: left center; - background-repeat: no-repeat; -} -.vakata-context-rtl .vakata-context-separator > a { - margin: 0 2.4em 0 0; - border-left: 0; - border-right: 1px solid #e2e3e3; -} -.vakata-context-rtl .vakata-context-left ul { - right: auto; - left: 100%; - margin-left: -4px; - margin-right: auto; -} -.vakata-context-rtl li > a > i { - margin: 0 -2em 0 0; -} -.vakata-context-rtl li > a .vakata-contextmenu-sep { - margin: 0 0 0 0.5em; - border-left-color: white; - background: #e2e3e3; -} -#jstree-marker { - position: absolute; - top: 0; - left: 0; - margin: -5px 0 0 0; - padding: 0; - border-right: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid; - width: 0; - height: 0; - font-size: 0; - line-height: 0; -} -#jstree-dnd { - line-height: 16px; - margin: 0; - padding: 4px; -} -#jstree-dnd .jstree-icon, -#jstree-dnd .jstree-copy { - display: inline-block; - text-decoration: none; - margin: 0 2px 0 0; - padding: 0; - width: 16px; - height: 16px; -} -#jstree-dnd .jstree-ok { - background: green; -} -#jstree-dnd .jstree-er { - background: red; -} -#jstree-dnd .jstree-copy { - margin: 0 2px 0 2px; -} -.jstree-proton .jstree-node, -.jstree-proton .jstree-icon { - background-repeat: no-repeat; - background-color: transparent; -} -.jstree-proton .jstree-anchor, -.jstree-proton .jstree-wholerow { - transition: background-color 0.15s, box-shadow 0.15s, color 0.15s; -} -.jstree-proton .jstree-hovered { - background: #76b6ec; - color: #ffffff; - border-radius: 3px; - box-shadow: inset 0 0 1px #76b6ec; -} -.jstree-proton .jstree-clicked { - background: #3392e3; - color: #ffffff; - border-radius: 3px; - box-shadow: inset 0 0 1px #3392e3; -} -.jstree-proton .jstree-no-icons .jstree-anchor > .jstree-themeicon { - display: none; -} -.jstree-proton .jstree-disabled { - background: transparent; - color: #666666; -} -.jstree-proton .jstree-disabled.jstree-hovered { - background: transparent; - box-shadow: none; -} -.jstree-proton .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-proton .jstree-disabled > .jstree-icon { - opacity: 0.8; - filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); - /* Firefox 10+ * -filter: gray; -/* IE6-9 */ - -webkit-filter: grayscale(100%); - /* Chrome 19+ & Safari 6+ */ -} -.jstree-proton .jstree-search { - font-style: italic; - color: #8b0000; - font-weight: bold; -} -.jstree-proton .jstree-no-checkboxes .jstree-checkbox { - display: none !important; -} -.jstree-proton.jstree-checkbox-no-clicked .jstree-clicked { - background: transparent; - color: inherit; - box-shadow: none; -} -.jstree-proton.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { - background: #76b6ec; - color: #ffffff; -} -.jstree-proton.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { - background: transparent; - color: inherit; -} -.jstree-proton.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { - background: #76b6ec; - color: #ffffff; -} -.jstree-proton > .jstree-striped { - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; -} -.jstree-proton > .jstree-wholerow-ul .jstree-hovered, -.jstree-proton > .jstree-wholerow-ul .jstree-clicked { - background: transparent; - box-shadow: none; - border-radius: 0; -} -.jstree-proton .jstree-wholerow { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.jstree-proton .jstree-wholerow-hovered { - background: #76b6ec; -} -.jstree-proton .jstree-wholerow-clicked { - background: #3392e3; - background: -moz-linear-gradient(top, #3392e3 0%, #3392e3 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3392e3), color-stop(100%, #3392e3)); - background: -webkit-linear-gradient(top, #3392e3 0%, #3392e3 100%); - background: -o-linear-gradient(top, #3392e3 0%, #3392e3 100%); - background: -ms-linear-gradient(top, #3392e3 0%, #3392e3 100%); - background: linear-gradient(to bottom, #3392e3 0%, #3392e3 100%); - /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@color1', endColorstr='@color2',GradientType=0 );*/ -} -.jstree-proton .jstree-node { - min-height: 22px; - line-height: 22px; - margin-left: 22px; - min-width: 22px; -} -.jstree-proton .jstree-anchor { - line-height: 22px; - margin: 1px 0 2px; - height: 22px; -} -.jstree-proton .jstree-icon { - width: 22px; - height: 22px; - line-height: 22px; -} -.jstree-proton .jstree-icon:empty { - width: 22px; - height: 22px; - line-height: 22px; -} -.jstree-proton.jstree-rtl .jstree-node { - margin-right: 22px; -} -.jstree-proton .jstree-wholerow { - height: 22px; -} -.jstree-proton .jstree-node, -.jstree-proton .jstree-icon { - background-size: 320px 96px; - background-image: url("32px.png"); -} -.jstree-proton .jstree-node { - background-position: -293px -5px; - background-repeat: repeat-y; -} -.jstree-proton .jstree-last { - background: transparent; -} -.jstree-proton .jstree-open > .jstree-ocl { - background-position: -133px -5px; -} -.jstree-proton .jstree-closed > .jstree-ocl { - background-position: -101px -5px; -} -.jstree-proton .jstree-leaf > .jstree-ocl { - background-position: -69px -5px; -} -.jstree-proton .jstree-themeicon { - background-position: -261px -7px; -} -.jstree-proton > .jstree-no-dots .jstree-node, -.jstree-proton > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -37px -5px; -} -.jstree-proton > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -5px -5px; -} -.jstree-proton .jstree-disabled { - background: transparent; -} -.jstree-proton .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-proton .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-proton .jstree-checkbox { - background-position: -165px -5px; -} -.jstree-proton .jstree-checkbox:hover { - background-position: -165px -37px; -} -.jstree-proton.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-proton .jstree-checked > .jstree-checkbox { - background-position: -229px -5px; -} -.jstree-proton.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-proton .jstree-checked > .jstree-checkbox:hover { - background-position: -229px -37px; -} -.jstree-proton .jstree-anchor > .jstree-undetermined { - background-position: -197px -5px; -} -.jstree-proton .jstree-anchor > .jstree-undetermined:hover { - background-position: -197px -37px; -} -.jstree-proton > .jstree-striped { - background-size: auto 44px; -} -.jstree-proton.jstree-rtl .jstree-node { - background-size: 320px 96px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-proton.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-proton.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -133px -37px; -} -.jstree-proton.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -101px -37px; -} -.jstree-proton.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -69px -37px; -} -.jstree-proton.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-proton.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -37px -37px; -} -.jstree-proton.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -5px -37px; -} -.jstree-proton .jstree-themeicon-custom { - background-color: transparent; - background-size: 320px 96px; - background-image: none; - background-position: 0 0; -} -.jstree-proton > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-proton .jstree-file { - background: url("32px.png") -101px -69px no-repeat; -} -.jstree-proton .jstree-folder { - background: url("32px.png") -261px -5px no-repeat; -} -.jstree-proton > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-proton { - line-height: 22px; - padding: 0 4px; -} -#jstree-dnd.jstree-proton .jstree-ok, -#jstree-dnd.jstree-proton .jstree-er { - background-size: 320px 96px; - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-proton i { - background: transparent; - width: 22px; - height: 22px; - line-height: 22px; -} -#jstree-dnd.jstree-proton .jstree-ok { - background-position: -5px -69px; -} -#jstree-dnd.jstree-proton .jstree-er { - background-position: -37px -69px; -} -.jstree-proton.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); -} -.jstree-proton.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-proton-small .jstree-node { - min-height: 18px; - line-height: 18px; - margin-left: 18px; - min-width: 18px; -} -.jstree-proton-small .jstree-anchor { - line-height: 18px; - margin: 1px 0 2px; - height: 18px; -} -.jstree-proton-small .jstree-icon { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-proton-small .jstree-icon:empty { - width: 18px; - height: 18px; - line-height: 18px; -} -.jstree-proton-small.jstree-rtl .jstree-node { - margin-right: 18px; -} -.jstree-proton-small .jstree-wholerow { - height: 18px; -} -.jstree-proton-small .jstree-node, -.jstree-proton-small .jstree-icon { - background-size: 320px 96px; - background-image: url("32px.png"); -} -.jstree-proton-small .jstree-node { - background-position: -295px -7px; - background-repeat: repeat-y; -} -.jstree-proton-small .jstree-last { - background: transparent; -} -.jstree-proton-small .jstree-open > .jstree-ocl { - background-position: -135px -7px; -} -.jstree-proton-small .jstree-closed > .jstree-ocl { - background-position: -103px -7px; -} -.jstree-proton-small .jstree-leaf > .jstree-ocl { - background-position: -71px -7px; -} -.jstree-proton-small .jstree-themeicon { - background-position: -263px -9px; -} -.jstree-proton-small > .jstree-no-dots .jstree-node, -.jstree-proton-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton-small > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -7px; -} -.jstree-proton-small > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -7px; -} -.jstree-proton-small .jstree-disabled { - background: transparent; -} -.jstree-proton-small .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-proton-small .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-proton-small .jstree-checkbox { - background-position: -167px -7px; -} -.jstree-proton-small .jstree-checkbox:hover { - background-position: -167px -39px; -} -.jstree-proton-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-proton-small .jstree-checked > .jstree-checkbox { - background-position: -231px -7px; -} -.jstree-proton-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-proton-small .jstree-checked > .jstree-checkbox:hover { - background-position: -231px -39px; -} -.jstree-proton-small .jstree-anchor > .jstree-undetermined { - background-position: -199px -7px; -} -.jstree-proton-small .jstree-anchor > .jstree-undetermined:hover { - background-position: -199px -39px; -} -.jstree-proton-small > .jstree-striped { - background-size: auto 36px; -} -.jstree-proton-small.jstree-rtl .jstree-node { - background-size: 320px 96px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-proton-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-proton-small.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -135px -39px; -} -.jstree-proton-small.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -103px -39px; -} -.jstree-proton-small.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -71px -39px; -} -.jstree-proton-small.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-proton-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -39px -39px; -} -.jstree-proton-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: -7px -39px; -} -.jstree-proton-small .jstree-themeicon-custom { - background-color: transparent; - background-size: 320px 96px; - background-image: none; - background-position: 0 0; -} -.jstree-proton-small > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-proton-small .jstree-file { - background: url("32px.png") -103px -71px no-repeat; -} -.jstree-proton-small .jstree-folder { - background: url("32px.png") -263px -7px no-repeat; -} -.jstree-proton-small > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-proton-small { - line-height: 18px; - padding: 0 4px; -} -#jstree-dnd.jstree-proton-small .jstree-ok, -#jstree-dnd.jstree-proton-small .jstree-er { - background-size: 320px 96px; - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-proton-small i { - background: transparent; - width: 18px; - height: 18px; - line-height: 18px; -} -#jstree-dnd.jstree-proton-small .jstree-ok { - background-position: -7px -71px; -} -#jstree-dnd.jstree-proton-small .jstree-er { - background-position: -39px -71px; -} -.jstree-proton-small.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); -} -.jstree-proton-small.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-proton-large .jstree-node { - min-height: 32px; - line-height: 32px; - margin-left: 32px; - min-width: 32px; -} -.jstree-proton-large .jstree-anchor { - line-height: 32px; - margin: 1px 0 2px; - height: 32px; -} -.jstree-proton-large .jstree-icon { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-proton-large .jstree-icon:empty { - width: 32px; - height: 32px; - line-height: 32px; -} -.jstree-proton-large.jstree-rtl .jstree-node { - margin-right: 32px; -} -.jstree-proton-large .jstree-wholerow { - height: 32px; -} -.jstree-proton-large .jstree-node, -.jstree-proton-large .jstree-icon { - background-size: 320px 96px; - background-image: url("32px.png"); -} -.jstree-proton-large .jstree-node { - background-position: -288px 0px; - background-repeat: repeat-y; -} -.jstree-proton-large .jstree-last { - background: transparent; -} -.jstree-proton-large .jstree-open > .jstree-ocl { - background-position: -128px 0px; -} -.jstree-proton-large .jstree-closed > .jstree-ocl { - background-position: -96px 0px; -} -.jstree-proton-large .jstree-leaf > .jstree-ocl { - background-position: -64px 0px; -} -.jstree-proton-large .jstree-themeicon { - background-position: -256px -2px; -} -.jstree-proton-large > .jstree-no-dots .jstree-node, -.jstree-proton-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton-large > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px 0px; -} -.jstree-proton-large > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px 0px; -} -.jstree-proton-large .jstree-disabled { - background: transparent; -} -.jstree-proton-large .jstree-disabled.jstree-hovered { - background: transparent; -} -.jstree-proton-large .jstree-disabled.jstree-clicked { - background: #efefef; -} -.jstree-proton-large .jstree-checkbox { - background-position: -160px 0px; -} -.jstree-proton-large .jstree-checkbox:hover { - background-position: -160px -32px; -} -.jstree-proton-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, -.jstree-proton-large .jstree-checked > .jstree-checkbox { - background-position: -224px 0px; -} -.jstree-proton-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, -.jstree-proton-large .jstree-checked > .jstree-checkbox:hover { - background-position: -224px -32px; -} -.jstree-proton-large .jstree-anchor > .jstree-undetermined { - background-position: -192px 0px; -} -.jstree-proton-large .jstree-anchor > .jstree-undetermined:hover { - background-position: -192px -32px; -} -.jstree-proton-large > .jstree-striped { - background-size: auto 64px; -} -.jstree-proton-large.jstree-rtl .jstree-node { - background-size: 320px 96px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); - background-position: 100% 1px; - background-repeat: repeat-y; -} -.jstree-proton-large.jstree-rtl .jstree-last { - background: transparent; -} -.jstree-proton-large.jstree-rtl .jstree-open > .jstree-ocl { - background-position: -128px -32px; -} -.jstree-proton-large.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -96px -32px; -} -.jstree-proton-large.jstree-rtl .jstree-leaf > .jstree-ocl { - background-position: -64px -32px; -} -.jstree-proton-large.jstree-rtl > .jstree-no-dots .jstree-node, -.jstree-proton-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { - background: transparent; -} -.jstree-proton-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { - background-position: -32px -32px; -} -.jstree-proton-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { - background-position: 0px -32px; -} -.jstree-proton-large .jstree-themeicon-custom { - background-color: transparent; - background-size: 320px 96px; - background-image: none; - background-position: 0 0; -} -.jstree-proton-large > .jstree-container-ul .jstree-loading > .jstree-ocl { - background: url("throbber.gif") center center no-repeat; -} -.jstree-proton-large .jstree-file { - background: url("32px.png") -96px -64px no-repeat; -} -.jstree-proton-large .jstree-folder { - background: url("32px.png") -256px 0px no-repeat; -} -.jstree-proton-large > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; -} -#jstree-dnd.jstree-proton-large { - line-height: 32px; - padding: 0 4px; -} -#jstree-dnd.jstree-proton-large .jstree-ok, -#jstree-dnd.jstree-proton-large .jstree-er { - background-size: 320px 96px; - background-image: url("32px.png"); - background-repeat: no-repeat; - background-color: transparent; -} -#jstree-dnd.jstree-proton-large i { - background: transparent; - width: 32px; - height: 32px; - line-height: 32px; -} -#jstree-dnd.jstree-proton-large .jstree-ok { - background-position: 0px -64px; -} -#jstree-dnd.jstree-proton-large .jstree-er { - background-position: -32px -64px; -} -.jstree-proton-large.jstree-rtl .jstree-node { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); -} -.jstree-proton-large.jstree-rtl .jstree-last { - background: transparent; -} -@media (max-width: 768px) { - #jstree-dnd.jstree-dnd-responsive { - line-height: 30px; - font-weight: bold; - font-size: 1.1em; - text-shadow: 1px 1px white; - } - #jstree-dnd.jstree-dnd-responsive > i { - background: transparent; - width: 30px; - height: 30px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-ok { - background-image: url("30px.png"); - background-position: 0 -150px; - background-size: 90px 180px; - } - #jstree-dnd.jstree-dnd-responsive > .jstree-er { - background-image: url("30px.png"); - background-position: -30px -150px; - background-size: 90px 180px; - } - #jstree-marker.jstree-dnd-responsive { - border-left-width: 10px; - border-top-width: 10px; - border-bottom-width: 10px; - margin-top: -10px; - } -} -@media (max-width: 768px) { - .jstree-proton-responsive { - /* - .jstree-open > .jstree-ocl, - .jstree-closed > .jstree-ocl { - border-radius:20px; - background-color:white; - } - */ - } - .jstree-proton-responsive .jstree-container-ul { - overflow: hidden; - } - .jstree-proton-responsive .jstree-icon { - background-image: url("30px.png"); - background-size: 90px 180px; - } - .jstree-proton-responsive .jstree-node, - .jstree-proton-responsive .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-proton-responsive .jstree-node { - min-height: 30px; - line-height: 30px; - margin-left: 30px; - min-width: 30px; - white-space: nowrap; - } - .jstree-proton-responsive .jstree-anchor { - line-height: 38px; - height: 38px; - margin: 0; - } - .jstree-proton-responsive .jstree-icon, - .jstree-proton-responsive .jstree-icon:empty { - margin-top: 4px; - width: 30px; - height: 30px; - line-height: 30px; - } - .jstree-proton-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - } - .jstree-proton-responsive.jstree-rtl .jstree-node { - margin-left: 0; - margin-right: 30px; - } - .jstree-proton-responsive.jstree-rtl .jstree-container-ul > .jstree-node { - margin-right: 0; - } - .jstree-proton-responsive .jstree-ocl, - .jstree-proton-responsive .jstree-themeicon, - .jstree-proton-responsive .jstree-checkbox { - background-size: 90px 180px; - } - .jstree-proton-responsive .jstree-leaf > .jstree-ocl { - background: transparent; - } - .jstree-proton-responsive .jstree-open > .jstree-ocl { - background-position: 0 0px !important; - } - .jstree-proton-responsive .jstree-closed > .jstree-ocl { - background-position: 0 -30px !important; - } - .jstree-proton-responsive.jstree-rtl .jstree-closed > .jstree-ocl { - background-position: -30px 0px !important; - } - .jstree-proton-responsive .jstree-themeicon { - background-position: -30px -30px; - } - .jstree-proton-responsive .jstree-checkbox, - .jstree-proton-responsive .jstree-checkbox:hover { - background-position: -30px -60px; - } - .jstree-proton-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, - .jstree-proton-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, - .jstree-proton-responsive .jstree-checked > .jstree-checkbox, - .jstree-proton-responsive .jstree-checked > .jstree-checkbox:hover { - background-position: 0 -60px; - } - .jstree-proton-responsive .jstree-anchor > .jstree-undetermined, - .jstree-proton-responsive .jstree-anchor > .jstree-undetermined:hover { - background-position: 0 -90px; - } - .jstree-proton-responsive > .jstree-striped { - background: transparent; - } - .jstree-proton-responsive .jstree-wholerow-ul li { - position: relative; - } - .jstree-proton-responsive .jstree-wholerow-ul .jstree-wholerow { - position: absolute; - top: 0; - left: -1000px; - right: -1000px; - width: auto; - height: 100%; - } - .jstree-proton-responsive .jstree-wholerow { - border-top: 1px solid rgba(0, 0, 0, 0.05); - background: rgba(0, 0, 0, 0.02); - height: 30px; - } - .jstree-proton-responsive .jstree-wholerow-hovered { - background: #76b6ec; - } - .jstree-proton-responsive .jstree-wholerow-clicked { - background: #3392e3; - } - .jstree-proton-responsive .jstree-children .jstree-open + .jstree-open { - box-shadow: none; - } - .jstree-proton-responsive .jstree-node, - .jstree-proton-responsive .jstree-icon, - .jstree-proton-responsive .jstree-node > .jstree-ocl, - .jstree-proton-responsive .jstree-themeicon, - .jstree-proton-responsive .jstree-checkbox { - background-image: url("30px.png"); - background-size: 90px 180px; - } - .jstree-proton-responsive .jstree-node { - background-position: -60px 0; - background-repeat: repeat-y; - } - .jstree-proton-responsive .jstree-last { - background: transparent; - } - .jstree-proton-responsive .jstree-leaf > .jstree-ocl { - background-position: -30px -90px; - } - .jstree-proton-responsive .jstree-last > .jstree-ocl { - background-position: -30px -120px; - } - .jstree-proton-responsive .jstree-themeicon-custom { - background-color: transparent; - background-image: none; - background-position: 0 0; - } - .jstree-proton-responsive .jstree-file { - background: url("30px.png") 0 -120px no-repeat; - background-size: 90px 180px; - } - .jstree-proton-responsive .jstree-folder { - background: url("30px.png") -30px -30px no-repeat; - background-size: 90px 180px; - } - .jstree-proton-responsive > .jstree-container-ul > .jstree-node { - margin-left: 0; - margin-right: 0; - } -} -@font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-extralight-webfont.eot'); - src: url('fonts/titillium/titilliumweb-extralight-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/titillium/titilliumweb-extralight-webfont.woff') format('woff'), url('fonts/titillium/titilliumweb-extralight-webfont.ttf') format('truetype'), url('fonts/titillium/titilliumweb-extralight-webfont.svg#titillium_webthin') format('svg'); - font-weight: 300; - font-style: normal; -} -@font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-regular-webfont.eot'); - src: url('fonts/titillium/titilliumweb-regular-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/titillium/titilliumweb-regular-webfont.woff') format('woff'), url('fonts/titillium/titilliumweb-regular-webfont.ttf') format('truetype'), url('fonts/titillium/titilliumweb-regular-webfont.svg#titillium_webregular') format('svg'); - font-weight: 400; - font-style: normal; -} -@font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-bold-webfont.eot'); - src: url('fonts/titillium/titilliumweb-bold-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/titillium/titilliumweb-bold-webfont.woff') format('woff'), url('fonts/titillium/titilliumweb-bold-webfont.ttf') format('truetype'), url('fonts/titillium/titilliumweb-bold-webfont.svg#titillium_webbold') format('svg'); - font-weight: 700; - font-style: normal; -} -@media screen and (-webkit-min-device-pixel-ratio: 0) { - @font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-extralight-webfont.svg#titillium_webthin') format('svg'); - font-weight: 300; - font-style: normal; - } - @font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-regular-webfont.svg#titillium_webregular') format('svg'); - font-weight: 400; - font-style: normal; - } - @font-face { - font-family: 'Titillium Web'; - src: url('fonts/titillium/titilliumweb-bold-webfont.svg#titillium_webbold') format('svg'); - font-weight: 700; - font-style: normal; - } -} -.jstree-proton { - font-family: 'Titillium Web', sans-serif, Arial, sans-serif; -} diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.min.css b/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.min.css deleted file mode 100644 index 5024e5c9..00000000 --- a/src/main/webapp/resources/3rd-party/jstree/themes/proton/style.min.css +++ /dev/null @@ -1 +0,0 @@ -.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#333;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;-moz-box-shadow:5px 5px 4px -4px #666;-webkit-box-shadow:2px 2px 2px #999;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none;display:inline}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;-moz-text-shadow:1px 1px 0 #fff;-webkit-text-shadow:1px 1px 0 #fff;text-shadow:1px 1px 0 #fff;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;-moz-box-shadow:0 0 2px #0a6aa1;-webkit-box-shadow:0 0 2px #0a6aa1;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;-moz-box-shadow:0 0 2px #0a6aa1;-webkit-box-shadow:0 0 2px #0a6aa1;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;-moz-text-shadow:0 0 0 transparent;-webkit-text-shadow:0 0 0 transparent;text-shadow:0 0 0 transparent;-moz-box-shadow:0 0 0 transparent;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-proton .jstree-node,.jstree-proton .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-proton .jstree-anchor,.jstree-proton .jstree-wholerow{transition:background-color .15s,box-shadow .15s,color .15s}.jstree-proton .jstree-hovered{background:#76b6ec;color:#fff;border-radius:3px;box-shadow:inset 0 0 1px #76b6ec}.jstree-proton .jstree-clicked{background:#3392e3;color:#fff;border-radius:3px;box-shadow:inset 0 0 1px #3392e3}.jstree-proton .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-proton .jstree-disabled{background:0 0;color:#666}.jstree-proton .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-proton .jstree-disabled.jstree-clicked{background:#efefef}.jstree-proton .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");-webkit-filter:grayscale(100%)}.jstree-proton .jstree-search{font-style:italic;color:#8b0000;font-weight:700}.jstree-proton .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-proton.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;color:inherit;box-shadow:none}.jstree-proton.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#76b6ec;color:#fff}.jstree-proton.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0;color:inherit}.jstree-proton.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#76b6ec;color:#fff}.jstree-proton>.jstree-striped{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-proton>.jstree-wholerow-ul .jstree-hovered,.jstree-proton>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-proton .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-proton .jstree-wholerow-hovered{background:#76b6ec}.jstree-proton .jstree-wholerow-clicked{background:#3392e3;background:-moz-linear-gradient(top,#3392e3 0,#3392e3 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#3392e3),color-stop(100%,#3392e3));background:-webkit-linear-gradient(top,#3392e3 0,#3392e3 100%);background:-o-linear-gradient(top,#3392e3 0,#3392e3 100%);background:-ms-linear-gradient(top,#3392e3 0,#3392e3 100%);background:linear-gradient(to bottom,#3392e3 0,#3392e3 100%)}.jstree-proton .jstree-node{min-height:22px;line-height:22px;margin-left:22px;min-width:22px}.jstree-proton .jstree-anchor{line-height:22px;margin:1px 0 2px;height:22px}.jstree-proton .jstree-icon{width:22px;height:22px;line-height:22px}.jstree-proton .jstree-icon:empty{width:22px;height:22px;line-height:22px}.jstree-proton.jstree-rtl .jstree-node{margin-right:22px}.jstree-proton .jstree-wholerow{height:22px}.jstree-proton .jstree-node,.jstree-proton .jstree-icon{background-size:320px 96px;background-image:url(32px.png)}.jstree-proton .jstree-node{background-position:-293px -5px;background-repeat:repeat-y}.jstree-proton .jstree-last{background:0 0}.jstree-proton .jstree-open>.jstree-ocl{background-position:-133px -5px}.jstree-proton .jstree-closed>.jstree-ocl{background-position:-101px -5px}.jstree-proton .jstree-leaf>.jstree-ocl{background-position:-69px -5px}.jstree-proton .jstree-themeicon{background-position:-261px -7px}.jstree-proton>.jstree-no-dots .jstree-node,.jstree-proton>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-37px -5px}.jstree-proton>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-5px -5px}.jstree-proton .jstree-disabled{background:0 0}.jstree-proton .jstree-disabled.jstree-hovered{background:0 0}.jstree-proton .jstree-disabled.jstree-clicked{background:#efefef}.jstree-proton .jstree-checkbox{background-position:-165px -5px}.jstree-proton .jstree-checkbox:hover{background-position:-165px -37px}.jstree-proton.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-proton .jstree-checked>.jstree-checkbox{background-position:-229px -5px}.jstree-proton.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-proton .jstree-checked>.jstree-checkbox:hover{background-position:-229px -37px}.jstree-proton .jstree-anchor>.jstree-undetermined{background-position:-197px -5px}.jstree-proton .jstree-anchor>.jstree-undetermined:hover{background-position:-197px -37px}.jstree-proton>.jstree-striped{background-size:auto 44px}.jstree-proton.jstree-rtl .jstree-node{background-size:320px 96px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-proton.jstree-rtl .jstree-last{background:0 0}.jstree-proton.jstree-rtl .jstree-open>.jstree-ocl{background-position:-133px -37px}.jstree-proton.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-101px -37px}.jstree-proton.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-69px -37px}.jstree-proton.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-proton.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-37px -37px}.jstree-proton.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-5px -37px}.jstree-proton .jstree-themeicon-custom{background-color:transparent;background-size:320px 96px;background-image:none;background-position:0 0}.jstree-proton>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-proton .jstree-file{background:url(32px.png) -101px -69px no-repeat}.jstree-proton .jstree-folder{background:url(32px.png) -261px -5px no-repeat}.jstree-proton>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-proton{line-height:22px;padding:0 4px}#jstree-dnd.jstree-proton .jstree-ok,#jstree-dnd.jstree-proton .jstree-er{background-size:320px 96px;background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-proton i{background:0 0;width:22px;height:22px;line-height:22px}#jstree-dnd.jstree-proton .jstree-ok{background-position:-5px -69px}#jstree-dnd.jstree-proton .jstree-er{background-position:-37px -69px}.jstree-proton.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-proton.jstree-rtl .jstree-last{background:0 0}.jstree-proton-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-proton-small .jstree-anchor{line-height:18px;margin:1px 0 2px;height:18px}.jstree-proton-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-proton-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-proton-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-proton-small .jstree-wholerow{height:18px}.jstree-proton-small .jstree-node,.jstree-proton-small .jstree-icon{background-size:320px 96px;background-image:url(32px.png)}.jstree-proton-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-proton-small .jstree-last{background:0 0}.jstree-proton-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-proton-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-proton-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-proton-small .jstree-themeicon{background-position:-263px -9px}.jstree-proton-small>.jstree-no-dots .jstree-node,.jstree-proton-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-proton-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-proton-small .jstree-disabled{background:0 0}.jstree-proton-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-proton-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-proton-small .jstree-checkbox{background-position:-167px -7px}.jstree-proton-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-proton-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-proton-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-proton-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-proton-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-proton-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-proton-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-proton-small>.jstree-striped{background-size:auto 36px}.jstree-proton-small.jstree-rtl .jstree-node{background-size:320px 96px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-proton-small.jstree-rtl .jstree-last{background:0 0}.jstree-proton-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-proton-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-proton-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-proton-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-proton-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-proton-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-proton-small .jstree-themeicon-custom{background-color:transparent;background-size:320px 96px;background-image:none;background-position:0 0}.jstree-proton-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-proton-small .jstree-file{background:url(32px.png) -103px -71px no-repeat}.jstree-proton-small .jstree-folder{background:url(32px.png) -263px -7px no-repeat}.jstree-proton-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-proton-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-proton-small .jstree-ok,#jstree-dnd.jstree-proton-small .jstree-er{background-size:320px 96px;background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-proton-small i{background:0 0;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-proton-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-proton-small .jstree-er{background-position:-39px -71px}.jstree-proton-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-proton-small.jstree-rtl .jstree-last{background:0 0}.jstree-proton-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-proton-large .jstree-anchor{line-height:32px;margin:1px 0 2px;height:32px}.jstree-proton-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-proton-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-proton-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-proton-large .jstree-wholerow{height:32px}.jstree-proton-large .jstree-node,.jstree-proton-large .jstree-icon{background-size:320px 96px;background-image:url(32px.png)}.jstree-proton-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-proton-large .jstree-last{background:0 0}.jstree-proton-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-proton-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-proton-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-proton-large .jstree-themeicon{background-position:-256px -2px}.jstree-proton-large>.jstree-no-dots .jstree-node,.jstree-proton-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-proton-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-proton-large .jstree-disabled{background:0 0}.jstree-proton-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-proton-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-proton-large .jstree-checkbox{background-position:-160px 0}.jstree-proton-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-proton-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-proton-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-proton-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-proton-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-proton-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-proton-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-proton-large>.jstree-striped{background-size:auto 64px}.jstree-proton-large.jstree-rtl .jstree-node{background-size:320px 96px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-proton-large.jstree-rtl .jstree-last{background:0 0}.jstree-proton-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-proton-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-proton-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-proton-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-proton-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-proton-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-proton-large .jstree-themeicon-custom{background-color:transparent;background-size:320px 96px;background-image:none;background-position:0 0}.jstree-proton-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-proton-large .jstree-file{background:url(32px.png) -96px -64px no-repeat}.jstree-proton-large .jstree-folder{background:url(32px.png) -256px 0 no-repeat}.jstree-proton-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-proton-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-proton-large .jstree-ok,#jstree-dnd.jstree-proton-large .jstree-er{background-size:320px 96px;background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-proton-large i{background:0 0;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-proton-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-proton-large .jstree-er{background-position:-32px -64px}.jstree-proton-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-proton-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:30px;font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}#jstree-dnd.jstree-dnd-responsive>i{background:0 0;width:30px;height:30px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url(30px.png);background-position:0 -150px;background-size:90px 180px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url(30px.png);background-position:-30px -150px;background-size:90px 180px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-proton-responsive .jstree-container-ul{overflow:hidden}.jstree-proton-responsive .jstree-icon{background-image:url(30px.png);background-size:90px 180px}.jstree-proton-responsive .jstree-node,.jstree-proton-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-responsive .jstree-node{min-height:30px;line-height:30px;margin-left:30px;min-width:30px;white-space:nowrap}.jstree-proton-responsive .jstree-anchor{line-height:38px;height:38px;margin:0}.jstree-proton-responsive .jstree-icon,.jstree-proton-responsive .jstree-icon:empty{margin-top:4px;width:30px;height:30px;line-height:30px}.jstree-proton-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-proton-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:30px}.jstree-proton-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-proton-responsive .jstree-ocl,.jstree-proton-responsive .jstree-themeicon,.jstree-proton-responsive .jstree-checkbox{background-size:90px 180px}.jstree-proton-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-proton-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-proton-responsive .jstree-closed>.jstree-ocl{background-position:0 -30px!important}.jstree-proton-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-30px 0!important}.jstree-proton-responsive .jstree-themeicon{background-position:-30px -30px}.jstree-proton-responsive .jstree-checkbox,.jstree-proton-responsive .jstree-checkbox:hover{background-position:-30px -60px}.jstree-proton-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-proton-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-proton-responsive .jstree-checked>.jstree-checkbox,.jstree-proton-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -60px}.jstree-proton-responsive .jstree-anchor>.jstree-undetermined,.jstree-proton-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -90px}.jstree-proton-responsive>.jstree-striped{background:0 0}.jstree-proton-responsive .jstree-wholerow-ul li{position:relative}.jstree-proton-responsive .jstree-wholerow-ul .jstree-wholerow{position:absolute;top:0;left:-1000px;right:-1000px;width:auto;height:100%}.jstree-proton-responsive .jstree-wholerow{border-top:1px solid rgba(0,0,0,.05);background:rgba(0,0,0,.02);height:30px}.jstree-proton-responsive .jstree-wholerow-hovered{background:#76b6ec}.jstree-proton-responsive .jstree-wholerow-clicked{background:#3392e3}.jstree-proton-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-proton-responsive .jstree-node,.jstree-proton-responsive .jstree-icon,.jstree-proton-responsive .jstree-node>.jstree-ocl,.jstree-proton-responsive .jstree-themeicon,.jstree-proton-responsive .jstree-checkbox{background-image:url(30px.png);background-size:90px 180px}.jstree-proton-responsive .jstree-node{background-position:-60px 0;background-repeat:repeat-y}.jstree-proton-responsive .jstree-last{background:0 0}.jstree-proton-responsive .jstree-leaf>.jstree-ocl{background-position:-30px -90px}.jstree-proton-responsive .jstree-last>.jstree-ocl{background-position:-30px -120px}.jstree-proton-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-proton-responsive .jstree-file{background:url(30px.png) 0 -120px no-repeat;background-size:90px 180px}.jstree-proton-responsive .jstree-folder{background:url(30px.png) -30px -30px no-repeat;background-size:90px 180px}.jstree-proton-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-extralight-webfont.eot);src:url(fonts/titillium/titilliumweb-extralight-webfont.eot?#iefix) format('embedded-opentype'),url(fonts/titillium/titilliumweb-extralight-webfont.woff) format('woff'),url(fonts/titillium/titilliumweb-extralight-webfont.ttf) format('truetype'),url(fonts/titillium/titilliumweb-extralight-webfont.svg#titillium_webthin) format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-regular-webfont.eot);src:url(fonts/titillium/titilliumweb-regular-webfont.eot?#iefix) format('embedded-opentype'),url(fonts/titillium/titilliumweb-regular-webfont.woff) format('woff'),url(fonts/titillium/titilliumweb-regular-webfont.ttf) format('truetype'),url(fonts/titillium/titilliumweb-regular-webfont.svg#titillium_webregular) format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-bold-webfont.eot);src:url(fonts/titillium/titilliumweb-bold-webfont.eot?#iefix) format('embedded-opentype'),url(fonts/titillium/titilliumweb-bold-webfont.woff) format('woff'),url(fonts/titillium/titilliumweb-bold-webfont.ttf) format('truetype'),url(fonts/titillium/titilliumweb-bold-webfont.svg#titillium_webbold) format('svg');font-weight:700;font-style:normal}@media screen and (-webkit-min-device-pixel-ratio:0){@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-extralight-webfont.svg#titillium_webthin) format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-regular-webfont.svg#titillium_webregular) format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Titillium Web';src:url(fonts/titillium/titilliumweb-bold-webfont.svg#titillium_webbold) format('svg');font-weight:700;font-style:normal}}.jstree-proton{font-family:'Titillium Web',sans-serif,Arial,sans-serif} \ No newline at end of file diff --git a/src/main/webapp/resources/3rd-party/jstree/themes/proton/throbber.gif b/src/main/webapp/resources/3rd-party/jstree/themes/proton/throbber.gif deleted file mode 100644 index 1b5b2fde42f8ea14e6981339196a9d62b681d79e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1720 zcmZ|OYfMvT7zgm4p2O+ea@rnBg#)OxTPX)YQxLES+gfgxVz~&+f}$;m6s%Hi3W%nq zP@z^qrV}=TNF%FL8K5q@MN>cp#S0pVI*qHSli{|&j8i`-D~lhy5AU}p`Tz2N-e*-( zqBu&8Q*g>F3T19?Zf0i2Y&JU_j>N>onwlC4g`!j{1p>jzlP51;yvXHpJ32ZL1c{7{ z)MzyPIro%=%#1i`T0+<|5ezw}`5%1a$_msK1)F#~iYhcbb+NiiTcX~ytZ3Wj5(@tv zLT5OqLY&VTiBl*@DK5jOqAQC<V}_H8&J8*d!6F|8^P+>r!@8gG==_FR|TOFO5N ztmi!uPli+Ln$x?H-gK%V=cf&)%tK3Ubl`;)j){YK#AZm_($yDbHN+iIVb4-MA(|Tn z%Y=0Su-m75IE?%N1|!SEl|tuKXsXZNj2Z=vp;+=jlJSZD2EODW0H`sM#)b0zgDU0)5!Grr5zO1 zNgN^!L7)EBFUC+Zhm%Mr7yC91@!CieHdPd#!o7Jn^!!TMrU0vgH)|h-!|2wozJKmj z`G&1Z^{+00Fi|SEx@=o?UTI)xo@>T@7i7MZAqTYCMc0JP{oZJEdWye2L~bM45otrq zk@}$q6%b*2<$_YGZVC^6PBqU&pG6rtOM!WN;+E;i3EB*=+K0j60WC&J{7x}V=Ak(w<1X>er- zV`_bHI~Y%5hQkS?_Lf?1C-Yh;suT(z!ZdS6NOH8>FGetNtnE-ngIxI9OKM9M!nq|ao z@ByV)WU%+EiuxlBZ=#rs_ZnY%+O^bXr2P8_g2l~7Z8221w?Uyx%!zc@?f!tWxz6{`xAWPUyeq1Vbvuj7m$3Dh(PTY04bw^_A zwRr|LuoC34N#A1;?zXdaId|wW$kzq2e~Uqdrq=@A0^DlGO4UM zzCO9@&t7@ohLX-t)ftJ| z)q;&?w?;l@^4Pc`;x3vPJ8(itFdKg3;$nap8V7O~;L775>pjUjnIyS=0%4f;&$i;^ q^<`2=x-x(uk2YUU2h;2jemskO_4rHker(f@*'+~#\";.,=\\- \\/${}%?`]/g,\n\t\troot : '#'\n\t};\n\t\n\t/**\n\t * creates a jstree instance\n\t * @name $.jstree.create(el [, options])\n\t * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector\n\t * @param {Object} options options for this instance (extends `$.jstree.defaults`)\n\t * @return {jsTree} the new instance\n\t */\n\t$.jstree.create = function (el, options) {\n\t\tvar tmp = new $.jstree.core(++instance_counter),\n\t\t\topt = options;\n\t\toptions = $.extend(true, {}, $.jstree.defaults, options);\n\t\tif(opt && opt.plugins) {\n\t\t\toptions.plugins = opt.plugins;\n\t\t}\n\t\t$.each(options.plugins, function (i, k) {\n\t\t\tif(i !== 'core') {\n\t\t\t\ttmp = tmp.plugin(k, options[k]);\n\t\t\t}\n\t\t});\n\t\t$(el).data('jstree', tmp);\n\t\ttmp.init(el, options);\n\t\treturn tmp;\n\t};\n\t/**\n\t * remove all traces of jstree from the DOM and destroy all instances\n\t * @name $.jstree.destroy()\n\t */\n\t$.jstree.destroy = function () {\n\t\t$('.jstree:jstree').jstree('destroy');\n\t\t$(document).off('.jstree');\n\t};\n\t/**\n\t * the jstree class constructor, used only internally\n\t * @private\n\t * @name $.jstree.core(id)\n\t * @param {Number} id this instance's index\n\t */\n\t$.jstree.core = function (id) {\n\t\tthis._id = id;\n\t\tthis._cnt = 0;\n\t\tthis._wrk = null;\n\t\tthis._data = {\n\t\t\tcore : {\n\t\t\t\tthemes : {\n\t\t\t\t\tname : false,\n\t\t\t\t\tdots : false,\n\t\t\t\t\ticons : false,\n\t\t\t\t\tellipsis : false\n\t\t\t\t},\n\t\t\t\tselected : [],\n\t\t\t\tlast_error : {},\n\t\t\t\tworking : false,\n\t\t\t\tworker_queue : [],\n\t\t\t\tfocused : null\n\t\t\t}\n\t\t};\n\t};\n\t/**\n\t * get a reference to an existing instance\n\t *\n\t * __Examples__\n\t *\n\t *\t// provided a container with an ID of \"tree\", and a nested node with an ID of \"branch\"\n\t *\t// all of there will return the same instance\n\t *\t$.jstree.reference('tree');\n\t *\t$.jstree.reference('#tree');\n\t *\t$.jstree.reference($('#tree'));\n\t *\t$.jstree.reference(document.getElementByID('tree'));\n\t *\t$.jstree.reference('branch');\n\t *\t$.jstree.reference('#branch');\n\t *\t$.jstree.reference($('#branch'));\n\t *\t$.jstree.reference(document.getElementByID('branch'));\n\t *\n\t * @name $.jstree.reference(needle)\n\t * @param {DOMElement|jQuery|String} needle\n\t * @return {jsTree|null} the instance or `null` if not found\n\t */\n\t$.jstree.reference = function (needle) {\n\t\tvar tmp = null,\n\t\t\tobj = null;\n\t\tif(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; }\n\n\t\tif(!obj || !obj.length) {\n\t\t\ttry { obj = $(needle); } catch (ignore) { }\n\t\t}\n\t\tif(!obj || !obj.length) {\n\t\t\ttry { obj = $('#' + needle.replace($.jstree.idregex,'\\\\$&')); } catch (ignore) { }\n\t\t}\n\t\tif(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) {\n\t\t\ttmp = obj;\n\t\t}\n\t\telse {\n\t\t\t$('.jstree').each(function () {\n\t\t\t\tvar inst = $(this).data('jstree');\n\t\t\t\tif(inst && inst._model.data[needle]) {\n\t\t\t\t\ttmp = inst;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn tmp;\n\t};\n\t/**\n\t * Create an instance, get an instance or invoke a command on a instance.\n\t *\n\t * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken).\n\t *\n\t * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function).\n\t *\n\t * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`).\n\t *\n\t * In any other case - nothing is returned and chaining is not broken.\n\t *\n\t * __Examples__\n\t *\n\t *\t$('#tree1').jstree(); // creates an instance\n\t *\t$('#tree2').jstree({ plugins : [] }); // create an instance with some options\n\t *\t$('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments\n\t *\t$('#tree2').jstree(); // get an existing instance (or create an instance)\n\t *\t$('#tree2').jstree(true); // get an existing instance (will not create new instance)\n\t *\t$('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method)\n\t *\n\t * @name $().jstree([arg])\n\t * @param {String|Object} arg\n\t * @return {Mixed}\n\t */\n\t$.fn.jstree = function (arg) {\n\t\t// check for string argument\n\t\tvar is_method\t= (typeof arg === 'string'),\n\t\t\targs\t\t= Array.prototype.slice.call(arguments, 1),\n\t\t\tresult\t\t= null;\n\t\tif(arg === true && !this.length) { return false; }\n\t\tthis.each(function () {\n\t\t\t// get the instance (if there is one) and method (if it exists)\n\t\t\tvar instance = $.jstree.reference(this),\n\t\t\t\tmethod = is_method && instance ? instance[arg] : null;\n\t\t\t// if calling a method, and method is available - execute on the instance\n\t\t\tresult = is_method && method ?\n\t\t\t\tmethod.apply(instance, args) :\n\t\t\t\tnull;\n\t\t\t// if there is no instance and no method is being called - create one\n\t\t\tif(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) {\n\t\t\t\t$.jstree.create(this, arg);\n\t\t\t}\n\t\t\t// if there is an instance and no method is called - return the instance\n\t\t\tif( (instance && !is_method) || arg === true ) {\n\t\t\t\tresult = instance || false;\n\t\t\t}\n\t\t\t// if there was a method call which returned a result - break and return the value\n\t\t\tif(result !== null && result !== undefined) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\t// if there was a method call with a valid return value - return that, otherwise continue the chain\n\t\treturn result !== null && result !== undefined ?\n\t\t\tresult : this;\n\t};\n\t/**\n\t * used to find elements containing an instance\n\t *\n\t * __Examples__\n\t *\n\t *\t$('div:jstree').each(function () {\n\t *\t\t$(this).jstree('destroy');\n\t *\t});\n\t *\n\t * @name $(':jstree')\n\t * @return {jQuery}\n\t */\n\t$.expr.pseudos.jstree = $.expr.createPseudo(function(search) {\n\t\treturn function(a) {\n\t\t\treturn $(a).hasClass('jstree') &&\n\t\t\t\t$(a).data('jstree') !== undefined;\n\t\t};\n\t});\n\n\t/**\n\t * stores all defaults for the core\n\t * @name $.jstree.defaults.core\n\t */\n\t$.jstree.defaults.core = {\n\t\t/**\n\t\t * data configuration\n\t\t *\n\t\t * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items).\n\t\t *\n\t\t * You can also pass in a HTML string or a JSON array here.\n\t\t *\n\t\t * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree.\n\t\t * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used.\n\t\t *\n\t\t * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result.\n\t\t *\n\t\t * __Examples__\n\t\t *\n\t\t *\t// AJAX\n\t\t *\t$('#tree').jstree({\n\t\t *\t\t'core' : {\n\t\t *\t\t\t'data' : {\n\t\t *\t\t\t\t'url' : '/get/children/',\n\t\t *\t\t\t\t'data' : function (node) {\n\t\t *\t\t\t\t\treturn { 'id' : node.id };\n\t\t *\t\t\t\t}\n\t\t *\t\t\t}\n\t\t *\t\t});\n\t\t *\n\t\t *\t// direct data\n\t\t *\t$('#tree').jstree({\n\t\t *\t\t'core' : {\n\t\t *\t\t\t'data' : [\n\t\t *\t\t\t\t'Simple root node',\n\t\t *\t\t\t\t{\n\t\t *\t\t\t\t\t'id' : 'node_2',\n\t\t *\t\t\t\t\t'text' : 'Root node with options',\n\t\t *\t\t\t\t\t'state' : { 'opened' : true, 'selected' : true },\n\t\t *\t\t\t\t\t'children' : [ { 'text' : 'Child 1' }, 'Child 2']\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 *\t// function\n\t\t *\t$('#tree').jstree({\n\t\t *\t\t'core' : {\n\t\t *\t\t\t'data' : function (obj, callback) {\n\t\t *\t\t\t\tcallback.call(this, ['Root 1', 'Root 2']);\n\t\t *\t\t\t}\n\t\t *\t\t});\n\t\t *\n\t\t * @name $.jstree.defaults.core.data\n\t\t */\n\t\tdata\t\t\t: false,\n\t\t/**\n\t\t * configure the various strings used throughout the tree\n\t\t *\n\t\t * You can use an object where the key is the string you need to replace and the value is your replacement.\n\t\t * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement.\n\t\t * If left as `false` no replacement is made.\n\t\t *\n\t\t * __Examples__\n\t\t *\n\t\t *\t$('#tree').jstree({\n\t\t *\t\t'core' : {\n\t\t *\t\t\t'strings' : {\n\t\t *\t\t\t\t'Loading ...' : 'Please wait ...'\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\t});\n\t\t *\n\t\t * @name $.jstree.defaults.core.strings\n\t\t */\n\t\tstrings\t\t\t: false,\n\t\t/**\n\t\t * determines what happens when a user tries to modify the structure of the tree\n\t\t * If left as `false` all operations like create, rename, delete, move or copy are prevented.\n\t\t * You can set this to `true` to allow all interactions or use a function to have better control.\n\t\t *\n\t\t * __Examples__\n\t\t *\n\t\t *\t$('#tree').jstree({\n\t\t *\t\t'core' : {\n\t\t *\t\t\t'check_callback' : function (operation, node, node_parent, node_position, more) {\n\t\t *\t\t\t\t// operation can be 'create_node', 'rename_node', 'delete_node', 'move_node', 'copy_node' or 'edit'\n\t\t *\t\t\t\t// in case of 'rename_node' node_position is filled with the new node name\n\t\t *\t\t\t\treturn operation === 'rename_node' ? true : false;\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\t});\n\t\t *\n\t\t * @name $.jstree.defaults.core.check_callback\n\t\t */\n\t\tcheck_callback\t: false,\n\t\t/**\n\t\t * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc)\n\t\t * @name $.jstree.defaults.core.error\n\t\t */\n\t\terror\t\t\t: $.noop,\n\t\t/**\n\t\t * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`)\n\t\t * @name $.jstree.defaults.core.animation\n\t\t */\n\t\tanimation\t\t: 200,\n\t\t/**\n\t\t * a boolean indicating if multiple nodes can be selected\n\t\t * @name $.jstree.defaults.core.multiple\n\t\t */\n\t\tmultiple\t\t: true,\n\t\t/**\n\t\t * theme configuration object\n\t\t * @name $.jstree.defaults.core.themes\n\t\t */\n\t\tthemes\t\t\t: {\n\t\t\t/**\n\t\t\t * the name of the theme to use (if left as `false` the default theme is used)\n\t\t\t * @name $.jstree.defaults.core.themes.name\n\t\t\t */\n\t\t\tname\t\t\t: false,\n\t\t\t/**\n\t\t\t * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme.\n\t\t\t * @name $.jstree.defaults.core.themes.url\n\t\t\t */\n\t\t\turl\t\t\t\t: false,\n\t\t\t/**\n\t\t\t * the location of all jstree themes - only used if `url` is set to `true`\n\t\t\t * @name $.jstree.defaults.core.themes.dir\n\t\t\t */\n\t\t\tdir\t\t\t\t: false,\n\t\t\t/**\n\t\t\t * a boolean indicating if connecting dots are shown\n\t\t\t * @name $.jstree.defaults.core.themes.dots\n\t\t\t */\n\t\t\tdots\t\t\t: true,\n\t\t\t/**\n\t\t\t * a boolean indicating if node icons are shown\n\t\t\t * @name $.jstree.defaults.core.themes.icons\n\t\t\t */\n\t\t\ticons\t\t\t: true,\n\t\t\t/**\n\t\t\t * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container\n\t\t\t * @name $.jstree.defaults.core.themes.ellipsis\n\t\t\t */\n\t\t\tellipsis\t\t: false,\n\t\t\t/**\n\t\t\t * a boolean indicating if the tree background is striped\n\t\t\t * @name $.jstree.defaults.core.themes.stripes\n\t\t\t */\n\t\t\tstripes\t\t\t: false,\n\t\t\t/**\n\t\t\t * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants)\n\t\t\t * @name $.jstree.defaults.core.themes.variant\n\t\t\t */\n\t\t\tvariant\t\t\t: false,\n\t\t\t/**\n\t\t\t * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`.\n\t\t\t * @name $.jstree.defaults.core.themes.responsive\n\t\t\t */\n\t\t\tresponsive\t\t: false\n\t\t},\n\t\t/**\n\t\t * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user)\n\t\t * @name $.jstree.defaults.core.expand_selected_onload\n\t\t */\n\t\texpand_selected_onload : true,\n\t\t/**\n\t\t * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true`\n\t\t * @name $.jstree.defaults.core.worker\n\t\t */\n\t\tworker : true,\n\t\t/**\n\t\t * Force node text to plain text (and escape HTML). Defaults to `false`\n\t\t * @name $.jstree.defaults.core.force_text\n\t\t */\n\t\tforce_text : false,\n\t\t/**\n\t\t * Should the node be toggled if the text is double clicked. Defaults to `true`\n\t\t * @name $.jstree.defaults.core.dblclick_toggle\n\t\t */\n\t\tdblclick_toggle : true,\n\t\t/**\n\t\t * Should the loaded nodes be part of the state. Defaults to `false`\n\t\t * @name $.jstree.defaults.core.loaded_state\n\t\t */\n\t\tloaded_state : false,\n\t\t/**\n\t\t * Should the last active node be focused when the tree container is blurred and the focused again. This helps working with screen readers. Defaults to `true`\n\t\t * @name $.jstree.defaults.core.restore_focus\n\t\t */\n\t\trestore_focus : true,\n\t\t/**\n\t\t * Force to compute and set \"aria-setsize\" and \"aria-posinset\" explicitly for each treeitem. \n\t\t * Some browsers may compute incorrect elements position and produce wrong announcements for screen readers. Defaults to `false`\n\t\t * @name $.jstree.defaults.core.compute_elements_positions\n\t\t */\n\t\tcompute_elements_positions : false,\n\t\t/**\n\t\t * Default keyboard shortcuts (an object where each key is the button name or combo - like 'enter', 'ctrl-space', 'p', etc and the value is the function to execute in the instance's scope)\n\t\t * @name $.jstree.defaults.core.keyboard\n\t\t */\n\t\tkeyboard : {\n\t\t\t'ctrl-space': function (e) {\n\t\t\t\t// aria defines space only with Ctrl\n\t\t\t\te.type = \"click\";\n\t\t\t\t$(e.currentTarget).trigger(e);\n\t\t\t},\n\t\t\t'enter': function (e) {\n\t\t\t\t// enter\n\t\t\t\te.type = \"click\";\n\t\t\t\t$(e.currentTarget).trigger(e);\n\t\t\t},\n\t\t\t'left': function (e) {\n\t\t\t\t// left\n\t\t\t\te.preventDefault();\n\t\t\t\tif(this.is_open(e.currentTarget)) {\n\t\t\t\t\tthis.close_node(e.currentTarget);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar o = this.get_parent(e.currentTarget);\n\t\t\t\t\tif(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').trigger('focus'); }\n\t\t\t\t}\n\t\t\t},\n\t\t\t'up': function (e) {\n\t\t\t\t// up\n\t\t\t\te.preventDefault();\n\t\t\t\tvar o = this.get_prev_dom(e.currentTarget);\n\t\t\t\tif(o && o.length) { o.children('.jstree-anchor').trigger('focus'); }\n\t\t\t},\n\t\t\t'right': function (e) {\n\t\t\t\t// right\n\t\t\t\te.preventDefault();\n\t\t\t\tif(this.is_closed(e.currentTarget)) {\n\t\t\t\t\tthis.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').trigger('focus'); });\n\t\t\t\t}\n\t\t\t\telse if (this.is_open(e.currentTarget)) {\n\t\t\t\t\tvar o = this.get_node(e.currentTarget, true).children('.jstree-children')[0];\n\t\t\t\t\tif(o) { $(this._firstChild(o)).children('.jstree-anchor').trigger('focus'); }\n\t\t\t\t}\n\t\t\t},\n\t\t\t'down': function (e) {\n\t\t\t\t// down\n\t\t\t\te.preventDefault();\n\t\t\t\tvar o = this.get_next_dom(e.currentTarget);\n\t\t\t\tif(o && o.length) { o.children('.jstree-anchor').trigger('focus'); }\n\t\t\t},\n\t\t\t'*': function (e) {\n\t\t\t\t// aria defines * on numpad as open_all - not very common\n\t\t\t\tthis.open_all();\n\t\t\t},\n\t\t\t'home': function (e) {\n\t\t\t\t// home\n\t\t\t\te.preventDefault();\n\t\t\t\tvar o = this._firstChild(this.get_container_ul()[0]);\n\t\t\t\tif(o) { $(o).children('.jstree-anchor').filter(':visible').trigger('focus'); }\n\t\t\t},\n\t\t\t'end': function (e) {\n\t\t\t\t// end\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.element.find('.jstree-anchor').filter(':visible').last().trigger('focus');\n\t\t\t},\n\t\t\t'f2': function (e) {\n\t\t\t\t// f2 - safe to include - if check_callback is false it will fail\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.edit(e.currentTarget);\n\t\t\t}\n\t\t}\n\t};\n\t$.jstree.core.prototype = {\n\t\t/**\n\t\t * used to decorate an instance with a plugin. Used internally.\n\t\t * @private\n\t\t * @name plugin(deco [, opts])\n\t\t * @param {String} deco the plugin to decorate with\n\t\t * @param {Object} opts options for the plugin\n\t\t * @return {jsTree}\n\t\t */\n\t\tplugin : function (deco, opts) {\n\t\t\tvar Child = $.jstree.plugins[deco];\n\t\t\tif(Child) {\n\t\t\t\tthis._data[deco] = {};\n\t\t\t\tChild.prototype = this;\n\t\t\t\treturn new Child(opts, this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\t/**\n\t\t * initialize the instance. Used internally.\n\t\t * @private\n\t\t * @name init(el, optons)\n\t\t * @param {DOMElement|jQuery|String} el the element we are transforming\n\t\t * @param {Object} options options for this instance\n\t\t * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree\n\t\t */\n\t\tinit : function (el, options) {\n\t\t\tthis._model = {\n\t\t\t\tdata : {},\n\t\t\t\tchanged : [],\n\t\t\t\tforce_full_redraw : false,\n\t\t\t\tredraw_timeout : false,\n\t\t\t\tdefault_state : {\n\t\t\t\t\tloaded : true,\n\t\t\t\t\topened : false,\n\t\t\t\t\tselected : false,\n\t\t\t\t\tdisabled : false\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis._model.data[$.jstree.root] = {\n\t\t\t\tid : $.jstree.root,\n\t\t\t\tparent : null,\n\t\t\t\tparents : [],\n\t\t\t\tchildren : [],\n\t\t\t\tchildren_d : [],\n\t\t\t\tstate : { loaded : false }\n\t\t\t};\n\n\t\t\tthis.element = $(el).addClass('jstree jstree-' + this._id);\n\t\t\tthis.settings = options;\n\n\t\t\tthis._data.core.ready = false;\n\t\t\tthis._data.core.loaded = false;\n\t\t\tthis._data.core.rtl = (this.element.css(\"direction\") === \"rtl\");\n\t\t\tthis.element[this._data.core.rtl ? 'addClass' : 'removeClass'](\"jstree-rtl\");\n\t\t\tthis.element.attr('role','tree');\n\t\t\tif(this.settings.core.multiple) {\n\t\t\t\tthis.element.attr('aria-multiselectable', true);\n\t\t\t}\n\t\t\tif(!this.element.attr('tabindex')) {\n\t\t\t\tthis.element.attr('tabindex','0');\n\t\t\t}\n\n\t\t\tthis.bind();\n\t\t\t/**\n\t\t\t * triggered after all events are bound\n\t\t\t * @event\n\t\t\t * @name init.jstree\n\t\t\t */\n\t\t\tthis.trigger(\"init\");\n\n\t\t\tthis._data.core.original_container_html = this.element.find(\" > ul > li\").clone(true);\n\t\t\tthis._data.core.original_container_html\n\t\t\t\t.find(\"li\").addBack()\n\t\t\t\t.contents().filter(function() {\n\t\t\t\t\treturn this.nodeType === 3 && (!this.nodeValue || /^\\s+$/.test(this.nodeValue));\n\t\t\t\t})\n\t\t\t\t.remove();\n\t\t\tthis.element.html(\"<\"+\"ul class='jstree-container-ul jstree-children' role='group'><\"+\"li id='j\"+this._id+\"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='none'><\"+\"a class='jstree-anchor' role='treeitem' href='#'>\" + this.get_string(\"Loading ...\") + \"

      • \");\n\t\t\tthis.element.attr('aria-activedescendant','j' + this._id + '_loading');\n\t\t\tthis._data.core.li_height = this.get_container_ul().children(\"li\").first().outerHeight() || 24;\n\t\t\tthis._data.core.node = this._create_prototype_node();\n\t\t\t/**\n\t\t\t * triggered after the loading text is shown and before loading starts\n\t\t\t * @event\n\t\t\t * @name loading.jstree\n\t\t\t */\n\t\t\tthis.trigger(\"loading\");\n\t\t\tthis.load_node($.jstree.root);\n\t\t},\n\t\t/**\n\t\t * destroy an instance\n\t\t * @name destroy()\n\t\t * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact\n\t\t */\n\t\tdestroy : function (keep_html) {\n\t\t\t/**\n\t\t\t * triggered before the tree is destroyed\n\t\t\t * @event\n\t\t\t * @name destroy.jstree\n\t\t\t */\n\t\t\tthis.trigger(\"destroy\");\n\t\t\tif(this._wrk) {\n\t\t\t\ttry {\n\t\t\t\t\twindow.URL.revokeObjectURL(this._wrk);\n\t\t\t\t\tthis._wrk = null;\n\t\t\t\t}\n\t\t\t\tcatch (ignore) { }\n\t\t\t}\n\t\t\tif(!keep_html) { this.element.empty(); }\n\t\t\tthis.teardown();\n\t\t},\n\t\t/**\n\t\t * Create a prototype node\n\t\t * @name _create_prototype_node()\n\t\t * @return {DOMElement}\n\t\t */\n\t\t_create_prototype_node : function () {\n\t\t\tvar _node = document.createElement('LI'), _temp1, _temp2;\n\t\t\t_node.setAttribute('role', 'none');\n\t\t\t_temp1 = document.createElement('I');\n\t\t\t_temp1.className = 'jstree-icon jstree-ocl';\n\t\t\t_temp1.setAttribute('role', 'presentation');\n\t\t\t_node.appendChild(_temp1);\n\t\t\t_temp1 = document.createElement('A');\n\t\t\t_temp1.className = 'jstree-anchor';\n\t\t\t_temp1.setAttribute('href','#');\n\t\t\t_temp1.setAttribute('tabindex','-1');\n\t\t\t_temp1.setAttribute('role', 'treeitem');\n\t\t\t_temp2 = document.createElement('I');\n\t\t\t_temp2.className = 'jstree-icon jstree-themeicon';\n\t\t\t_temp2.setAttribute('role', 'presentation');\n\t\t\t_temp1.appendChild(_temp2);\n\t\t\t_node.appendChild(_temp1);\n\t\t\t_temp1 = _temp2 = null;\n\n\t\t\treturn _node;\n\t\t},\n\t\t_kbevent_to_func : function (e) {\n\t\t\tvar keys = {\n\t\t\t\t8: \"Backspace\", 9: \"Tab\", 13: \"Enter\", 19: \"Pause\", 27: \"Esc\",\n\t\t\t\t32: \"Space\", 33: \"PageUp\", 34: \"PageDown\", 35: \"End\", 36: \"Home\",\n\t\t\t\t37: \"Left\", 38: \"Up\", 39: \"Right\", 40: \"Down\", 44: \"Print\", 45: \"Insert\",\n\t\t\t\t46: \"Delete\", 96: \"Numpad0\", 97: \"Numpad1\", 98: \"Numpad2\", 99 : \"Numpad3\",\n\t\t\t\t100: \"Numpad4\", 101: \"Numpad5\", 102: \"Numpad6\", 103: \"Numpad7\",\n\t\t\t\t104: \"Numpad8\", 105: \"Numpad9\", '-13': \"NumpadEnter\", 112: \"F1\",\n\t\t\t\t113: \"F2\", 114: \"F3\", 115: \"F4\", 116: \"F5\", 117: \"F6\", 118: \"F7\",\n\t\t\t\t119: \"F8\", 120: \"F9\", 121: \"F10\", 122: \"F11\", 123: \"F12\", 144: \"Numlock\",\n\t\t\t\t145: \"Scrolllock\", 16: 'Shift', 17: 'Ctrl', 18: 'Alt',\n\t\t\t\t48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',\n\t\t\t\t54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',\n\t\t\t\t66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',\n\t\t\t\t73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',\n\t\t\t\t80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',\n\t\t\t\t87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',\n\t\t\t\t186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`',\n\t\t\t\t219: '[', 220: '\\\\',221: ']', 222: \"'\", 111: '/', 106: '*', 173: '-'\n\t\t\t};\n\t\t\tvar parts = [];\n\t\t\tif (e.ctrlKey) { parts.push('ctrl'); }\n\t\t\tif (e.altKey) { parts.push('alt'); }\n if (e.shiftKey) { parts.push('shift'); }\n\t\t\tparts.push(keys[e.which] ? keys[e.which].toLowerCase() : e.which);\n parts = parts.sort().join('-').toLowerCase();\n if (parts === 'shift-shift' || parts === 'ctrl-ctrl' || parts === 'alt-alt') {\n return null;\n }\n\n\t\t\tvar kb = this.settings.core.keyboard, i, tmp;\n\t\t\tfor (i in kb) {\n\t\t\t\tif (kb.hasOwnProperty(i)) {\n\t\t\t\t\ttmp = i;\n\t\t\t\t\tif (tmp !== '-' && tmp !== '+') {\n\t\t\t\t\t\ttmp = tmp.replace('--', '-MINUS').replace('+-', '-MINUS').replace('++', '-PLUS').replace('-+', '-PLUS');\n\t\t\t\t\t\ttmp = tmp.split(/-|\\+/).sort().join('-').replace('MINUS', '-').replace('PLUS', '+').toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (tmp === parts) {\n\t\t\t\t\t\treturn kb[i];\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 * part of the destroying of an instance. Used internally.\n\t\t * @private\n\t\t * @name teardown()\n\t\t */\n\t\tteardown : function () {\n\t\t\tthis.unbind();\n\t\t\tthis.element\n\t\t\t\t.removeClass('jstree')\n\t\t\t\t.removeData('jstree')\n\t\t\t\t.find(\"[class^='jstree']\")\n\t\t\t\t\t.addBack()\n\t\t\t\t\t.attr(\"class\", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });\n\t\t\tthis.element = null;\n\t\t},\n\t\t/**\n\t\t * bind all events. Used internally.\n\t\t * @private\n\t\t * @name bind()\n\t\t */\n\t\tbind : function () {\n\t\t\tvar word = '',\n\t\t\t\ttout = null,\n\t\t\t\twas_click = 0;\n\t\t\tthis.element\n\t\t\t\t.on(\"dblclick.jstree\", function (e) {\n\t\t\t\t\t\tif(e.target.tagName && e.target.tagName.toLowerCase() === \"input\") { return true; }\n\t\t\t\t\t\tif(document.selection && document.selection.empty) {\n\t\t\t\t\t\t\tdocument.selection.empty();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tif(window.getSelection) {\n\t\t\t\t\t\t\t\tvar sel = window.getSelection();\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tsel.removeAllRanges();\n\t\t\t\t\t\t\t\t\tsel.collapse();\n\t\t\t\t\t\t\t\t} catch (ignore) { }\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.on(\"mousedown.jstree\", function (e) {\n\t\t\t\t\t\tif(e.target === this.element[0]) {\n\t\t\t\t\t\t\te.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome)\n\t\t\t\t\t\t\twas_click = +(new Date()); // ie does not allow to prevent losing focus\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"mousedown.jstree\", \".jstree-ocl\", function (e) {\n\t\t\t\t\t\te.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon\n\t\t\t\t\t})\n\t\t\t\t.on(\"click.jstree\", \".jstree-ocl\", function (e) {\n\t\t\t\t\t\tthis.toggle_node(e.target);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"dblclick.jstree\", \".jstree-anchor\", function (e) {\n\t\t\t\t\t\tif(e.target.tagName && e.target.tagName.toLowerCase() === \"input\") { return true; }\n\t\t\t\t\t\tif(this.settings.core.dblclick_toggle) {\n\t\t\t\t\t\t\tthis.toggle_node(e.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"click.jstree\", \".jstree-anchor\", function (e) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif(e.currentTarget !== document.activeElement) { $(e.currentTarget).trigger('focus'); }\n\t\t\t\t\t\tthis.activate_node(e.currentTarget, e);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('keydown.jstree', '.jstree-anchor', function (e) {\n\t\t\t\t\t\tif(e.target.tagName && e.target.tagName.toLowerCase() === \"input\") { return true; }\n\t\t\t\t\t\tif(this._data.core.rtl) {\n\t\t\t\t\t\t\tif(e.which === 37) { e.which = 39; }\n\t\t\t\t\t\t\telse if(e.which === 39) { e.which = 37; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar f = this._kbevent_to_func(e);\n\t\t\t\t\t\tif (f) {\n\t\t\t\t\t\t\tvar r = f.call(this, e);\n\t\t\t\t\t\t\tif (r === false || r === true) {\n\t\t\t\t\t\t\t\treturn r;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"load_node.jstree\", function (e, data) {\n\t\t\t\t\t\tif(data.status) {\n\t\t\t\t\t\t\tif(data.node.id === $.jstree.root && !this._data.core.loaded) {\n\t\t\t\t\t\t\t\tthis._data.core.loaded = true;\n\t\t\t\t\t\t\t\tif(this._firstChild(this.get_container_ul()[0])) {\n\t\t\t\t\t\t\t\t\tthis.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t\t * triggered after the root node is loaded for the first time\n\t\t\t\t\t\t\t\t * @event\n\t\t\t\t\t\t\t\t * @name loaded.jstree\n\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\tthis.trigger(\"loaded\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!this._data.core.ready) {\n\t\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\t\tif(this.element && !this.get_container_ul().find('.jstree-loading').length) {\n\t\t\t\t\t\t\t\t\t\tthis._data.core.ready = true;\n\t\t\t\t\t\t\t\t\t\tif(this._data.core.selected.length) {\n\t\t\t\t\t\t\t\t\t\t\tif(this.settings.core.expand_selected_onload) {\n\t\t\t\t\t\t\t\t\t\t\t\tvar tmp = [], i, j;\n\t\t\t\t\t\t\t\t\t\t\t\tfor(i = 0, j = this._data.core.selected.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\ttmp = $.vakata.array_unique(tmp);\n\t\t\t\t\t\t\t\t\t\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis.open_node(tmp[i], false, 0);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tthis.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected });\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t\t\t\t * triggered after all nodes are finished loading\n\t\t\t\t\t\t\t\t\t\t * @event\n\t\t\t\t\t\t\t\t\t\t * @name ready.jstree\n\t\t\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\t\t\tthis.trigger(\"ready\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}.bind(this), 0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t// quick searching when the tree is focused\n\t\t\t\t.on('keypress.jstree', function (e) {\n\t\t\t\t\t\tif(e.target.tagName && e.target.tagName.toLowerCase() === \"input\") { return true; }\n\t\t\t\t\t\tif(tout) { clearTimeout(tout); }\n\t\t\t\t\t\ttout = setTimeout(function () {\n\t\t\t\t\t\t\tword = '';\n\t\t\t\t\t\t}, 500);\n\n\t\t\t\t\t\tvar chr = String.fromCharCode(e.which).toLowerCase(),\n\t\t\t\t\t\t\tcol = this.element.find('.jstree-anchor').filter(':visible'),\n\t\t\t\t\t\t\tind = col.index(document.activeElement) || 0,\n\t\t\t\t\t\t\tend = false;\n\t\t\t\t\t\tword += chr;\n\n\t\t\t\t\t\t// match for whole word from current node down (including the current node)\n\t\t\t\t\t\tif(word.length > 1) {\n\t\t\t\t\t\t\tcol.slice(ind).each(function (i, v) {\n\t\t\t\t\t\t\t\tif($(v).text().toLowerCase().indexOf(word) === 0) {\n\t\t\t\t\t\t\t\t\t$(v).trigger('focus');\n\t\t\t\t\t\t\t\t\tend = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t\t\tif(end) { return; }\n\n\t\t\t\t\t\t\t// match for whole word from the beginning of the tree\n\t\t\t\t\t\t\tcol.slice(0, ind).each(function (i, v) {\n\t\t\t\t\t\t\t\tif($(v).text().toLowerCase().indexOf(word) === 0) {\n\t\t\t\t\t\t\t\t\t$(v).trigger('focus');\n\t\t\t\t\t\t\t\t\tend = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t\t\tif(end) { return; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// list nodes that start with that letter (only if word consists of a single char)\n\t\t\t\t\t\tif(new RegExp('^' + chr.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&') + '+$').test(word)) {\n\t\t\t\t\t\t\t// search for the next node starting with that letter\n\t\t\t\t\t\t\tcol.slice(ind + 1).each(function (i, v) {\n\t\t\t\t\t\t\t\tif($(v).text().toLowerCase().charAt(0) === chr) {\n\t\t\t\t\t\t\t\t\t$(v).trigger('focus');\n\t\t\t\t\t\t\t\t\tend = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t\t\tif(end) { return; }\n\n\t\t\t\t\t\t\t// search from the beginning\n\t\t\t\t\t\t\tcol.slice(0, ind + 1).each(function (i, v) {\n\t\t\t\t\t\t\t\tif($(v).text().toLowerCase().charAt(0) === chr) {\n\t\t\t\t\t\t\t\t\t$(v).trigger('focus');\n\t\t\t\t\t\t\t\t\tend = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t\t\tif(end) { return; }\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t// THEME RELATED\n\t\t\t\t.on(\"init.jstree\", function () {\n\t\t\t\t\t\tvar s = this.settings.core.themes;\n\t\t\t\t\t\tthis._data.core.themes.dots\t\t\t= s.dots;\n\t\t\t\t\t\tthis._data.core.themes.stripes\t\t= s.stripes;\n\t\t\t\t\t\tthis._data.core.themes.icons\t\t= s.icons;\n\t\t\t\t\t\tthis._data.core.themes.ellipsis\t\t= s.ellipsis;\n\t\t\t\t\t\tthis.set_theme(s.name || \"default\", s.url);\n\t\t\t\t\t\tthis.set_theme_variant(s.variant);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"loading.jstree\", function () {\n\t\t\t\t\t\tthis[ this._data.core.themes.dots ? \"show_dots\" : \"hide_dots\" ]();\n\t\t\t\t\t\tthis[ this._data.core.themes.icons ? \"show_icons\" : \"hide_icons\" ]();\n\t\t\t\t\t\tthis[ this._data.core.themes.stripes ? \"show_stripes\" : \"hide_stripes\" ]();\n\t\t\t\t\t\tthis[ this._data.core.themes.ellipsis ? \"show_ellipsis\" : \"hide_ellipsis\" ]();\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('blur.jstree', '.jstree-anchor', function (e) {\n\t\t\t\t\t\tthis._data.core.focused = null;\n\t\t\t\t\t\t$(e.currentTarget).filter('.jstree-hovered').trigger('mouseleave');\n\t\t\t\t\t\tthis.element.attr('tabindex', '0');\n\t\t\t\t\t\t$(e.currentTarget).attr('tabindex', '-1');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('focus.jstree', '.jstree-anchor', function (e) {\n\t\t\t\t\t\tvar tmp = this.get_node(e.currentTarget);\n\t\t\t\t\t\tif(tmp && tmp.id) {\n\t\t\t\t\t\t\tthis._data.core.focused = tmp.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.element.find('.jstree-hovered').not(e.currentTarget).trigger('mouseleave');\n\t\t\t\t\t\t$(e.currentTarget).trigger('mouseenter');\n\t\t\t\t\t\tthis.element.attr('tabindex', '-1');\n\t\t\t\t\t\t$(e.currentTarget).attr('tabindex', '0');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('focus.jstree', function () {\n\t\t\t\t\t\tif(+(new Date()) - was_click > 500 && !this._data.core.focused && this.settings.core.restore_focus) {\n\t\t\t\t\t\t\twas_click = 0;\n\t\t\t\t\t\t\tvar act = this.get_node(this.element.attr('aria-activedescendant'), true);\n\t\t\t\t\t\t\tif(act) {\n\t\t\t\t\t\t\t\tact.find('> .jstree-anchor').trigger('focus');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('mouseenter.jstree', '.jstree-anchor', function (e) {\n\t\t\t\t\t\tthis.hover_node(e.currentTarget);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on('mouseleave.jstree', '.jstree-anchor', function (e) {\n\t\t\t\t\t\tthis.dehover_node(e.currentTarget);\n\t\t\t\t\t}.bind(this));\n\t\t},\n\t\t/**\n\t\t * part of the destroying of an instance. Used internally.\n\t\t * @private\n\t\t * @name unbind()\n\t\t */\n\t\tunbind : function () {\n\t\t\tthis.element.off('.jstree');\n\t\t\t$(document).off('.jstree-' + this._id);\n\t\t},\n\t\t/**\n\t\t * trigger an event. Used internally.\n\t\t * @private\n\t\t * @name trigger(ev [, data])\n\t\t * @param {String} ev the name of the event to trigger\n\t\t * @param {Object} data additional data to pass with the event\n\t\t */\n\t\ttrigger : function (ev, data) {\n\t\t\tif(!data) {\n\t\t\t\tdata = {};\n\t\t\t}\n\t\t\tdata.instance = this;\n\t\t\tthis.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data);\n\t\t},\n\t\t/**\n\t\t * returns the jQuery extended instance container\n\t\t * @name get_container()\n\t\t * @return {jQuery}\n\t\t */\n\t\tget_container : function () {\n\t\t\treturn this.element;\n\t\t},\n\t\t/**\n\t\t * returns the jQuery extended main UL node inside the instance container. Used internally.\n\t\t * @private\n\t\t * @name get_container_ul()\n\t\t * @return {jQuery}\n\t\t */\n\t\tget_container_ul : function () {\n\t\t\treturn this.element.children(\".jstree-children\").first();\n\t\t},\n\t\t/**\n\t\t * gets string replacements (localization). Used internally.\n\t\t * @private\n\t\t * @name get_string(key)\n\t\t * @param {String} key\n\t\t * @return {String}\n\t\t */\n\t\tget_string : function (key) {\n\t\t\tvar a = this.settings.core.strings;\n\t\t\tif($.vakata.is_function(a)) { return a.call(this, key); }\n\t\t\tif(a && a[key]) { return a[key]; }\n\t\t\treturn key;\n\t\t},\n\t\t/**\n\t\t * gets the first child of a DOM node. Used internally.\n\t\t * @private\n\t\t * @name _firstChild(dom)\n\t\t * @param {DOMElement} dom\n\t\t * @return {DOMElement}\n\t\t */\n\t\t_firstChild : function (dom) {\n\t\t\tdom = dom ? dom.firstChild : null;\n\t\t\twhile(dom !== null && dom.nodeType !== 1) {\n\t\t\t\tdom = dom.nextSibling;\n\t\t\t}\n\t\t\treturn dom;\n\t\t},\n\t\t/**\n\t\t * gets the next sibling of a DOM node. Used internally.\n\t\t * @private\n\t\t * @name _nextSibling(dom)\n\t\t * @param {DOMElement} dom\n\t\t * @return {DOMElement}\n\t\t */\n\t\t_nextSibling : function (dom) {\n\t\t\tdom = dom ? dom.nextSibling : null;\n\t\t\twhile(dom !== null && dom.nodeType !== 1) {\n\t\t\t\tdom = dom.nextSibling;\n\t\t\t}\n\t\t\treturn dom;\n\t\t},\n\t\t/**\n\t\t * gets the previous sibling of a DOM node. Used internally.\n\t\t * @private\n\t\t * @name _previousSibling(dom)\n\t\t * @param {DOMElement} dom\n\t\t * @return {DOMElement}\n\t\t */\n\t\t_previousSibling : function (dom) {\n\t\t\tdom = dom ? dom.previousSibling : null;\n\t\t\twhile(dom !== null && dom.nodeType !== 1) {\n\t\t\t\tdom = dom.previousSibling;\n\t\t\t}\n\t\t\treturn dom;\n\t\t},\n\t\t/**\n\t\t * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc)\n\t\t * @name get_node(obj [, as_dom])\n\t\t * @param {mixed} obj\n\t\t * @param {Boolean} as_dom\n\t\t * @return {Object|jQuery}\n\t\t */\n\t\tget_node : function (obj, as_dom) {\n\t\t\tif(obj && obj.id) {\n\t\t\t\tobj = obj.id;\n\t\t\t}\n\t\t\tif (obj instanceof $ && obj.length && obj[0].id) {\n\t\t\t\tobj = obj[0].id;\n\t\t\t}\n\t\t\tvar dom;\n\t\t\ttry {\n\t\t\t\tif(this._model.data[obj]) {\n\t\t\t\t\tobj = this._model.data[obj];\n\t\t\t\t}\n\t\t\t\telse if(typeof obj === \"string\" && this._model.data[obj.replace(/^#/, '')]) {\n\t\t\t\t\tobj = this._model.data[obj.replace(/^#/, '')];\n\t\t\t\t}\n\t\t\t\telse if(typeof obj === \"string\" && (dom = $('#' + obj.replace($.jstree.idregex,'\\\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {\n\t\t\t\t\tobj = this._model.data[dom.closest('.jstree-node').attr('id')];\n\t\t\t\t}\n\t\t\t\telse if((dom = this.element.find(obj)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {\n\t\t\t\t\tobj = this._model.data[dom.closest('.jstree-node').attr('id')];\n\t\t\t\t}\n\t\t\t\telse if((dom = this.element.find(obj)).length && dom.hasClass('jstree')) {\n\t\t\t\t\tobj = this._model.data[$.jstree.root];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif(as_dom) {\n\t\t\t\t\tobj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\\\$&'), this.element);\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t} catch (ex) { return false; }\n\t\t},\n\t\t/**\n\t\t * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array)\n\t\t * @name get_path(obj [, glue, ids])\n\t\t * @param {mixed} obj the node\n\t\t * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned\n\t\t * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used\n\t\t * @return {mixed}\n\t\t */\n\t\tget_path : function (obj, glue, ids) {\n\t\t\tobj = obj.parents ? obj : this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root || !obj.parents) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar i, j, p = [];\n\t\t\tp.push(ids ? obj.id : obj.text);\n\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\tp.push(ids ? obj.parents[i] : this.get_text(obj.parents[i]));\n\t\t\t}\n\t\t\tp = p.reverse().slice(1);\n\t\t\treturn glue ? p.join(glue) : p;\n\t\t},\n\t\t/**\n\t\t * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned.\n\t\t * @name get_next_dom(obj [, strict])\n\t\t * @param {mixed} obj\n\t\t * @param {Boolean} strict\n\t\t * @return {jQuery}\n\t\t */\n\t\tget_next_dom : function (obj, strict) {\n\t\t\tvar tmp;\n\t\t\tobj = this.get_node(obj, true);\n\t\t\tif(obj[0] === this.element[0]) {\n\t\t\t\ttmp = this._firstChild(this.get_container_ul()[0]);\n\t\t\t\twhile (tmp && tmp.offsetHeight === 0) {\n\t\t\t\t\ttmp = this._nextSibling(tmp);\n\t\t\t\t}\n\t\t\t\treturn tmp ? $(tmp) : false;\n\t\t\t}\n\t\t\tif(!obj || !obj.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(strict) {\n\t\t\t\ttmp = obj[0];\n\t\t\t\tdo {\n\t\t\t\t\ttmp = this._nextSibling(tmp);\n\t\t\t\t} while (tmp && tmp.offsetHeight === 0);\n\t\t\t\treturn tmp ? $(tmp) : false;\n\t\t\t}\n\t\t\tif(obj.hasClass(\"jstree-open\")) {\n\t\t\t\ttmp = this._firstChild(obj.children('.jstree-children')[0]);\n\t\t\t\twhile (tmp && tmp.offsetHeight === 0) {\n\t\t\t\t\ttmp = this._nextSibling(tmp);\n\t\t\t\t}\n\t\t\t\tif(tmp !== null) {\n\t\t\t\t\treturn $(tmp);\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp = obj[0];\n\t\t\tdo {\n\t\t\t\ttmp = this._nextSibling(tmp);\n\t\t\t} while (tmp && tmp.offsetHeight === 0);\n\t\t\tif(tmp !== null) {\n\t\t\t\treturn $(tmp);\n\t\t\t}\n\t\t\treturn obj.parentsUntil(\".jstree\",\".jstree-node\").nextAll(\".jstree-node:visible\").first();\n\t\t},\n\t\t/**\n\t\t * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned.\n\t\t * @name get_prev_dom(obj [, strict])\n\t\t * @param {mixed} obj\n\t\t * @param {Boolean} strict\n\t\t * @return {jQuery}\n\t\t */\n\t\tget_prev_dom : function (obj, strict) {\n\t\t\tvar tmp;\n\t\t\tobj = this.get_node(obj, true);\n\t\t\tif(obj[0] === this.element[0]) {\n\t\t\t\ttmp = this.get_container_ul()[0].lastChild;\n\t\t\t\twhile (tmp && tmp.offsetHeight === 0) {\n\t\t\t\t\ttmp = this._previousSibling(tmp);\n\t\t\t\t}\n\t\t\t\treturn tmp ? $(tmp) : false;\n\t\t\t}\n\t\t\tif(!obj || !obj.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(strict) {\n\t\t\t\ttmp = obj[0];\n\t\t\t\tdo {\n\t\t\t\t\ttmp = this._previousSibling(tmp);\n\t\t\t\t} while (tmp && tmp.offsetHeight === 0);\n\t\t\t\treturn tmp ? $(tmp) : false;\n\t\t\t}\n\t\t\ttmp = obj[0];\n\t\t\tdo {\n\t\t\t\ttmp = this._previousSibling(tmp);\n\t\t\t} while (tmp && tmp.offsetHeight === 0);\n\t\t\tif(tmp !== null) {\n\t\t\t\tobj = $(tmp);\n\t\t\t\twhile(obj.hasClass(\"jstree-open\")) {\n\t\t\t\t\tobj = obj.children(\".jstree-children\").first().children(\".jstree-node:visible:last\");\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t}\n\t\t\ttmp = obj[0].parentNode.parentNode;\n\t\t\treturn tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false;\n\t\t},\n\t\t/**\n\t\t * get the parent ID of a node\n\t\t * @name get_parent(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {String}\n\t\t */\n\t\tget_parent : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn obj.parent;\n\t\t},\n\t\t/**\n\t\t * get a jQuery collection of all the children of a node (node must be rendered), returns false on error\n\t\t * @name get_children_dom(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {jQuery}\n\t\t */\n\t\tget_children_dom : function (obj) {\n\t\t\tobj = this.get_node(obj, true);\n\t\t\tif(obj[0] === this.element[0]) {\n\t\t\t\treturn this.get_container_ul().children(\".jstree-node\");\n\t\t\t}\n\t\t\tif(!obj || !obj.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn obj.children(\".jstree-children\").children(\".jstree-node\");\n\t\t},\n\t\t/**\n\t\t * checks if a node has children\n\t\t * @name is_parent(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_parent : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && (obj.state.loaded === false || obj.children.length > 0);\n\t\t},\n\t\t/**\n\t\t * checks if a node is loaded (its children are available)\n\t\t * @name is_loaded(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_loaded : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && obj.state.loaded;\n\t\t},\n\t\t/**\n\t\t * check if a node is currently loading (fetching children)\n\t\t * @name is_loading(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_loading : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && obj.state && obj.state.loading;\n\t\t},\n\t\t/**\n\t\t * check if a node is opened\n\t\t * @name is_open(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_open : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && obj.state.opened;\n\t\t},\n\t\t/**\n\t\t * check if a node is in a closed state\n\t\t * @name is_closed(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_closed : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && this.is_parent(obj) && !obj.state.opened;\n\t\t},\n\t\t/**\n\t\t * check if a node has no children\n\t\t * @name is_leaf(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_leaf : function (obj) {\n\t\t\treturn !this.is_parent(obj);\n\t\t},\n\t\t/**\n\t\t * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array.\n\t\t * @name load_node(obj [, callback])\n\t\t * @param {mixed} obj\n\t\t * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status\n\t\t * @return {Boolean}\n\t\t * @trigger load_node.jstree\n\t\t */\n\t\tload_node : function (obj, callback) {\n\t\t\tvar dom = this.get_node(obj, true), k, l, i, j, c;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tthis._load_nodes(obj.slice(), callback);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) {\n\t\t\t\tif(callback) { callback.call(this, obj, false); }\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again?\n\t\t\tif(obj.state.loaded) {\n\t\t\t\tobj.state.loaded = false;\n\t\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\t\tthis._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) {\n\t\t\t\t\t\treturn $.inArray(v, obj.children_d) === -1;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tfor(k = 0, l = obj.children_d.length; k < l; k++) {\n\t\t\t\t\tif(this._model.data[obj.children_d[k]].state.selected) {\n\t\t\t\t\t\tc = true;\n\t\t\t\t\t}\n\t\t\t\t\tdelete this._model.data[obj.children_d[k]];\n\t\t\t\t}\n\t\t\t\tif (c) {\n\t\t\t\t\tthis._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) {\n\t\t\t\t\t\treturn $.inArray(v, obj.children_d) === -1;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tobj.children = [];\n\t\t\t\tobj.children_d = [];\n\t\t\t\tif(c) {\n\t\t\t\t\tthis.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected });\n\t\t\t\t}\n\t\t\t}\n\t\t\tobj.state.failed = false;\n\t\t\tobj.state.loading = true;\n\t\t\tif (obj.id !== $.jstree.root) {\n\t\t\t\tdom.children(\".jstree-anchor\").attr('aria-busy', true);\n\t\t\t} else {\n\t\t\t\tdom.attr('aria-busy', true);\n\t\t\t}\n\t\t\tdom.addClass(\"jstree-loading\");\n\t\t\tthis._load_node(obj, function (status) {\n\t\t\t\tobj = this._model.data[obj.id];\n\t\t\t\tobj.state.loading = false;\n\t\t\t\tobj.state.loaded = status;\n\t\t\t\tobj.state.failed = !obj.state.loaded;\n\t\t\t\tvar dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false;\n\t\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\t\tif(m[obj.children[i]] && !m[obj.children[i]].state.hidden) {\n\t\t\t\t\t\thas_children = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(obj.state.loaded && dom && dom.length) {\n\t\t\t\t\tdom.removeClass('jstree-closed jstree-open jstree-leaf');\n\t\t\t\t\tif (!has_children) {\n\t\t\t\t\t\tdom.addClass('jstree-leaf');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (obj.id !== '#') {\n\t\t\t\t\t\t\tdom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (obj.id !== $.jstree.root) {\n\t\t\t\t\tdom.children(\".jstree-anchor\").attr('aria-busy', false);\n\t\t\t\t} else {\n\t\t\t\t\tdom.attr('aria-busy', false);\n\t\t\t\t}\n\t\t\t\tdom.removeClass(\"jstree-loading\");\n\t\t\t\t/**\n\t\t\t\t * triggered after a node is loaded\n\t\t\t\t * @event\n\t\t\t\t * @name load_node.jstree\n\t\t\t\t * @param {Object} node the node that was loading\n\t\t\t\t * @param {Boolean} status was the node loaded successfully\n\t\t\t\t */\n\t\t\t\tthis.trigger('load_node', { \"node\" : obj, \"status\" : status });\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback.call(this, obj, status);\n\t\t\t\t}\n\t\t\t}.bind(this));\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * load an array of nodes (will also load unavailable nodes as soon as they appear in the structure). Used internally.\n\t\t * @private\n\t\t * @name _load_nodes(nodes [, callback])\n\t\t * @param {array} nodes\n\t\t * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes\n\t\t */\n\t\t_load_nodes : function (nodes, callback, is_callback, force_reload) {\n\t\t\tvar r = true,\n\t\t\t\tc = function () { this._load_nodes(nodes, callback, true); },\n\t\t\t\tm = this._model.data, i, j, tmp = [];\n\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\tif(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) {\n\t\t\t\t\tif(!this.is_loading(nodes[i])) {\n\t\t\t\t\t\tthis.load_node(nodes[i], c);\n\t\t\t\t\t}\n\t\t\t\t\tr = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(r) {\n\t\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\t\tif(m[nodes[i]] && m[nodes[i]].state.loaded) {\n\t\t\t\t\t\ttmp.push(nodes[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(callback && !callback.done) {\n\t\t\t\t\tcallback.call(this, tmp);\n\t\t\t\t\tcallback.done = true;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * loads all unloaded nodes\n\t\t * @name load_all([obj, callback])\n\t\t * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree\n\t\t * @param {function} callback a function to be executed once loading all the nodes is complete,\n\t\t * @trigger load_all.jstree\n\t\t */\n\t\tload_all : function (obj, callback) {\n\t\t\tif(!obj) { obj = $.jstree.root; }\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) { return false; }\n\t\t\tvar to_load = [],\n\t\t\t\tm = this._model.data,\n\t\t\t\tc = m[obj.id].children_d,\n\t\t\t\ti, j;\n\t\t\tif(obj.state && !obj.state.loaded) {\n\t\t\t\tto_load.push(obj.id);\n\t\t\t}\n\t\t\tfor(i = 0, j = c.length; i < j; i++) {\n\t\t\t\tif(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) {\n\t\t\t\t\tto_load.push(c[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(to_load.length) {\n\t\t\t\tthis._load_nodes(to_load, function () {\n\t\t\t\t\tthis.load_all(obj, callback);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/**\n\t\t\t\t * triggered after a load_all call completes\n\t\t\t\t * @event\n\t\t\t\t * @name load_all.jstree\n\t\t\t\t * @param {Object} node the recursively loaded node\n\t\t\t\t */\n\t\t\t\tif(callback) { callback.call(this, obj); }\n\t\t\t\tthis.trigger('load_all', { \"node\" : obj });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * handles the actual loading of a node. Used only internally.\n\t\t * @private\n\t\t * @name _load_node(obj [, callback])\n\t\t * @param {mixed} obj\n\t\t * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status\n\t\t * @return {Boolean}\n\t\t */\n\t\t_load_node : function (obj, callback) {\n\t\t\tvar s = this.settings.core.data, t;\n\t\t\tvar notTextOrCommentNode = function notTextOrCommentNode () {\n\t\t\t\treturn this.nodeType !== 3 && this.nodeType !== 8;\n\t\t\t};\n\t\t\t// use original HTML\n\t\t\tif(!s) {\n\t\t\t\tif(obj.id === $.jstree.root) {\n\t\t\t\t\treturn this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) {\n\t\t\t\t\t\tcallback.call(this, status);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn callback.call(this, false);\n\t\t\t\t}\n\t\t\t\t// return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);\n\t\t\t}\n\t\t\tif($.vakata.is_function(s)) {\n\t\t\t\treturn s.call(this, obj, function (d) {\n\t\t\t\t\tif(d === false) {\n\t\t\t\t\t\tcallback.call(this, false);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) {\n\t\t\t\t\t\t\tcallback.call(this, status);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d));\n\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t\tif(typeof s === 'object') {\n\t\t\t\tif(s.url) {\n\t\t\t\t\ts = $.extend(true, {}, s);\n\t\t\t\t\tif($.vakata.is_function(s.url)) {\n\t\t\t\t\t\ts.url = s.url.call(this, obj);\n\t\t\t\t\t}\n\t\t\t\t\tif($.vakata.is_function(s.data)) {\n\t\t\t\t\t\ts.data = s.data.call(this, obj);\n\t\t\t\t\t}\n\t\t\t\t\treturn $.ajax(s)\n\t\t\t\t\t\t.done(function (d,t,x) {\n\t\t\t\t\t\t\t\tvar type = x.getResponseHeader('Content-Type');\n\t\t\t\t\t\t\t\tif((type && type.indexOf('json') !== -1) || typeof d === \"object\") {\n\t\t\t\t\t\t\t\t\treturn this._append_json_data(obj, d, function (status) { callback.call(this, status); });\n\t\t\t\t\t\t\t\t\t//return callback.call(this, this._append_json_data(obj, d));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif((type && type.indexOf('html') !== -1) || typeof d === \"string\") {\n\t\t\t\t\t\t\t\t\treturn this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); });\n\t\t\t\t\t\t\t\t\t// return callback.call(this, this._append_html_data(obj, $(d)));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) };\n\t\t\t\t\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\t\t\t\t\treturn callback.call(this, false);\n\t\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t\t.fail(function (f) {\n\t\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) };\n\t\t\t\t\t\t\t\tcallback.call(this, false);\n\t\t\t\t\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t}\n\t\t\t\tif ($.vakata.is_array(s)) {\n\t\t\t\t\tt = $.extend(true, [], s);\n\t\t\t\t} else if ($.isPlainObject(s)) {\n\t\t\t\t\tt = $.extend(true, {}, s);\n\t\t\t\t} else {\n\t\t\t\t\tt = s;\n\t\t\t\t}\n\t\t\t\tif(obj.id === $.jstree.root) {\n\t\t\t\t\treturn this._append_json_data(obj, t, function (status) {\n\t\t\t\t\t\tcallback.call(this, status);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };\n\t\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\t\treturn callback.call(this, false);\n\t\t\t\t}\n\t\t\t\t//return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) );\n\t\t\t}\n\t\t\tif(typeof s === 'string') {\n\t\t\t\tif(obj.id === $.jstree.root) {\n\t\t\t\t\treturn this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) {\n\t\t\t\t\t\tcallback.call(this, status);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };\n\t\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\t\treturn callback.call(this, false);\n\t\t\t\t}\n\t\t\t\t//return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) );\n\t\t\t}\n\t\t\treturn callback.call(this, false);\n\t\t},\n\t\t/**\n\t\t * adds a node to the list of nodes to redraw. Used only internally.\n\t\t * @private\n\t\t * @name _node_changed(obj [, callback])\n\t\t * @param {mixed} obj\n\t\t */\n\t\t_node_changed : function (obj) {\n\t\t\tobj = this.get_node(obj);\n if (obj && $.inArray(obj.id, this._model.changed) === -1) {\n\t\t\t\tthis._model.changed.push(obj.id);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * appends HTML content to the tree. Used internally.\n\t\t * @private\n\t\t * @name _append_html_data(obj, data)\n\t\t * @param {mixed} obj the node to append to\n\t\t * @param {String} data the HTML string to parse and append\n\t\t * @trigger model.jstree, changed.jstree\n\t\t */\n\t\t_append_html_data : function (dom, data, cb) {\n\t\t\tdom = this.get_node(dom);\n\t\t\tdom.children = [];\n\t\t\tdom.children_d = [];\n\t\t\tvar dat = data.is('ul') ? data.children() : data,\n\t\t\t\tpar = dom.id,\n\t\t\t\tchd = [],\n\t\t\t\tdpc = [],\n\t\t\t\tm = this._model.data,\n\t\t\t\tp = m[par],\n\t\t\t\ts = this._data.core.selected.length,\n\t\t\t\ttmp, i, j;\n\t\t\tdat.each(function (i, v) {\n\t\t\t\ttmp = this._parse_model_from_html($(v), par, p.parents.concat());\n\t\t\t\tif(tmp) {\n\t\t\t\t\tchd.push(tmp);\n\t\t\t\t\tdpc.push(tmp);\n\t\t\t\t\tif(m[tmp].children_d.length) {\n\t\t\t\t\t\tdpc = dpc.concat(m[tmp].children_d);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}.bind(this));\n\t\t\tp.children = chd;\n\t\t\tp.children_d = dpc;\n\t\t\tfor(i = 0, j = p.parents.length; i < j; i++) {\n\t\t\t\tm[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when new data is inserted to the tree model\n\t\t\t * @event\n\t\t\t * @name model.jstree\n\t\t\t * @param {Array} nodes an array of node IDs\n\t\t\t * @param {String} parent the parent ID of the nodes\n\t\t\t */\n\t\t\tthis.trigger('model', { \"nodes\" : dpc, 'parent' : par });\n\t\t\tif(par !== $.jstree.root) {\n\t\t\t\tthis._node_changed(par);\n\t\t\t\tthis.redraw();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.get_container_ul().children('.jstree-initial-node').remove();\n\t\t\t\tthis.redraw(true);\n\t\t\t}\n\t\t\tif(this._data.core.selected.length !== s) {\n\t\t\t\tthis.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });\n\t\t\t}\n\t\t\tcb.call(this, true);\n\t\t},\n\t\t/**\n\t\t * appends JSON content to the tree. Used internally.\n\t\t * @private\n\t\t * @name _append_json_data(obj, data)\n\t\t * @param {mixed} obj the node to append to\n\t\t * @param {String} data the JSON object to parse and append\n\t\t * @param {Boolean} force_processing internal param - do not set\n\t\t * @trigger model.jstree, changed.jstree\n\t\t */\n\t\t_append_json_data : function (dom, data, cb, force_processing) {\n\t\t\tif(this.element === null) { return; }\n\t\t\tdom = this.get_node(dom);\n\t\t\tdom.children = [];\n\t\t\tdom.children_d = [];\n\t\t\t// *%$@!!!\n\t\t\tif(data.d) {\n\t\t\t\tdata = data.d;\n\t\t\t\tif(typeof data === \"string\") {\n\t\t\t\t\tdata = JSON.parse(data);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!$.vakata.is_array(data)) { data = [data]; }\n\t\t\tvar w = null,\n\t\t\t\targs = {\n\t\t\t\t\t'df'\t: this._model.default_state,\n\t\t\t\t\t'dat'\t: data,\n\t\t\t\t\t'par'\t: dom.id,\n\t\t\t\t\t'm'\t\t: this._model.data,\n\t\t\t\t\t't_id'\t: this._id,\n\t\t\t\t\t't_cnt'\t: this._cnt,\n\t\t\t\t\t'sel'\t: this._data.core.selected\n\t\t\t\t},\n\t\t\t\tinst = this,\n\t\t\t\tfunc = function (data, undefined) {\n\t\t\t\t\tif(data.data) { data = data.data; }\n\t\t\t\t\tvar dat = data.dat,\n\t\t\t\t\t\tpar = data.par,\n\t\t\t\t\t\tchd = [],\n\t\t\t\t\t\tdpc = [],\n\t\t\t\t\t\tadd = [],\n\t\t\t\t\t\tdf = data.df,\n\t\t\t\t\t\tt_id = data.t_id,\n\t\t\t\t\t\tt_cnt = data.t_cnt,\n\t\t\t\t\t\tm = data.m,\n\t\t\t\t\t\tp = m[par],\n\t\t\t\t\t\tsel = data.sel,\n\t\t\t\t\t\ttmp, i, j, rslt,\n\t\t\t\t\t\tparse_flat = function (d, p, ps) {\n\t\t\t\t\t\t\tif(!ps) { ps = []; }\n\t\t\t\t\t\t\telse { ps = ps.concat(); }\n\t\t\t\t\t\t\tif(p) { ps.unshift(p); }\n\t\t\t\t\t\t\tvar tid = d.id.toString(),\n\t\t\t\t\t\t\t\ti, j, c, e,\n\t\t\t\t\t\t\t\ttmp = {\n\t\t\t\t\t\t\t\t\tid\t\t\t: tid,\n\t\t\t\t\t\t\t\t\ttext\t\t: d.text || '',\n\t\t\t\t\t\t\t\t\ticon\t\t: d.icon !== undefined ? d.icon : true,\n\t\t\t\t\t\t\t\t\tparent\t\t: p,\n\t\t\t\t\t\t\t\t\tparents\t\t: ps,\n\t\t\t\t\t\t\t\t\tchildren\t: d.children || [],\n\t\t\t\t\t\t\t\t\tchildren_d\t: d.children_d || [],\n\t\t\t\t\t\t\t\t\tdata\t\t: d.data,\n\t\t\t\t\t\t\t\t\tstate\t\t: { },\n\t\t\t\t\t\t\t\t\tli_attr\t\t: { id : false },\n\t\t\t\t\t\t\t\t\ta_attr\t\t: { href : '#' },\n\t\t\t\t\t\t\t\t\toriginal\t: false\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tfor(i in df) {\n\t\t\t\t\t\t\t\tif(df.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\ttmp.state[i] = df[i];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.data && d.data.jstree && d.data.jstree.icon) {\n\t\t\t\t\t\t\t\ttmp.icon = d.data.jstree.icon;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(tmp.icon === undefined || tmp.icon === null || tmp.icon === \"\") {\n\t\t\t\t\t\t\t\ttmp.icon = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.data) {\n\t\t\t\t\t\t\t\ttmp.data = d.data;\n\t\t\t\t\t\t\t\tif(d.data.jstree) {\n\t\t\t\t\t\t\t\t\tfor(i in d.data.jstree) {\n\t\t\t\t\t\t\t\t\t\tif(d.data.jstree.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.state[i] = d.data.jstree[i];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.state === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.state) {\n\t\t\t\t\t\t\t\t\tif(d.state.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.state[i] = d.state[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.li_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.li_attr) {\n\t\t\t\t\t\t\t\t\tif(d.li_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.li_attr[i] = d.li_attr[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!tmp.li_attr.id) {\n\t\t\t\t\t\t\t\ttmp.li_attr.id = tid;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.a_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.a_attr) {\n\t\t\t\t\t\t\t\t\tif(d.a_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.a_attr[i] = d.a_attr[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.children && d.children === true) {\n\t\t\t\t\t\t\t\ttmp.state.loaded = false;\n\t\t\t\t\t\t\t\ttmp.children = [];\n\t\t\t\t\t\t\t\ttmp.children_d = [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tm[tmp.id] = tmp;\n\t\t\t\t\t\t\tfor(i = 0, j = tmp.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\tc = parse_flat(m[tmp.children[i]], tmp.id, ps);\n\t\t\t\t\t\t\t\te = m[c];\n\t\t\t\t\t\t\t\ttmp.children_d.push(c);\n\t\t\t\t\t\t\t\tif(e.children_d.length) {\n\t\t\t\t\t\t\t\t\ttmp.children_d = tmp.children_d.concat(e.children_d);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete d.data;\n\t\t\t\t\t\t\tdelete d.children;\n\t\t\t\t\t\t\tm[tmp.id].original = d;\n\t\t\t\t\t\t\tif(tmp.state.selected) {\n\t\t\t\t\t\t\t\tadd.push(tmp.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn tmp.id;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tparse_nest = function (d, p, ps) {\n\t\t\t\t\t\t\tif(!ps) { ps = []; }\n\t\t\t\t\t\t\telse { ps = ps.concat(); }\n\t\t\t\t\t\t\tif(p) { ps.unshift(p); }\n\t\t\t\t\t\t\tvar tid = false, i, j, c, e, tmp;\n\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\ttid = 'j' + t_id + '_' + (++t_cnt);\n\t\t\t\t\t\t\t} while(m[tid]);\n\n\t\t\t\t\t\t\ttmp = {\n\t\t\t\t\t\t\t\tid\t\t\t: false,\n\t\t\t\t\t\t\t\ttext\t\t: typeof d === 'string' ? d : '',\n\t\t\t\t\t\t\t\ticon\t\t: typeof d === 'object' && d.icon !== undefined ? d.icon : true,\n\t\t\t\t\t\t\t\tparent\t\t: p,\n\t\t\t\t\t\t\t\tparents\t\t: ps,\n\t\t\t\t\t\t\t\tchildren\t: [],\n\t\t\t\t\t\t\t\tchildren_d\t: [],\n\t\t\t\t\t\t\t\tdata\t\t: null,\n\t\t\t\t\t\t\t\tstate\t\t: { },\n\t\t\t\t\t\t\t\tli_attr\t\t: { id : false },\n\t\t\t\t\t\t\t\ta_attr\t\t: { href : '#' },\n\t\t\t\t\t\t\t\toriginal\t: false\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tfor(i in df) {\n\t\t\t\t\t\t\t\tif(df.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\ttmp.state[i] = df[i];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.id) { tmp.id = d.id.toString(); }\n\t\t\t\t\t\t\tif(d && d.text) { tmp.text = d.text; }\n\t\t\t\t\t\t\tif(d && d.data && d.data.jstree && d.data.jstree.icon) {\n\t\t\t\t\t\t\t\ttmp.icon = d.data.jstree.icon;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(tmp.icon === undefined || tmp.icon === null || tmp.icon === \"\") {\n\t\t\t\t\t\t\t\ttmp.icon = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.data) {\n\t\t\t\t\t\t\t\ttmp.data = d.data;\n\t\t\t\t\t\t\t\tif(d.data.jstree) {\n\t\t\t\t\t\t\t\t\tfor(i in d.data.jstree) {\n\t\t\t\t\t\t\t\t\t\tif(d.data.jstree.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.state[i] = d.data.jstree[i];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.state === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.state) {\n\t\t\t\t\t\t\t\t\tif(d.state.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.state[i] = d.state[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.li_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.li_attr) {\n\t\t\t\t\t\t\t\t\tif(d.li_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.li_attr[i] = d.li_attr[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(tmp.li_attr.id && !tmp.id) {\n\t\t\t\t\t\t\t\ttmp.id = tmp.li_attr.id.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!tmp.id) {\n\t\t\t\t\t\t\t\ttmp.id = tid;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!tmp.li_attr.id) {\n\t\t\t\t\t\t\t\ttmp.li_attr.id = tmp.id;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && typeof d.a_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (i in d.a_attr) {\n\t\t\t\t\t\t\t\t\tif(d.a_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\ttmp.a_attr[i] = d.a_attr[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.children && d.children.length) {\n\t\t\t\t\t\t\t\tfor(i = 0, j = d.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\tc = parse_nest(d.children[i], tmp.id, ps);\n\t\t\t\t\t\t\t\t\te = m[c];\n\t\t\t\t\t\t\t\t\ttmp.children.push(c);\n\t\t\t\t\t\t\t\t\tif(e.children_d.length) {\n\t\t\t\t\t\t\t\t\t\ttmp.children_d = tmp.children_d.concat(e.children_d);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttmp.children_d = tmp.children_d.concat(tmp.children);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(d && d.children && d.children === true) {\n\t\t\t\t\t\t\t\ttmp.state.loaded = false;\n\t\t\t\t\t\t\t\ttmp.children = [];\n\t\t\t\t\t\t\t\ttmp.children_d = [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete d.data;\n\t\t\t\t\t\t\tdelete d.children;\n\t\t\t\t\t\t\ttmp.original = d;\n\t\t\t\t\t\t\tm[tmp.id] = tmp;\n\t\t\t\t\t\t\tif(tmp.state.selected) {\n\t\t\t\t\t\t\t\tadd.push(tmp.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn tmp.id;\n\t\t\t\t\t\t};\n\n\t\t\t\t\tif(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) {\n\t\t\t\t\t\t// Flat JSON support (for easy import from DB):\n\t\t\t\t\t\t// 1) convert to object (foreach)\n\t\t\t\t\t\tfor(i = 0, j = dat.length; i < j; i++) {\n\t\t\t\t\t\t\tif(!dat[i].children) {\n\t\t\t\t\t\t\t\tdat[i].children = [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!dat[i].state) {\n\t\t\t\t\t\t\t\tdat[i].state = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tm[dat[i].id.toString()] = dat[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// 2) populate children (foreach)\n\t\t\t\t\t\tfor(i = 0, j = dat.length; i < j; i++) {\n\t\t\t\t\t\t\tif (!m[dat[i].parent.toString()]) {\n\t\t\t\t\t\t\t\tif (typeof inst !== \"undefined\") {\n\t\t\t\t\t\t\t\t\tinst._data.core.last_error = { 'error' : 'parse', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Node with invalid parent', 'data' : JSON.stringify({ 'id' : dat[i].id.toString(), 'parent' : dat[i].parent.toString() }) };\n\t\t\t\t\t\t\t\t\tinst.settings.core.error.call(inst, inst._data.core.last_error);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tm[dat[i].parent.toString()].children.push(dat[i].id.toString());\n\t\t\t\t\t\t\t// populate parent.children_d\n\t\t\t\t\t\t\tp.children_d.push(dat[i].id.toString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// 3) normalize && populate parents and children_d with recursion\n\t\t\t\t\t\tfor(i = 0, j = p.children.length; i < j; i++) {\n\t\t\t\t\t\t\ttmp = parse_flat(m[p.children[i]], par, p.parents.concat());\n\t\t\t\t\t\t\tdpc.push(tmp);\n\t\t\t\t\t\t\tif(m[tmp].children_d.length) {\n\t\t\t\t\t\t\t\tdpc = dpc.concat(m[tmp].children_d);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(i = 0, j = p.parents.length; i < j; i++) {\n\t\t\t\t\t\t\tm[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true;\n\t\t\t\t\t\trslt = {\n\t\t\t\t\t\t\t'cnt' : t_cnt,\n\t\t\t\t\t\t\t'mod' : m,\n\t\t\t\t\t\t\t'sel' : sel,\n\t\t\t\t\t\t\t'par' : par,\n\t\t\t\t\t\t\t'dpc' : dpc,\n\t\t\t\t\t\t\t'add' : add\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(i = 0, j = dat.length; i < j; i++) {\n\t\t\t\t\t\t\ttmp = parse_nest(dat[i], par, p.parents.concat());\n\t\t\t\t\t\t\tif(tmp) {\n\t\t\t\t\t\t\t\tchd.push(tmp);\n\t\t\t\t\t\t\t\tdpc.push(tmp);\n\t\t\t\t\t\t\t\tif(m[tmp].children_d.length) {\n\t\t\t\t\t\t\t\t\tdpc = dpc.concat(m[tmp].children_d);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.children = chd;\n\t\t\t\t\t\tp.children_d = dpc;\n\t\t\t\t\t\tfor(i = 0, j = p.parents.length; i < j; i++) {\n\t\t\t\t\t\t\tm[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trslt = {\n\t\t\t\t\t\t\t'cnt' : t_cnt,\n\t\t\t\t\t\t\t'mod' : m,\n\t\t\t\t\t\t\t'sel' : sel,\n\t\t\t\t\t\t\t'par' : par,\n\t\t\t\t\t\t\t'dpc' : dpc,\n\t\t\t\t\t\t\t'add' : add\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif(typeof window === 'undefined' || typeof window.document === 'undefined') {\n\t\t\t\t\t\tpostMessage(rslt);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treturn rslt;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\trslt = function (rslt, worker) {\n\t\t\t\t\tif(this.element === null) { return; }\n\t\t\t\t\tthis._cnt = rslt.cnt;\n\t\t\t\t\tvar i, m = this._model.data;\n\t\t\t\t\tfor (i in m) {\n\t\t\t\t\t\tif (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) {\n\t\t\t\t\t\t\trslt.mod[i].state.loading = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._model.data = rslt.mod; // breaks the reference in load_node - careful\n\n\t\t\t\t\tif(worker) {\n\t\t\t\t\t\tvar j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice();\n\t\t\t\t\t\tm = this._model.data;\n\t\t\t\t\t\t// if selection was changed while calculating in worker\n\t\t\t\t\t\tif(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) {\n\t\t\t\t\t\t\t// deselect nodes that are no longer selected\n\t\t\t\t\t\t\tfor(i = 0, j = r.length; i < j; i++) {\n\t\t\t\t\t\t\t\tif($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) {\n\t\t\t\t\t\t\t\t\tm[r[i]].state.selected = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// select nodes that were selected in the mean time\n\t\t\t\t\t\t\tfor(i = 0, j = s.length; i < j; i++) {\n\t\t\t\t\t\t\t\tif($.inArray(s[i], r) === -1) {\n\t\t\t\t\t\t\t\t\tm[s[i]].state.selected = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(rslt.add.length) {\n\t\t\t\t\t\tthis._data.core.selected = this._data.core.selected.concat(rslt.add);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.trigger('model', { \"nodes\" : rslt.dpc, 'parent' : rslt.par });\n\n\t\t\t\t\tif(rslt.par !== $.jstree.root) {\n\t\t\t\t\t\tthis._node_changed(rslt.par);\n\t\t\t\t\t\tthis.redraw();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// this.get_container_ul().children('.jstree-initial-node').remove();\n\t\t\t\t\t\tthis.redraw(true);\n\t\t\t\t\t}\n\t\t\t\t\tif(rslt.add.length) {\n\t\t\t\t\t\tthis.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });\n\t\t\t\t\t}\n\n\t\t\t\t\t// If no worker, try to mimic worker behavioour, by invoking cb asynchronously\n\t\t\t\t\tif (!worker && setImmediate) {\n\t\t\t\t\t\tsetImmediate(function(){\n\t\t\t\t\t\t\tcb.call(inst, true);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tcb.call(inst, true);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\tif(this.settings.core.worker && window.Blob && window.URL && window.Worker) {\n\t\t\t\ttry {\n\t\t\t\t\tif(this._wrk === null) {\n\t\t\t\t\t\tthis._wrk = window.URL.createObjectURL(\n\t\t\t\t\t\t\tnew window.Blob(\n\t\t\t\t\t\t\t\t['self.onmessage = ' + func.toString()],\n\t\t\t\t\t\t\t\t{type:\"text/javascript\"}\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\tif(!this._data.core.working || force_processing) {\n\t\t\t\t\t\tthis._data.core.working = true;\n\t\t\t\t\t\tw = new window.Worker(this._wrk);\n\t\t\t\t\t\tw.onmessage = function (e) {\n\t\t\t\t\t\t\trslt.call(this, e.data, true);\n\t\t\t\t\t\t\ttry { w.terminate(); w = null; } catch(ignore) { }\n\t\t\t\t\t\t\tif(this._data.core.worker_queue.length) {\n\t\t\t\t\t\t\t\tthis._append_json_data.apply(this, this._data.core.worker_queue.shift());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tthis._data.core.working = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}.bind(this);\n\t\t\t\t\t\tw.onerror = function (e) {\n\t\t\t\t\t\t\trslt.call(this, func(args), false);\n\t\t\t\t\t\t\tif(this._data.core.worker_queue.length) {\n\t\t\t\t\t\t\t\tthis._append_json_data.apply(this, this._data.core.worker_queue.shift());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tthis._data.core.working = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}.bind(this);\n\t\t\t\t\t\tif(!args.par) {\n\t\t\t\t\t\t\tif(this._data.core.worker_queue.length) {\n\t\t\t\t\t\t\t\tthis._append_json_data.apply(this, this._data.core.worker_queue.shift());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tthis._data.core.working = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tw.postMessage(args);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._data.core.worker_queue.push([dom, data, cb, true]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(e) {\n\t\t\t\t\trslt.call(this, func(args), false);\n\t\t\t\t\tif(this._data.core.worker_queue.length) {\n\t\t\t\t\t\tthis._append_json_data.apply(this, this._data.core.worker_queue.shift());\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._data.core.working = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\trslt.call(this, func(args), false);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * parses a node from a jQuery object and appends them to the in memory tree model. Used internally.\n\t\t * @private\n\t\t * @name _parse_model_from_html(d [, p, ps])\n\t\t * @param {jQuery} d the jQuery object to parse\n\t\t * @param {String} p the parent ID\n\t\t * @param {Array} ps list of all parents\n\t\t * @return {String} the ID of the object added to the model\n\t\t */\n\t\t_parse_model_from_html : function (d, p, ps) {\n\t\t\tif(!ps) { ps = []; }\n\t\t\telse { ps = [].concat(ps); }\n\t\t\tif(p) { ps.unshift(p); }\n\t\t\tvar c, e, m = this._model.data,\n\t\t\t\tdata = {\n\t\t\t\t\tid\t\t\t: false,\n\t\t\t\t\ttext\t\t: false,\n\t\t\t\t\ticon\t\t: true,\n\t\t\t\t\tparent\t\t: p,\n\t\t\t\t\tparents\t\t: ps,\n\t\t\t\t\tchildren\t: [],\n\t\t\t\t\tchildren_d\t: [],\n\t\t\t\t\tdata\t\t: null,\n\t\t\t\t\tstate\t\t: { },\n\t\t\t\t\tli_attr\t\t: { id : false },\n\t\t\t\t\ta_attr\t\t: { href : '#' },\n\t\t\t\t\toriginal\t: false\n\t\t\t\t}, i, tmp, tid;\n\t\t\tfor(i in this._model.default_state) {\n\t\t\t\tif(this._model.default_state.hasOwnProperty(i)) {\n\t\t\t\t\tdata.state[i] = this._model.default_state[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp = $.vakata.attributes(d, true);\n\t\t\t$.each(tmp, function (i, v) {\n\t\t\t\tv = $.vakata.trim(v);\n\t\t\t\tif(!v.length) { return true; }\n\t\t\t\tdata.li_attr[i] = v;\n\t\t\t\tif(i === 'id') {\n\t\t\t\t\tdata.id = v.toString();\n\t\t\t\t}\n\t\t\t});\n\t\t\ttmp = d.children('a').first();\n\t\t\tif(tmp.length) {\n\t\t\t\ttmp = $.vakata.attributes(tmp, true);\n\t\t\t\t$.each(tmp, function (i, v) {\n\t\t\t\t\tv = $.vakata.trim(v);\n\t\t\t\t\tif(v.length) {\n\t\t\t\t\t\tdata.a_attr[i] = v;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\ttmp = d.children(\"a\").first().length ? d.children(\"a\").first().clone() : d.clone();\n\t\t\ttmp.children(\"ins, i, ul\").remove();\n\t\t\ttmp = tmp.html();\n\t\t\ttmp = $('
        ').html(tmp);\n\t\t\tdata.text = this.settings.core.force_text ? tmp.text() : tmp.html();\n\t\t\ttmp = d.data();\n\t\t\tdata.data = tmp ? $.extend(true, {}, tmp) : null;\n\t\t\tdata.state.opened = d.hasClass('jstree-open');\n\t\t\tdata.state.selected = d.children('a').hasClass('jstree-clicked');\n\t\t\tdata.state.disabled = d.children('a').hasClass('jstree-disabled');\n\t\t\tif(data.data && data.data.jstree) {\n\t\t\t\tfor(i in data.data.jstree) {\n\t\t\t\t\tif(data.data.jstree.hasOwnProperty(i)) {\n\t\t\t\t\t\tdata.state[i] = data.data.jstree[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp = d.children(\"a\").children(\".jstree-themeicon\");\n\t\t\tif(tmp.length) {\n\t\t\t\tdata.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel');\n\t\t\t}\n\t\t\tif(data.state.icon !== undefined) {\n\t\t\t\tdata.icon = data.state.icon;\n\t\t\t}\n\t\t\tif(data.icon === undefined || data.icon === null || data.icon === \"\") {\n\t\t\t\tdata.icon = true;\n\t\t\t}\n\t\t\ttmp = d.children(\"ul\").children(\"li\");\n\t\t\tdo {\n\t\t\t\ttid = 'j' + this._id + '_' + (++this._cnt);\n\t\t\t} while(m[tid]);\n\t\t\tdata.id = data.li_attr.id ? data.li_attr.id.toString() : tid;\n\t\t\tif(tmp.length) {\n\t\t\t\ttmp.each(function (i, v) {\n\t\t\t\t\tc = this._parse_model_from_html($(v), data.id, ps);\n\t\t\t\t\te = this._model.data[c];\n\t\t\t\t\tdata.children.push(c);\n\t\t\t\t\tif(e.children_d.length) {\n\t\t\t\t\t\tdata.children_d = data.children_d.concat(e.children_d);\n\t\t\t\t\t}\n\t\t\t\t}.bind(this));\n\t\t\t\tdata.children_d = data.children_d.concat(data.children);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(d.hasClass('jstree-closed')) {\n\t\t\t\t\tdata.state.loaded = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(data.li_attr['class']) {\n\t\t\t\tdata.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open','');\n\t\t\t}\n\t\t\tif(data.a_attr['class']) {\n\t\t\t\tdata.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled','');\n\t\t\t}\n\t\t\tm[data.id] = data;\n\t\t\tif(data.state.selected) {\n\t\t\t\tthis._data.core.selected.push(data.id);\n\t\t\t}\n\t\t\treturn data.id;\n\t\t},\n\t\t/**\n\t\t * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally.\n\t\t * @private\n\t\t * @name _parse_model_from_flat_json(d [, p, ps])\n\t\t * @param {Object} d the JSON object to parse\n\t\t * @param {String} p the parent ID\n\t\t * @param {Array} ps list of all parents\n\t\t * @return {String} the ID of the object added to the model\n\t\t */\n\t\t_parse_model_from_flat_json : function (d, p, ps) {\n\t\t\tif(!ps) { ps = []; }\n\t\t\telse { ps = ps.concat(); }\n\t\t\tif(p) { ps.unshift(p); }\n\t\t\tvar tid = d.id.toString(),\n\t\t\t\tm = this._model.data,\n\t\t\t\tdf = this._model.default_state,\n\t\t\t\ti, j, c, e,\n\t\t\t\ttmp = {\n\t\t\t\t\tid\t\t\t: tid,\n\t\t\t\t\ttext\t\t: d.text || '',\n\t\t\t\t\ticon\t\t: d.icon !== undefined ? d.icon : true,\n\t\t\t\t\tparent\t\t: p,\n\t\t\t\t\tparents\t\t: ps,\n\t\t\t\t\tchildren\t: d.children || [],\n\t\t\t\t\tchildren_d\t: d.children_d || [],\n\t\t\t\t\tdata\t\t: d.data,\n\t\t\t\t\tstate\t\t: { },\n\t\t\t\t\tli_attr\t\t: { id : false },\n\t\t\t\t\ta_attr\t\t: { href : '#' },\n\t\t\t\t\toriginal\t: false\n\t\t\t\t};\n\t\t\tfor(i in df) {\n\t\t\t\tif(df.hasOwnProperty(i)) {\n\t\t\t\t\ttmp.state[i] = df[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && d.data && d.data.jstree && d.data.jstree.icon) {\n\t\t\t\ttmp.icon = d.data.jstree.icon;\n\t\t\t}\n\t\t\tif(tmp.icon === undefined || tmp.icon === null || tmp.icon === \"\") {\n\t\t\t\ttmp.icon = true;\n\t\t\t}\n\t\t\tif(d && d.data) {\n\t\t\t\ttmp.data = d.data;\n\t\t\t\tif(d.data.jstree) {\n\t\t\t\t\tfor(i in d.data.jstree) {\n\t\t\t\t\t\tif(d.data.jstree.hasOwnProperty(i)) {\n\t\t\t\t\t\t\ttmp.state[i] = d.data.jstree[i];\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\tif(d && typeof d.state === 'object') {\n\t\t\t\tfor (i in d.state) {\n\t\t\t\t\tif(d.state.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.state[i] = d.state[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && typeof d.li_attr === 'object') {\n\t\t\t\tfor (i in d.li_attr) {\n\t\t\t\t\tif(d.li_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.li_attr[i] = d.li_attr[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!tmp.li_attr.id) {\n\t\t\t\ttmp.li_attr.id = tid;\n\t\t\t}\n\t\t\tif(d && typeof d.a_attr === 'object') {\n\t\t\t\tfor (i in d.a_attr) {\n\t\t\t\t\tif(d.a_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.a_attr[i] = d.a_attr[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && d.children && d.children === true) {\n\t\t\t\ttmp.state.loaded = false;\n\t\t\t\ttmp.children = [];\n\t\t\t\ttmp.children_d = [];\n\t\t\t}\n\t\t\tm[tmp.id] = tmp;\n\t\t\tfor(i = 0, j = tmp.children.length; i < j; i++) {\n\t\t\t\tc = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps);\n\t\t\t\te = m[c];\n\t\t\t\ttmp.children_d.push(c);\n\t\t\t\tif(e.children_d.length) {\n\t\t\t\t\ttmp.children_d = tmp.children_d.concat(e.children_d);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete d.data;\n\t\t\tdelete d.children;\n\t\t\tm[tmp.id].original = d;\n\t\t\tif(tmp.state.selected) {\n\t\t\t\tthis._data.core.selected.push(tmp.id);\n\t\t\t}\n\t\t\treturn tmp.id;\n\t\t},\n\t\t/**\n\t\t * parses a node from a JSON object and appends it to the in memory tree model. Used internally.\n\t\t * @private\n\t\t * @name _parse_model_from_json(d [, p, ps])\n\t\t * @param {Object} d the JSON object to parse\n\t\t * @param {String} p the parent ID\n\t\t * @param {Array} ps list of all parents\n\t\t * @return {String} the ID of the object added to the model\n\t\t */\n\t\t_parse_model_from_json : function (d, p, ps) {\n\t\t\tif(!ps) { ps = []; }\n\t\t\telse { ps = ps.concat(); }\n\t\t\tif(p) { ps.unshift(p); }\n\t\t\tvar tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp;\n\t\t\tdo {\n\t\t\t\ttid = 'j' + this._id + '_' + (++this._cnt);\n\t\t\t} while(m[tid]);\n\n\t\t\ttmp = {\n\t\t\t\tid\t\t\t: false,\n\t\t\t\ttext\t\t: typeof d === 'string' ? d : '',\n\t\t\t\ticon\t\t: typeof d === 'object' && d.icon !== undefined ? d.icon : true,\n\t\t\t\tparent\t\t: p,\n\t\t\t\tparents\t\t: ps,\n\t\t\t\tchildren\t: [],\n\t\t\t\tchildren_d\t: [],\n\t\t\t\tdata\t\t: null,\n\t\t\t\tstate\t\t: { },\n\t\t\t\tli_attr\t\t: { id : false },\n\t\t\t\ta_attr\t\t: { href : '#' },\n\t\t\t\toriginal\t: false\n\t\t\t};\n\t\t\tfor(i in df) {\n\t\t\t\tif(df.hasOwnProperty(i)) {\n\t\t\t\t\ttmp.state[i] = df[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && d.id) { tmp.id = d.id.toString(); }\n\t\t\tif(d && d.text) { tmp.text = d.text; }\n\t\t\tif(d && d.data && d.data.jstree && d.data.jstree.icon) {\n\t\t\t\ttmp.icon = d.data.jstree.icon;\n\t\t\t}\n\t\t\tif(tmp.icon === undefined || tmp.icon === null || tmp.icon === \"\") {\n\t\t\t\ttmp.icon = true;\n\t\t\t}\n\t\t\tif(d && d.data) {\n\t\t\t\ttmp.data = d.data;\n\t\t\t\tif(d.data.jstree) {\n\t\t\t\t\tfor(i in d.data.jstree) {\n\t\t\t\t\t\tif(d.data.jstree.hasOwnProperty(i)) {\n\t\t\t\t\t\t\ttmp.state[i] = d.data.jstree[i];\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\tif(d && typeof d.state === 'object') {\n\t\t\t\tfor (i in d.state) {\n\t\t\t\t\tif(d.state.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.state[i] = d.state[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && typeof d.li_attr === 'object') {\n\t\t\t\tfor (i in d.li_attr) {\n\t\t\t\t\tif(d.li_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.li_attr[i] = d.li_attr[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(tmp.li_attr.id && !tmp.id) {\n\t\t\t\ttmp.id = tmp.li_attr.id.toString();\n\t\t\t}\n\t\t\tif(!tmp.id) {\n\t\t\t\ttmp.id = tid;\n\t\t\t}\n\t\t\tif(!tmp.li_attr.id) {\n\t\t\t\ttmp.li_attr.id = tmp.id;\n\t\t\t}\n\t\t\tif(d && typeof d.a_attr === 'object') {\n\t\t\t\tfor (i in d.a_attr) {\n\t\t\t\t\tif(d.a_attr.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.a_attr[i] = d.a_attr[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(d && d.children && d.children.length) {\n\t\t\t\tfor(i = 0, j = d.children.length; i < j; i++) {\n\t\t\t\t\tc = this._parse_model_from_json(d.children[i], tmp.id, ps);\n\t\t\t\t\te = m[c];\n\t\t\t\t\ttmp.children.push(c);\n\t\t\t\t\tif(e.children_d.length) {\n\t\t\t\t\t\ttmp.children_d = tmp.children_d.concat(e.children_d);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttmp.children_d = tmp.children.concat(tmp.children_d);\n\t\t\t}\n\t\t\tif(d && d.children && d.children === true) {\n\t\t\t\ttmp.state.loaded = false;\n\t\t\t\ttmp.children = [];\n\t\t\t\ttmp.children_d = [];\n\t\t\t}\n\t\t\tdelete d.data;\n\t\t\tdelete d.children;\n\t\t\ttmp.original = d;\n\t\t\tm[tmp.id] = tmp;\n\t\t\tif(tmp.state.selected) {\n\t\t\t\tthis._data.core.selected.push(tmp.id);\n\t\t\t}\n\t\t\treturn tmp.id;\n\t\t},\n\t\t/**\n\t\t * redraws all nodes that need to be redrawn. Used internally.\n\t\t * @private\n\t\t * @name _redraw()\n\t\t * @trigger redraw.jstree\n\t\t */\n\t\t_redraw : function () {\n\t\t\tvar nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]),\n\t\t\t\tf = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused;\n\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\ttmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw);\n\t\t\t\tif(tmp && this._model.force_full_redraw) {\n\t\t\t\t\tf.appendChild(tmp);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(this._model.force_full_redraw) {\n\t\t\t\tf.className = this.get_container_ul()[0].className;\n\t\t\t\tf.setAttribute('role','presentation');\n\t\t\t\tthis.element.empty().append(f);\n\t\t\t\t//this.get_container_ul()[0].appendChild(f);\n\t\t\t}\n\t\t\tif(fe !== null && this.settings.core.restore_focus) {\n\t\t\t\ttmp = this.get_node(fe, true);\n\t\t\t\tif(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) {\n\t\t\t\t\ttmp.children('.jstree-anchor').trigger('focus');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis._data.core.focused = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._model.force_full_redraw = false;\n\t\t\tthis._model.changed = [];\n\t\t\t/**\n\t\t\t * triggered after nodes are redrawn\n\t\t\t * @event\n\t\t\t * @name redraw.jstree\n\t\t\t * @param {array} nodes the redrawn nodes\n\t\t\t */\n\t\t\tthis.trigger('redraw', { \"nodes\" : nodes });\n\t\t},\n\t\t/**\n\t\t * redraws all nodes that need to be redrawn or optionally - the whole tree\n\t\t * @name redraw([full])\n\t\t * @param {Boolean} full if set to `true` all nodes are redrawn.\n\t\t */\n\t\tredraw : function (full) {\n\t\t\tif(full) {\n\t\t\t\tthis._model.force_full_redraw = true;\n\t\t\t}\n\t\t\t//if(this._model.redraw_timeout) {\n\t\t\t//\tclearTimeout(this._model.redraw_timeout);\n\t\t\t//}\n\t\t\t//this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0);\n\t\t\tthis._redraw();\n\t\t},\n\t\t/**\n\t\t * redraws a single node's children. Used internally.\n\t\t * @private\n\t\t * @name draw_children(node)\n\t\t * @param {mixed} node the node whose children will be redrawn\n\t\t */\n\t\tdraw_children : function (node) {\n\t\t\tvar obj = this.get_node(node),\n\t\t\t\ti = false,\n\t\t\t\tj = false,\n\t\t\t\tk = false,\n\t\t\t\td = document;\n\t\t\tif(!obj) { return false; }\n\t\t\tif(obj.id === $.jstree.root) { return this.redraw(true); }\n\t\t\tnode = this.get_node(node, true);\n\t\t\tif(!node || !node.length) { return false; } // TODO: quick toggle\n\n\t\t\tnode.children('.jstree-children').remove();\n\t\t\tnode = node[0];\n\t\t\tif(obj.children.length && obj.state.loaded) {\n\t\t\t\tk = d.createElement('UL');\n\t\t\t\tk.setAttribute('role', 'group');\n\t\t\t\tk.className = 'jstree-children';\n\t\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\t\tk.appendChild(this.redraw_node(obj.children[i], true, true));\n\t\t\t\t}\n\t\t\t\tnode.appendChild(k);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * redraws a single node. Used internally.\n\t\t * @private\n\t\t * @name redraw_node(node, deep, is_callback, force_render)\n\t\t * @param {mixed} node the node to redraw\n\t\t * @param {Boolean} deep should child nodes be redrawn too\n\t\t * @param {Boolean} is_callback is this a recursion call\n\t\t * @param {Boolean} force_render should children of closed parents be drawn anyway\n\t\t */\n\t\tredraw_node : function (node, deep, is_callback, force_render) {\n\t\t\tvar obj = this.get_node(node),\n\t\t\t\tpar = false,\n\t\t\t\tind = false,\n\t\t\t\told = false,\n\t\t\t\ti = false,\n\t\t\t\tj = false,\n\t\t\t\tk = false,\n\t\t\t\tc = '',\n\t\t\t\td = document,\n\t\t\t\tm = this._model.data,\n\t\t\t\tf = false,\n\t\t\t\ts = false,\n\t\t\t\ttmp = null,\n\t\t\t\tt = 0,\n\t\t\t\tl = 0,\n\t\t\t\thas_children = false,\n\t\t\t\tlast_sibling = false;\n\t\t\tif(!obj) { return false; }\n\t\t\tif(obj.id === $.jstree.root) { return this.redraw(true); }\n\t\t\tdeep = deep || obj.children.length === 0;\n\t\t\tnode = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + (\"0123456789\".indexOf(obj.id[0]) !== -1 ? '\\\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\\\$&') : obj.id.replace($.jstree.idregex,'\\\\$&')) ); //, this.element);\n\t\t\tif(!node) {\n\t\t\t\tdeep = true;\n\t\t\t\t//node = d.createElement('LI');\n\t\t\t\tif(!is_callback) {\n\t\t\t\t\tpar = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\\\$&'), this.element)[0] : null;\n\t\t\t\t\tif(par !== null && (!par || !m[obj.parent].state.opened)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnode = $(node);\n\t\t\t\tif(!is_callback) {\n\t\t\t\t\tpar = node.parent().parent()[0];\n\t\t\t\t\tif(par === this.element[0]) {\n\t\t\t\t\t\tpar = null;\n\t\t\t\t\t}\n\t\t\t\t\tind = node.index();\n\t\t\t\t}\n\t\t\t\t// m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage\n\t\t\t\tif(!deep && obj.children.length && !node.children('.jstree-children').length) {\n\t\t\t\t\tdeep = true;\n\t\t\t\t}\n\t\t\t\tif(!deep) {\n\t\t\t\t\told = node.children('.jstree-children')[0];\n\t\t\t\t}\n\t\t\t\tf = node.children('.jstree-anchor')[0] === document.activeElement;\n\t\t\t\tnode.remove();\n\t\t\t\t//node = d.createElement('LI');\n\t\t\t\t//node = node[0];\n\t\t\t}\n\t\t\tnode = this._data.core.node.cloneNode(true);\n\t\t\t// node is DOM, deep is boolean\n\n\t\t\tc = 'jstree-node ';\n\t\t\tfor(i in obj.li_attr) {\n\t\t\t\tif(obj.li_attr.hasOwnProperty(i)) {\n\t\t\t\t\tif(i === 'id') { continue; }\n\t\t\t\t\tif(i !== 'class') {\n\t\t\t\t\t\tnode.setAttribute(i, obj.li_attr[i]);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tc += obj.li_attr[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!obj.a_attr.id) {\n\t\t\t\tobj.a_attr.id = obj.id + '_anchor';\n\t\t\t}\n\t\t\tnode.childNodes[1].setAttribute('aria-selected', !!obj.state.selected);\n\t\t\tnode.childNodes[1].setAttribute('aria-level', obj.parents.length);\n\t\t\tif(this.settings.core.compute_elements_positions) {\n\t\t\t\tnode.childNodes[1].setAttribute('aria-setsize', m[obj.parent].children.length);\n\t\t\t\tnode.childNodes[1].setAttribute('aria-posinset', m[obj.parent].children.indexOf(obj.id) + 1);\n\t\t\t}\n\t\t\tif(obj.state.disabled) {\n\t\t\t\tnode.childNodes[1].setAttribute('aria-disabled', true);\n\t\t\t}\n\n\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\tif(!m[obj.children[i]].state.hidden) {\n\t\t\t\t\thas_children = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(obj.parent !== null && m[obj.parent] && !obj.state.hidden) {\n\t\t\t\ti = $.inArray(obj.id, m[obj.parent].children);\n\t\t\t\tlast_sibling = obj.id;\n\t\t\t\tif(i !== -1) {\n\t\t\t\t\ti++;\n\t\t\t\t\tfor(j = m[obj.parent].children.length; i < j; i++) {\n\t\t\t\t\t\tif(!m[m[obj.parent].children[i]].state.hidden) {\n\t\t\t\t\t\t\tlast_sibling = m[obj.parent].children[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(last_sibling !== obj.id) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(obj.state.hidden) {\n\t\t\t\tc += ' jstree-hidden';\n\t\t\t}\n\t\t\tif (obj.state.loading) {\n\t\t\t\tc += ' jstree-loading';\n\t\t\t}\n\t\t\tif(obj.state.loaded && !has_children) {\n\t\t\t\tc += ' jstree-leaf';\n\t\t\t}\n\t\t\telse {\n\t\t\t\tc += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed';\n\t\t\t\tnode.childNodes[1].setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) );\n\t\t\t}\n\t\t\tif(last_sibling === obj.id) {\n\t\t\t\tc += ' jstree-last';\n\t\t\t}\n\t\t\tnode.id = obj.id;\n\t\t\tnode.className = c;\n\t\t\tc = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : '');\n\t\t\tfor(j in obj.a_attr) {\n\t\t\t\tif(obj.a_attr.hasOwnProperty(j)) {\n\t\t\t\t\tif(j === 'href' && obj.a_attr[j] === '#') { continue; }\n\t\t\t\t\tif(j !== 'class') {\n\t\t\t\t\t\tnode.childNodes[1].setAttribute(j, obj.a_attr[j]);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tc += ' ' + obj.a_attr[j];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(c.length) {\n\t\t\t\tnode.childNodes[1].className = 'jstree-anchor ' + c;\n\t\t\t}\n\t\t\tif((obj.icon && obj.icon !== true) || obj.icon === false) {\n\t\t\t\tif(obj.icon === false) {\n\t\t\t\t\tnode.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden';\n\t\t\t\t}\n\t\t\t\telse if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) {\n\t\t\t\t\tnode.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom';\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnode.childNodes[1].childNodes[0].style.backgroundImage = 'url(\"'+obj.icon+'\")';\n\t\t\t\t\tnode.childNodes[1].childNodes[0].style.backgroundPosition = 'center center';\n\t\t\t\t\tnode.childNodes[1].childNodes[0].style.backgroundSize = 'auto';\n\t\t\t\t\tnode.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(this.settings.core.force_text) {\n\t\t\t\tnode.childNodes[1].appendChild(d.createTextNode(obj.text));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnode.childNodes[1].innerHTML += obj.text;\n\t\t\t}\n\n\n\t\t\tif(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) {\n\t\t\t\tk = d.createElement('UL');\n\t\t\t\tk.setAttribute('role', 'group');\n\t\t\t\tk.className = 'jstree-children';\n\t\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\t\tk.appendChild(this.redraw_node(obj.children[i], deep, true));\n\t\t\t\t}\n\t\t\t\tnode.appendChild(k);\n\t\t\t}\n\t\t\tif(old) {\n\t\t\t\tnode.appendChild(old);\n\t\t\t}\n\t\t\tif(!is_callback) {\n\t\t\t\t// append back using par / ind\n\t\t\t\tif(!par) {\n\t\t\t\t\tpar = this.element[0];\n\t\t\t\t}\n\t\t\t\tfor(i = 0, j = par.childNodes.length; i < j; i++) {\n\t\t\t\t\tif(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) {\n\t\t\t\t\t\ttmp = par.childNodes[i];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(!tmp) {\n\t\t\t\t\ttmp = d.createElement('UL');\n\t\t\t\t\ttmp.setAttribute('role', 'group');\n\t\t\t\t\ttmp.className = 'jstree-children';\n\t\t\t\t\tpar.appendChild(tmp);\n\t\t\t\t}\n\t\t\t\tpar = tmp;\n\n\t\t\t\tif(ind < par.childNodes.length) {\n\t\t\t\t\tpar.insertBefore(node, par.childNodes[ind]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpar.appendChild(node);\n\t\t\t\t}\n\t\t\t\tif(f) {\n\t\t\t\t\tt = this.element[0].scrollTop;\n\t\t\t\t\tl = this.element[0].scrollLeft;\n\t\t\t\t\tnode.childNodes[1].focus();\n\t\t\t\t\tthis.element[0].scrollTop = t;\n\t\t\t\t\tthis.element[0].scrollLeft = l;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(obj.state.opened && !obj.state.loaded) {\n\t\t\t\tobj.state.opened = false;\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\tthis.open_node(obj.id, false, 0);\n\t\t\t\t}.bind(this), 0);\n\t\t\t}\n\t\t\treturn node;\n\t\t},\n\t\t/**\n\t\t * opens a node, revealing its children. If the node is not loaded it will be loaded and opened once ready.\n\t\t * @name open_node(obj [, callback, animation])\n\t\t * @param {mixed} obj the node to open\n\t\t * @param {Function} callback a function to execute once the node is opened\n\t\t * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation.\n\t\t * @trigger open_node.jstree, after_open.jstree, before_open.jstree\n\t\t */\n\t\topen_node : function (obj, callback, animation) {\n\t\t\tvar t1, t2, d, t;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.open_node(obj[t1], callback, animation);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tanimation = animation === undefined ? this.settings.core.animation : animation;\n\t\t\tif(!this.is_closed(obj)) {\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback.call(this, obj, false);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(!this.is_loaded(obj)) {\n\t\t\t\tif(this.is_loading(obj)) {\n\t\t\t\t\treturn setTimeout(function () {\n\t\t\t\t\t\tthis.open_node(obj, callback, animation);\n\t\t\t\t\t}.bind(this), 500);\n\t\t\t\t}\n\t\t\t\tthis.load_node(obj, function (o, ok) {\n\t\t\t\t\treturn ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\td = this.get_node(obj, true);\n\t\t\t\tt = this;\n\t\t\t\tif(d.length) {\n\t\t\t\t\tif(animation && d.children(\".jstree-children\").length) {\n\t\t\t\t\t\td.children(\".jstree-children\").stop(true, true);\n\t\t\t\t\t}\n\t\t\t\t\tif(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) {\n\t\t\t\t\t\tthis.draw_children(obj);\n\t\t\t\t\t\t//d = this.get_node(obj, true);\n\t\t\t\t\t}\n\t\t\t\t\tif(!animation) {\n\t\t\t\t\t\tthis.trigger('before_open', { \"node\" : obj });\n\t\t\t\t\t\td[0].className = d[0].className.replace('jstree-closed', 'jstree-open');\n\t\t\t\t\t\td[0].childNodes[1].setAttribute(\"aria-expanded\", true);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.trigger('before_open', { \"node\" : obj });\n\t\t\t\t\t\td\n\t\t\t\t\t\t\t.children(\".jstree-children\").css(\"display\",\"none\").end()\n\t\t\t\t\t\t\t.removeClass(\"jstree-closed\").addClass(\"jstree-open\")\n\t\t\t\t\t\t\t\t.children('.jstree-anchor').attr(\"aria-expanded\", true).end()\n\t\t\t\t\t\t\t.children(\".jstree-children\").stop(true, true)\n\t\t\t\t\t\t\t\t.slideDown(animation, function () {\n\t\t\t\t\t\t\t\t\tthis.style.display = \"\";\n\t\t\t\t\t\t\t\t\tif (t.element) {\n\t\t\t\t\t\t\t\t\t\tt.trigger(\"after_open\", { \"node\" : obj });\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tobj.state.opened = true;\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback.call(this, obj, true);\n\t\t\t\t}\n\t\t\t\tif(!d.length) {\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet)\n\t\t\t\t\t * @event\n\t\t\t\t\t * @name before_open.jstree\n\t\t\t\t\t * @param {Object} node the opened node\n\t\t\t\t\t */\n\t\t\t\t\tthis.trigger('before_open', { \"node\" : obj });\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when a node is opened (if there is an animation it will not be completed yet)\n\t\t\t\t * @event\n\t\t\t\t * @name open_node.jstree\n\t\t\t\t * @param {Object} node the opened node\n\t\t\t\t */\n\t\t\t\tthis.trigger('open_node', { \"node\" : obj });\n\t\t\t\tif(!animation || !d.length) {\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered when a node is opened and the animation is complete\n\t\t\t\t\t * @event\n\t\t\t\t\t * @name after_open.jstree\n\t\t\t\t\t * @param {Object} node the opened node\n\t\t\t\t\t */\n\t\t\t\t\tthis.trigger(\"after_open\", { \"node\" : obj });\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * opens every parent of a node (node should be loaded)\n\t\t * @name _open_to(obj)\n\t\t * @param {mixed} obj the node to reveal\n\t\t * @private\n\t\t */\n\t\t_open_to : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar i, j, p = obj.parents;\n\t\t\tfor(i = 0, j = p.length; i < j; i+=1) {\n\t\t\t\tif(i !== $.jstree.root) {\n\t\t\t\t\tthis.open_node(p[i], false, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $('#' + obj.id.replace($.jstree.idregex,'\\\\$&'), this.element);\n\t\t},\n\t\t/**\n\t\t * closes a node, hiding its children\n\t\t * @name close_node(obj [, animation])\n\t\t * @param {mixed} obj the node to close\n\t\t * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation.\n\t\t * @trigger close_node.jstree, after_close.jstree\n\t\t */\n\t\tclose_node : function (obj, animation) {\n\t\t\tvar t1, t2, t, d;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.close_node(obj[t1], animation);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(this.is_closed(obj)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tanimation = animation === undefined ? this.settings.core.animation : animation;\n\t\t\tt = this;\n\t\t\td = this.get_node(obj, true);\n\n\t\t\tobj.state.opened = false;\n\t\t\t/**\n\t\t\t * triggered when a node is closed (if there is an animation it will not be complete yet)\n\t\t\t * @event\n\t\t\t * @name close_node.jstree\n\t\t\t * @param {Object} node the closed node\n\t\t\t */\n\t\t\tthis.trigger('close_node',{ \"node\" : obj });\n\t\t\tif(!d.length) {\n\t\t\t\t/**\n\t\t\t\t * triggered when a node is closed and the animation is complete\n\t\t\t\t * @event\n\t\t\t\t * @name after_close.jstree\n\t\t\t\t * @param {Object} node the closed node\n\t\t\t\t */\n\t\t\t\tthis.trigger(\"after_close\", { \"node\" : obj });\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(!animation) {\n\t\t\t\t\td[0].className = d[0].className.replace('jstree-open', 'jstree-closed');\n\t\t\t\t\td.children('.jstree-anchor').attr(\"aria-expanded\", false);\n\t\t\t\t\td.children('.jstree-children').remove();\n\t\t\t\t\tthis.trigger(\"after_close\", { \"node\" : obj });\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\td\n\t\t\t\t\t\t.children(\".jstree-children\").attr(\"style\",\"display:block !important\").end()\n\t\t\t\t\t\t.removeClass(\"jstree-open\").addClass(\"jstree-closed\")\n\t\t\t\t\t\t\t.children('.jstree-anchor').attr(\"aria-expanded\", false).end()\n\t\t\t\t\t\t.children(\".jstree-children\").stop(true, true).slideUp(animation, function () {\n\t\t\t\t\t\t\tthis.style.display = \"\";\n\t\t\t\t\t\t\td.children('.jstree-children').remove();\n\t\t\t\t\t\t\tif (t.element) {\n\t\t\t\t\t\t\t\tt.trigger(\"after_close\", { \"node\" : obj });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * toggles a node - closing it if it is open, opening it if it is closed\n\t\t * @name toggle_node(obj)\n\t\t * @param {mixed} obj the node to toggle\n\t\t */\n\t\ttoggle_node : function (obj) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.toggle_node(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(this.is_closed(obj)) {\n\t\t\t\treturn this.open_node(obj);\n\t\t\t}\n\t\t\tif(this.is_open(obj)) {\n\t\t\t\treturn this.close_node(obj);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * opens all nodes within a node (or the tree), revealing their children. If the node is not loaded it will be loaded and opened once ready.\n\t\t * @name open_all([obj, animation, original_obj])\n\t\t * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree\n\t\t * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation\n\t\t * @param {jQuery} reference to the node that started the process (internal use)\n\t\t * @trigger open_all.jstree\n\t\t */\n\t\topen_all : function (obj, animation, original_obj) {\n\t\t\tif(!obj) { obj = $.jstree.root; }\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) { return false; }\n\t\t\tvar dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;\n\t\t\tif(!dom.length) {\n\t\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\t\tif(this.is_closed(this._model.data[obj.children_d[i]])) {\n\t\t\t\t\t\tthis._model.data[obj.children_d[i]].state.opened = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this.trigger('open_all', { \"node\" : obj });\n\t\t\t}\n\t\t\toriginal_obj = original_obj || dom;\n\t\t\t_this = this;\n\t\t\tdom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed');\n\t\t\tdom.each(function () {\n\t\t\t\t_this.open_node(\n\t\t\t\t\tthis,\n\t\t\t\t\tfunction(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } },\n\t\t\t\t\tanimation || 0\n\t\t\t\t);\n\t\t\t});\n\t\t\tif(original_obj.find('.jstree-closed').length === 0) {\n\t\t\t\t/**\n\t\t\t\t * triggered when an `open_all` call completes\n\t\t\t\t * @event\n\t\t\t\t * @name open_all.jstree\n\t\t\t\t * @param {Object} node the opened node\n\t\t\t\t */\n\t\t\t\tthis.trigger('open_all', { \"node\" : this.get_node(original_obj) });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * closes all nodes within a node (or the tree), revealing their children\n\t\t * @name close_all([obj, animation])\n\t\t * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree\n\t\t * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation\n\t\t * @trigger close_all.jstree\n\t\t */\n\t\tclose_all : function (obj, animation) {\n\t\t\tif(!obj) { obj = $.jstree.root; }\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) { return false; }\n\t\t\tvar dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true),\n\t\t\t\t_this = this, i, j;\n\t\t\tif(dom.length) {\n\t\t\t\tdom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open');\n\t\t\t\t$(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); });\n\t\t\t}\n\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\tthis._model.data[obj.children_d[i]].state.opened = false;\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when an `close_all` call completes\n\t\t\t * @event\n\t\t\t * @name close_all.jstree\n\t\t\t * @param {Object} node the closed node\n\t\t\t */\n\t\t\tthis.trigger('close_all', { \"node\" : obj });\n\t\t},\n\t\t/**\n\t\t * checks if a node is disabled (not selectable)\n\t\t * @name is_disabled(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_disabled : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj && obj.state && obj.state.disabled;\n\t\t},\n\t\t/**\n\t\t * enables a node - so that it can be selected\n\t\t * @name enable_node(obj)\n\t\t * @param {mixed} obj the node to enable\n\t\t * @trigger enable_node.jstree\n\t\t */\n\t\tenable_node : function (obj) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.enable_node(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj.state.disabled = false;\n\t\t\tthis.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false);\n\t\t\t/**\n\t\t\t * triggered when an node is enabled\n\t\t\t * @event\n\t\t\t * @name enable_node.jstree\n\t\t\t * @param {Object} node the enabled node\n\t\t\t */\n\t\t\tthis.trigger('enable_node', { 'node' : obj });\n\t\t},\n\t\t/**\n\t\t * disables a node - so that it can not be selected\n\t\t * @name disable_node(obj)\n\t\t * @param {mixed} obj the node to disable\n\t\t * @trigger disable_node.jstree\n\t\t */\n\t\tdisable_node : function (obj) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.disable_node(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj.state.disabled = true;\n\t\t\tthis.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true);\n\t\t\t/**\n\t\t\t * triggered when an node is disabled\n\t\t\t * @event\n\t\t\t * @name disable_node.jstree\n\t\t\t * @param {Object} node the disabled node\n\t\t\t */\n\t\t\tthis.trigger('disable_node', { 'node' : obj });\n\t\t},\n\t\t/**\n\t\t * determines if a node is hidden\n\t\t * @name is_hidden(obj)\n\t\t * @param {mixed} obj the node\n\t\t */\n\t\tis_hidden : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn obj.state.hidden === true;\n\t\t},\n\t\t/**\n\t\t * hides a node - it is still in the structure but will not be visible\n\t\t * @name hide_node(obj)\n\t\t * @param {mixed} obj the node to hide\n\t\t * @param {Boolean} skip_redraw internal parameter controlling if redraw is called\n\t\t * @trigger hide_node.jstree\n\t\t */\n\t\thide_node : function (obj, skip_redraw) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.hide_node(obj[t1], true);\n\t\t\t\t}\n\t\t\t\tif (!skip_redraw) {\n\t\t\t\t\tthis.redraw();\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(!obj.state.hidden) {\n\t\t\t\tobj.state.hidden = true;\n\t\t\t\tthis._node_changed(obj.parent);\n\t\t\t\tif(!skip_redraw) {\n\t\t\t\t\tthis.redraw();\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is hidden\n\t\t\t\t * @event\n\t\t\t\t * @name hide_node.jstree\n\t\t\t\t * @param {Object} node the hidden node\n\t\t\t\t */\n\t\t\t\tthis.trigger('hide_node', { 'node' : obj });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * shows a node\n\t\t * @name show_node(obj)\n\t\t * @param {mixed} obj the node to show\n\t\t * @param {Boolean} skip_redraw internal parameter controlling if redraw is called\n\t\t * @trigger show_node.jstree\n\t\t */\n\t\tshow_node : function (obj, skip_redraw) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.show_node(obj[t1], true);\n\t\t\t\t}\n\t\t\t\tif (!skip_redraw) {\n\t\t\t\t\tthis.redraw();\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(obj.state.hidden) {\n\t\t\t\tobj.state.hidden = false;\n\t\t\t\tthis._node_changed(obj.parent);\n\t\t\t\tif(!skip_redraw) {\n\t\t\t\t\tthis.redraw();\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is shown\n\t\t\t\t * @event\n\t\t\t\t * @name show_node.jstree\n\t\t\t\t * @param {Object} node the shown node\n\t\t\t\t */\n\t\t\t\tthis.trigger('show_node', { 'node' : obj });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * hides all nodes\n\t\t * @name hide_all()\n\t\t * @trigger hide_all.jstree\n\t\t */\n\t\thide_all : function (skip_redraw) {\n\t\t\tvar i, m = this._model.data, ids = [];\n\t\t\tfor(i in m) {\n\t\t\t\tif(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) {\n\t\t\t\t\tm[i].state.hidden = true;\n\t\t\t\t\tids.push(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._model.force_full_redraw = true;\n\t\t\tif(!skip_redraw) {\n\t\t\t\tthis.redraw();\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when all nodes are hidden\n\t\t\t * @event\n\t\t\t * @name hide_all.jstree\n\t\t\t * @param {Array} nodes the IDs of all hidden nodes\n\t\t\t */\n\t\t\tthis.trigger('hide_all', { 'nodes' : ids });\n\t\t\treturn ids;\n\t\t},\n\t\t/**\n\t\t * shows all nodes\n\t\t * @name show_all()\n\t\t * @trigger show_all.jstree\n\t\t */\n\t\tshow_all : function (skip_redraw) {\n\t\t\tvar i, m = this._model.data, ids = [];\n\t\t\tfor(i in m) {\n\t\t\t\tif(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) {\n\t\t\t\t\tm[i].state.hidden = false;\n\t\t\t\t\tids.push(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._model.force_full_redraw = true;\n\t\t\tif(!skip_redraw) {\n\t\t\t\tthis.redraw();\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when all nodes are shown\n\t\t\t * @event\n\t\t\t * @name show_all.jstree\n\t\t\t * @param {Array} nodes the IDs of all shown nodes\n\t\t\t */\n\t\t\tthis.trigger('show_all', { 'nodes' : ids });\n\t\t\treturn ids;\n\t\t},\n\t\t/**\n\t\t * called when a node is selected by the user. Used internally.\n\t\t * @private\n\t\t * @name activate_node(obj, e)\n\t\t * @param {mixed} obj the node\n\t\t * @param {Object} e the related event\n\t\t * @trigger activate_node.jstree, changed.jstree\n\t\t */\n\t\tactivate_node : function (obj, e) {\n\t\t\tif(this.is_disabled(obj)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(!e || typeof e !== 'object') {\n\t\t\t\te = {};\n\t\t\t}\n\n\t\t\t// ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node\n\t\t\tthis._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null;\n\t\t\tif(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; }\n\t\t\tif(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); }\n\n\t\t\tif(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) {\n\t\t\t\tif(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) {\n\t\t\t\t\tthis.deselect_node(obj, false, e);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (!this.is_selected(obj) || this._data.core.selected.length !== 1) {\n\t\t\t\t\t\tthis.deselect_all(true);\n\t\t\t\t\t\tthis.select_node(obj, false, false, e);\n\t\t\t\t\t}\n\t\t\t\t\tthis._data.core.last_clicked = this.get_node(obj);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(e.shiftKey) {\n\t\t\t\t\tvar o = this.get_node(obj).id,\n\t\t\t\t\t\tl = this._data.core.last_clicked.id,\n\t\t\t\t\t\tp = this.get_node(this._data.core.last_clicked.parent).children,\n\t\t\t\t\t\tc = false,\n\t\t\t\t\t\ti, j;\n\t\t\t\t\tfor(i = 0, j = p.length; i < j; i += 1) {\n\t\t\t\t\t\t// separate IFs work whem o and l are the same\n\t\t\t\t\t\tif(p[i] === o) {\n\t\t\t\t\t\t\tc = !c;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p[i] === l) {\n\t\t\t\t\t\t\tc = !c;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) {\n\t\t\t\t\t\t\tif (!this.is_hidden(p[i])) {\n\t\t\t\t\t\t\t\tthis.select_node(p[i], true, false, e);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tif (!e.ctrlKey) {\n\t\t\t\t\t\t\t\tthis.deselect_node(p[i], true, e);\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\tthis.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e });\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif(!this.is_selected(obj)) {\n\t\t\t\t\t\tif (e.ctrlKey) {\n\t\t\t\t\t\t\tthis._data.core.last_clicked = this.get_node(obj);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.select_node(obj, false, false, e);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.deselect_node(obj, false, e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when an node is clicked or intercated with by the user\n\t\t\t * @event\n\t\t\t * @name activate_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object)\n\t\t\t */\n\t\t\tthis.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e });\n\t\t},\n\t\t/**\n\t\t * applies the hover state on a node, called when a node is hovered by the user. Used internally.\n\t\t * @private\n\t\t * @name hover_node(obj)\n\t\t * @param {mixed} obj\n\t\t * @trigger hover_node.jstree\n\t\t */\n\t\thover_node : function (obj) {\n\t\t\tobj = this.get_node(obj, true);\n\t\t\tif(!obj || !obj.length || obj.children('.jstree-hovered').length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar o = this.element.find('.jstree-hovered'), t = this.element;\n\t\t\tif(o && o.length) { this.dehover_node(o); }\n\n\t\t\tobj.children('.jstree-anchor').addClass('jstree-hovered');\n\t\t\t/**\n\t\t\t * triggered when an node is hovered\n\t\t\t * @event\n\t\t\t * @name hover_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t */\n\t\t\tthis.trigger('hover_node', { 'node' : this.get_node(obj) });\n\t\t\tsetTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0);\n\t\t},\n\t\t/**\n\t\t * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally.\n\t\t * @private\n\t\t * @name dehover_node(obj)\n\t\t * @param {mixed} obj\n\t\t * @trigger dehover_node.jstree\n\t\t */\n\t\tdehover_node : function (obj) {\n\t\t\tobj = this.get_node(obj, true);\n\t\t\tif(!obj || !obj.length || !obj.children('.jstree-hovered').length) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj.children('.jstree-anchor').removeClass('jstree-hovered');\n\t\t\t/**\n\t\t\t * triggered when an node is no longer hovered\n\t\t\t * @event\n\t\t\t * @name dehover_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t */\n\t\t\tthis.trigger('dehover_node', { 'node' : this.get_node(obj) });\n\t\t},\n\t\t/**\n\t\t * select a node\n\t\t * @name select_node(obj [, supress_event, prevent_open])\n\t\t * @param {mixed} obj an array can be used to select multiple nodes\n\t\t * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered\n\t\t * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened\n\t\t * @trigger select_node.jstree, changed.jstree\n\t\t */\n\t\tselect_node : function (obj, supress_event, prevent_open, e) {\n\t\t\tvar dom, t1, t2, th;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.select_node(obj[t1], supress_event, prevent_open, e);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(!obj.state.selected) {\n\t\t\t\tobj.state.selected = true;\n\t\t\t\tthis._data.core.selected.push(obj.id);\n\t\t\t\tif(!prevent_open) {\n\t\t\t\t\tdom = this._open_to(obj);\n\t\t\t\t}\n\t\t\t\tif(dom && dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').addClass('jstree-clicked').attr('aria-selected', true);\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is selected\n\t\t\t\t * @event\n\t\t\t\t * @name select_node.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @param {Array} selected the current selection\n\t\t\t\t * @param {Object} event the event (if any) that triggered this select_node\n\t\t\t\t */\n\t\t\t\tthis.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });\n\t\t\t\tif(!supress_event) {\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered when selection changes\n\t\t\t\t\t * @event\n\t\t\t\t\t * @name changed.jstree\n\t\t\t\t\t * @param {Object} node\n\t\t\t\t\t * @param {Object} action the action that caused the selection to change\n\t\t\t\t\t * @param {Array} selected the current selection\n\t\t\t\t\t * @param {Object} event the event (if any) that triggered this changed event\n\t\t\t\t\t */\n\t\t\t\t\tthis.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * deselect a node\n\t\t * @name deselect_node(obj [, supress_event])\n\t\t * @param {mixed} obj an array can be used to deselect multiple nodes\n\t\t * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered\n\t\t * @trigger deselect_node.jstree, changed.jstree\n\t\t */\n\t\tdeselect_node : function (obj, supress_event, e) {\n\t\t\tvar t1, t2, dom;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.deselect_node(obj[t1], supress_event, e);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(obj.state.selected) {\n\t\t\t\tobj.state.selected = false;\n\t\t\t\tthis._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id);\n\t\t\t\tif(dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').removeClass('jstree-clicked').attr('aria-selected', false);\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is deselected\n\t\t\t\t * @event\n\t\t\t\t * @name deselect_node.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @param {Array} selected the current selection\n\t\t\t\t * @param {Object} event the event (if any) that triggered this deselect_node\n\t\t\t\t */\n\t\t\t\tthis.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });\n\t\t\t\tif(!supress_event) {\n\t\t\t\t\tthis.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * select all nodes in the tree\n\t\t * @name select_all([supress_event])\n\t\t * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered\n\t\t * @trigger select_all.jstree, changed.jstree\n\t\t */\n\t\tselect_all : function (supress_event) {\n\t\t\tvar tmp = this._data.core.selected.concat([]), i, j;\n\t\t\tthis._data.core.selected = this._model.data[$.jstree.root].children_d.concat();\n\t\t\tfor(i = 0, j = this._data.core.selected.length; i < j; i++) {\n\t\t\t\tif(this._model.data[this._data.core.selected[i]]) {\n\t\t\t\t\tthis._model.data[this._data.core.selected[i]].state.selected = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.redraw(true);\n\t\t\t/**\n\t\t\t * triggered when all nodes are selected\n\t\t\t * @event\n\t\t\t * @name select_all.jstree\n\t\t\t * @param {Array} selected the current selection\n\t\t\t */\n\t\t\tthis.trigger('select_all', { 'selected' : this._data.core.selected });\n\t\t\tif(!supress_event) {\n\t\t\t\tthis.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * deselect all selected nodes\n\t\t * @name deselect_all([supress_event])\n\t\t * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered\n\t\t * @trigger deselect_all.jstree, changed.jstree\n\t\t */\n\t\tdeselect_all : function (supress_event) {\n\t\t\tvar tmp = this._data.core.selected.concat([]), i, j;\n\t\t\tfor(i = 0, j = this._data.core.selected.length; i < j; i++) {\n\t\t\t\tif(this._model.data[this._data.core.selected[i]]) {\n\t\t\t\t\tthis._model.data[this._data.core.selected[i]].state.selected = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._data.core.selected = [];\n\t\t\tthis.element.find('.jstree-clicked').removeClass('jstree-clicked').attr('aria-selected', false);\n\t\t\t/**\n\t\t\t * triggered when all nodes are deselected\n\t\t\t * @event\n\t\t\t * @name deselect_all.jstree\n\t\t\t * @param {Object} node the previous selection\n\t\t\t * @param {Array} selected the current selection\n\t\t\t */\n\t\t\tthis.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp });\n\t\t\tif(!supress_event) {\n\t\t\t\tthis.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * checks if a node is selected\n\t\t * @name is_selected(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tis_selected : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn obj.state.selected;\n\t\t},\n\t\t/**\n\t\t * get an array of all selected nodes\n\t\t * @name get_selected([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t */\n\t\tget_selected : function (full) {\n\t\t\treturn full ? $.map(this._data.core.selected, function (i) { return this.get_node(i); }.bind(this)) : this._data.core.selected.slice();\n\t\t},\n\t\t/**\n\t\t * get an array of all top level selected nodes (ignoring children of selected nodes)\n\t\t * @name get_top_selected([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t */\n\t\tget_top_selected : function (full) {\n\t\t\tvar tmp = this.get_selected(true),\n\t\t\t\tobj = {}, i, j, k, l;\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tobj[tmp[i].id] = tmp[i];\n\t\t\t}\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tfor(k = 0, l = tmp[i].children_d.length; k < l; k++) {\n\t\t\t\t\tif(obj[tmp[i].children_d[k]]) {\n\t\t\t\t\t\tdelete obj[tmp[i].children_d[k]];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp = [];\n\t\t\tfor(i in obj) {\n\t\t\t\tif(obj.hasOwnProperty(i)) {\n\t\t\t\t\ttmp.push(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn full ? $.map(tmp, function (i) { return this.get_node(i); }.bind(this)) : tmp;\n\t\t},\n\t\t/**\n\t\t * get an array of all bottom level selected nodes (ignoring selected parents)\n\t\t * @name get_bottom_selected([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t */\n\t\tget_bottom_selected : function (full) {\n\t\t\tvar tmp = this.get_selected(true),\n\t\t\t\tobj = [], i, j;\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tif(!tmp[i].children.length) {\n\t\t\t\t\tobj.push(tmp[i].id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn full ? $.map(obj, function (i) { return this.get_node(i); }.bind(this)) : obj;\n\t\t},\n\t\t/**\n\t\t * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally.\n\t\t * @name get_state()\n\t\t * @private\n\t\t * @return {Object}\n\t\t */\n\t\tget_state : function () {\n\t\t\tvar state\t= {\n\t\t\t\t'core' : {\n\t\t\t\t\t'open' : [],\n\t\t\t\t\t'loaded' : [],\n\t\t\t\t\t'scroll' : {\n\t\t\t\t\t\t'left' : this.element.scrollLeft(),\n\t\t\t\t\t\t'top' : this.element.scrollTop()\n\t\t\t\t\t},\n\t\t\t\t\t/*!\n\t\t\t\t\t'themes' : {\n\t\t\t\t\t\t'name' : this.get_theme(),\n\t\t\t\t\t\t'icons' : this._data.core.themes.icons,\n\t\t\t\t\t\t'dots' : this._data.core.themes.dots\n\t\t\t\t\t},\n\t\t\t\t\t*/\n\t\t\t\t\t'selected' : []\n\t\t\t\t}\n\t\t\t}, i;\n\t\t\tfor(i in this._model.data) {\n\t\t\t\tif(this._model.data.hasOwnProperty(i)) {\n\t\t\t\t\tif(i !== $.jstree.root) {\n\t\t\t\t\t\tif(this._model.data[i].state.loaded && this.settings.core.loaded_state) {\n\t\t\t\t\t\t\tstate.core.loaded.push(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this._model.data[i].state.opened) {\n\t\t\t\t\t\t\tstate.core.open.push(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this._model.data[i].state.selected) {\n\t\t\t\t\t\t\tstate.core.selected.push(i);\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\treturn state;\n\t\t},\n\t\t/**\n\t\t * sets the state of the tree. Used internally.\n\t\t * @name set_state(state [, callback])\n\t\t * @private\n\t\t * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it.\n\t\t * @param {Function} callback an optional function to execute once the state is restored.\n\t\t * @trigger set_state.jstree\n\t\t */\n\t\tset_state : function (state, callback) {\n\t\t\tif(state) {\n\t\t\t\tif(state.core && state.core.selected && state.core.initial_selection === undefined) {\n\t\t\t\t\tstate.core.initial_selection = this._data.core.selected.concat([]).sort().join(',');\n\t\t\t\t}\n\t\t\t\tif(state.core) {\n\t\t\t\t\tvar res, n, t, _this, i;\n\t\t\t\t\tif(state.core.loaded) {\n\t\t\t\t\t\tif(!this.settings.core.loaded_state || !$.vakata.is_array(state.core.loaded) || !state.core.loaded.length) {\n\t\t\t\t\t\t\tdelete state.core.loaded;\n\t\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis._load_nodes(state.core.loaded, function (nodes) {\n\t\t\t\t\t\t\t\tdelete state.core.loaded;\n\t\t\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif(state.core.open) {\n\t\t\t\t\t\tif(!$.vakata.is_array(state.core.open) || !state.core.open.length) {\n\t\t\t\t\t\t\tdelete state.core.open;\n\t\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis._load_nodes(state.core.open, function (nodes) {\n\t\t\t\t\t\t\t\tthis.open_node(nodes, false, 0);\n\t\t\t\t\t\t\t\tdelete state.core.open;\n\t\t\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif(state.core.scroll) {\n\t\t\t\t\t\tif(state.core.scroll && state.core.scroll.left !== undefined) {\n\t\t\t\t\t\t\tthis.element.scrollLeft(state.core.scroll.left);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(state.core.scroll && state.core.scroll.top !== undefined) {\n\t\t\t\t\t\t\tthis.element.scrollTop(state.core.scroll.top);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdelete state.core.scroll;\n\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif(state.core.selected) {\n\t\t\t\t\t\t_this = this;\n\t\t\t\t\t\tif (state.core.initial_selection === undefined ||\n\t\t\t\t\t\t\tstate.core.initial_selection === this._data.core.selected.concat([]).sort().join(',')\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.deselect_all();\n\t\t\t\t\t\t\t$.each(state.core.selected, function (i, v) {\n\t\t\t\t\t\t\t\t_this.select_node(v, false, true);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdelete state.core.initial_selection;\n\t\t\t\t\t\tdelete state.core.selected;\n\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tfor(i in state) {\n\t\t\t\t\t\tif(state.hasOwnProperty(i) && i !== \"core\" && $.inArray(i, this.settings.plugins) === -1) {\n\t\t\t\t\t\t\tdelete state[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif($.isEmptyObject(state.core)) {\n\t\t\t\t\t\tdelete state.core;\n\t\t\t\t\t\tthis.set_state(state, callback);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif($.isEmptyObject(state)) {\n\t\t\t\t\tstate = null;\n\t\t\t\t\tif(callback) { callback.call(this); }\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered when a `set_state` call completes\n\t\t\t\t\t * @event\n\t\t\t\t\t * @name set_state.jstree\n\t\t\t\t\t */\n\t\t\t\t\tthis.trigger('set_state');\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\t/**\n\t\t * refreshes the tree - all nodes are reloaded with calls to `load_node`.\n\t\t * @name refresh()\n\t\t * @param {Boolean} skip_loading an option to skip showing the loading indicator\n\t\t * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state\n\t\t * @trigger refresh.jstree\n\t\t */\n\t\trefresh : function (skip_loading, forget_state) {\n\t\t\tthis._data.core.state = forget_state === true ? {} : this.get_state();\n\t\t\tif(forget_state && $.vakata.is_function(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); }\n\t\t\tthis._cnt = 0;\n\t\t\tthis._model.data = {};\n\t\t\tthis._model.data[$.jstree.root] = {\n\t\t\t\tid : $.jstree.root,\n\t\t\t\tparent : null,\n\t\t\t\tparents : [],\n\t\t\t\tchildren : [],\n\t\t\t\tchildren_d : [],\n\t\t\t\tstate : { loaded : false }\n\t\t\t};\n\t\t\tthis._data.core.selected = [];\n\t\t\tthis._data.core.last_clicked = null;\n\t\t\tthis._data.core.focused = null;\n\n\t\t\tvar c = this.get_container_ul()[0].className;\n\t\t\tif(!skip_loading) {\n\t\t\t\tthis.element.html(\"<\"+\"ul class='\"+c+\"' role='group'><\"+\"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='none' id='j\"+this._id+\"_loading'><\"+\"a class='jstree-anchor' role='treeitem' href='#'>\" + this.get_string(\"Loading ...\") + \"\");\n\t\t\t\tthis.element.attr('aria-activedescendant','j'+this._id+'_loading');\n\t\t\t}\n\t\t\tthis.load_node($.jstree.root, function (o, s) {\n\t\t\t\tif(s) {\n\t\t\t\t\tthis.get_container_ul()[0].className = c;\n\t\t\t\t\tif(this._firstChild(this.get_container_ul()[0])) {\n\t\t\t\t\t\tthis.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);\n\t\t\t\t\t}\n\t\t\t\t\tthis.set_state($.extend(true, {}, this._data.core.state), function () {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * triggered when a `refresh` call completes\n\t\t\t\t\t\t * @event\n\t\t\t\t\t\t * @name refresh.jstree\n\t\t\t\t\t\t */\n\t\t\t\t\t\tthis.trigger('refresh');\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._data.core.state = null;\n\t\t\t});\n\t\t},\n\t\t/**\n\t\t * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`.\n\t\t * @name refresh_node(obj)\n\t\t * @param {mixed} obj the node\n\t\t * @trigger refresh_node.jstree\n\t\t */\n\t\trefresh_node : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\tvar opened = [], to_load = [], s = this._data.core.selected.concat([]);\n\t\t\tto_load.push(obj.id);\n\t\t\tif(obj.state.opened === true) { opened.push(obj.id); }\n\t\t\tthis.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); });\n\t\t\tthis._load_nodes(to_load, function (nodes) {\n\t\t\t\tthis.open_node(opened, false, 0);\n\t\t\t\tthis.select_node(s);\n\t\t\t\t/**\n\t\t\t\t * triggered when a node is refreshed\n\t\t\t\t * @event\n\t\t\t\t * @name refresh_node.jstree\n\t\t\t\t * @param {Object} node - the refreshed node\n\t\t\t\t * @param {Array} nodes - an array of the IDs of the nodes that were reloaded\n\t\t\t\t */\n\t\t\t\tthis.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes });\n\t\t\t}.bind(this), false, true);\n\t\t},\n\t\t/**\n\t\t * set (change) the ID of a node\n\t\t * @name set_id(obj, id)\n\t\t * @param {mixed} obj the node\n\t\t * @param {String} id the new ID\n\t\t * @return {Boolean}\n\t\t * @trigger set_id.jstree\n\t\t */\n\t\tset_id : function (obj, id) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\tvar i, j, m = this._model.data, old = obj.id;\n\t\t\tid = id.toString();\n\t\t\t// update parents (replace current ID with new one in children and children_d)\n\t\t\tm[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id;\n\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\tm[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id;\n\t\t\t}\n\t\t\t// update children (replace current ID with new one in parent and parents)\n\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\tm[obj.children[i]].parent = id;\n\t\t\t}\n\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\tm[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id;\n\t\t\t}\n\t\t\ti = $.inArray(obj.id, this._data.core.selected);\n\t\t\tif(i !== -1) { this._data.core.selected[i] = id; }\n\t\t\t// update model and obj itself (obj.id, this._model.data[KEY])\n\t\t\ti = this.get_node(obj.id, true);\n\t\t\tif(i) {\n\t\t\t\ti.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor');\n\t\t\t\tif(this.element.attr('aria-activedescendant') === obj.id) {\n\t\t\t\t\tthis.element.attr('aria-activedescendant', id);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete m[obj.id];\n\t\t\tobj.id = id;\n\t\t\tobj.li_attr.id = id;\n\t\t\tm[id] = obj;\n\t\t\t/**\n\t\t\t * triggered when a node id value is changed\n\t\t\t * @event\n\t\t\t * @name set_id.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {String} old the old id\n\t\t\t */\n\t\t\tthis.trigger('set_id',{ \"node\" : obj, \"new\" : obj.id, \"old\" : old });\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * get the text value of a node\n\t\t * @name get_text(obj)\n\t\t * @param {mixed} obj the node\n\t\t * @return {String}\n\t\t */\n\t\tget_text : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn (!obj || obj.id === $.jstree.root) ? false : obj.text;\n\t\t},\n\t\t/**\n\t\t * set the text value of a node. Used internally, please use `rename_node(obj, val)`.\n\t\t * @private\n\t\t * @name set_text(obj, val)\n\t\t * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes\n\t\t * @param {String} val the new text value\n\t\t * @return {Boolean}\n\t\t * @trigger set_text.jstree\n\t\t */\n\t\tset_text : function (obj, val) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.set_text(obj[t1], val);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\tobj.text = val;\n\t\t\tif(this.get_node(obj, true).length) {\n\t\t\t\tthis.redraw_node(obj.id);\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when a node text value is changed\n\t\t\t * @event\n\t\t\t * @name set_text.jstree\n\t\t\t * @param {Object} obj\n\t\t\t * @param {String} text the new value\n\t\t\t */\n\t\t\tthis.trigger('set_text',{ \"obj\" : obj, \"text\" : val });\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * gets a JSON representation of a node (or the whole tree)\n\t\t * @name get_json([obj, options])\n\t\t * @param {mixed} obj\n\t\t * @param {Object} options\n\t\t * @param {Boolean} options.no_state do not return state information\n\t\t * @param {Boolean} options.no_id do not return ID\n\t\t * @param {Boolean} options.no_children do not include children\n\t\t * @param {Boolean} options.no_data do not include node data\n\t\t * @param {Boolean} options.no_li_attr do not include LI attributes\n\t\t * @param {Boolean} options.no_a_attr do not include A attributes\n\t\t * @param {Boolean} options.flat return flat JSON instead of nested\n\t\t * @return {Object}\n\t\t */\n\t\tget_json : function (obj, options, flat) {\n\t\t\tobj = this.get_node(obj || $.jstree.root);\n\t\t\tif(!obj) { return false; }\n\t\t\tif(options && options.flat && !flat) { flat = []; }\n\t\t\tvar tmp = {\n\t\t\t\t'id' : obj.id,\n\t\t\t\t'text' : obj.text,\n\t\t\t\t'icon' : this.get_icon(obj),\n\t\t\t\t'li_attr' : $.extend(true, {}, obj.li_attr),\n\t\t\t\t'a_attr' : $.extend(true, {}, obj.a_attr),\n\t\t\t\t'state' : {},\n\t\t\t\t'data' : options && options.no_data ? false : $.extend(true, $.vakata.is_array(obj.data)?[]:{}, obj.data)\n\t\t\t\t//( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ),\n\t\t\t}, i, j;\n\t\t\tif(options && options.flat) {\n\t\t\t\ttmp.parent = obj.parent;\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttmp.children = [];\n\t\t\t}\n\t\t\tif(!options || !options.no_state) {\n\t\t\t\tfor(i in obj.state) {\n\t\t\t\t\tif(obj.state.hasOwnProperty(i)) {\n\t\t\t\t\t\ttmp.state[i] = obj.state[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete tmp.state;\n\t\t\t}\n\t\t\tif(options && options.no_li_attr) {\n\t\t\t\tdelete tmp.li_attr;\n\t\t\t}\n\t\t\tif(options && options.no_a_attr) {\n\t\t\t\tdelete tmp.a_attr;\n\t\t\t}\n\t\t\tif(options && options.no_id) {\n\t\t\t\tdelete tmp.id;\n\t\t\t\tif(tmp.li_attr && tmp.li_attr.id) {\n\t\t\t\t\tdelete tmp.li_attr.id;\n\t\t\t\t}\n\t\t\t\tif(tmp.a_attr && tmp.a_attr.id) {\n\t\t\t\t\tdelete tmp.a_attr.id;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(options && options.flat && obj.id !== $.jstree.root) {\n\t\t\t\tflat.push(tmp);\n\t\t\t}\n\t\t\tif(!options || !options.no_children) {\n\t\t\t\tfor(i = 0, j = obj.children.length; i < j; i++) {\n\t\t\t\t\tif(options && options.flat) {\n\t\t\t\t\t\tthis.get_json(obj.children[i], options, flat);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\ttmp.children.push(this.get_json(obj.children[i], options));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp);\n\t\t},\n\t\t/**\n\t\t * create a new node (do not confuse with load_node)\n\t\t * @name create_node([par, node, pos, callback, is_loaded])\n\t\t * @param {mixed} par the parent node (to create a root node use either \"#\" (string) or `null`)\n\t\t * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name)\n\t\t * @param {mixed} pos the index at which to insert the node, \"first\" and \"last\" are also supported, default is \"last\"\n\t\t * @param {Function} callback a function to be called once the node is created\n\t\t * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded\n\t\t * @return {String} the ID of the newly create node\n\t\t * @trigger model.jstree, create_node.jstree\n\t\t */\n\t\tcreate_node : function (par, node, pos, callback, is_loaded) {\n\t\t\tif(par === null) { par = $.jstree.root; }\n\t\t\tpar = this.get_node(par);\n\t\t\tif(!par) { return false; }\n\t\t\tpos = pos === undefined ? \"last\" : pos;\n\t\t\tif(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {\n\t\t\t\treturn this.load_node(par, function () { this.create_node(par, node, pos, callback, true); });\n\t\t\t}\n\t\t\tif(!node) { node = { \"text\" : this.get_string('New node') }; }\n\t\t\tif(typeof node === \"string\") {\n\t\t\t\tnode = { \"text\" : node };\n\t\t\t} else {\n\t\t\t\tnode = $.extend(true, {}, node);\n\t\t\t}\n\t\t\tif(node.text === undefined) { node.text = this.get_string('New node'); }\n\t\t\tvar tmp, dpc, i, j;\n\n\t\t\tif(par.id === $.jstree.root) {\n\t\t\t\tif(pos === \"before\") { pos = \"first\"; }\n\t\t\t\tif(pos === \"after\") { pos = \"last\"; }\n\t\t\t}\n\t\t\tswitch(pos) {\n\t\t\t\tcase \"before\":\n\t\t\t\t\ttmp = this.get_node(par.parent);\n\t\t\t\t\tpos = $.inArray(par.id, tmp.children);\n\t\t\t\t\tpar = tmp;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"after\" :\n\t\t\t\t\ttmp = this.get_node(par.parent);\n\t\t\t\t\tpos = $.inArray(par.id, tmp.children) + 1;\n\t\t\t\t\tpar = tmp;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"inside\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\tpos = 0;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"last\":\n\t\t\t\t\tpos = par.children.length;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(!pos) { pos = 0; }\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(pos > par.children.length) { pos = par.children.length; }\n\t\t\tif(!node.id) { node.id = true; }\n\t\t\tif(!this.check(\"create_node\", node, par, pos)) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(node.id === true) { delete node.id; }\n\t\t\tnode = this._parse_model_from_json(node, par.id, par.parents.concat());\n\t\t\tif(!node) { return false; }\n\t\t\ttmp = this.get_node(node);\n\t\t\tdpc = [];\n\t\t\tdpc.push(node);\n\t\t\tdpc = dpc.concat(tmp.children_d);\n\t\t\tthis.trigger('model', { \"nodes\" : dpc, \"parent\" : par.id });\n\n\t\t\tpar.children_d = par.children_d.concat(dpc);\n\t\t\tfor(i = 0, j = par.parents.length; i < j; i++) {\n\t\t\t\tthis._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc);\n\t\t\t}\n\t\t\tnode = tmp;\n\t\t\ttmp = [];\n\t\t\tfor(i = 0, j = par.children.length; i < j; i++) {\n\t\t\t\ttmp[i >= pos ? i+1 : i] = par.children[i];\n\t\t\t}\n\t\t\ttmp[pos] = node.id;\n\t\t\tpar.children = tmp;\n\n\t\t\tthis.redraw_node(par, true);\n\t\t\t/**\n\t\t\t * triggered when a node is created\n\t\t\t * @event\n\t\t\t * @name create_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {String} parent the parent's ID\n\t\t\t * @param {Number} position the position of the new node among the parent's children\n\t\t\t */\n\t\t\tthis.trigger('create_node', { \"node\" : this.get_node(node), \"parent\" : par.id, \"position\" : pos });\n\t\t\tif(callback) { callback.call(this, this.get_node(node)); }\n\t\t\treturn node.id;\n\t\t},\n\t\t/**\n\t\t * set the text value of a node\n\t\t * @name rename_node(obj, val)\n\t\t * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name\n\t\t * @param {String} val the new text value\n\t\t * @return {Boolean}\n\t\t * @trigger rename_node.jstree\n\t\t */\n\t\trename_node : function (obj, val) {\n\t\t\tvar t1, t2, old;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.rename_node(obj[t1], val);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\told = obj.text;\n\t\t\tif(!this.check(\"rename_node\", obj, this.get_parent(obj), val)) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments))\n\t\t\t/**\n\t\t\t * triggered when a node is renamed\n\t\t\t * @event\n\t\t\t * @name rename_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {String} text the new value\n\t\t\t * @param {String} old the old value\n\t\t\t */\n\t\t\tthis.trigger('rename_node', { \"node\" : obj, \"text\" : val, \"old\" : old });\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * remove a node\n\t\t * @name delete_node(obj)\n\t\t * @param {mixed} obj the node, you can pass an array to delete multiple nodes\n\t\t * @return {Boolean}\n\t\t * @trigger delete_node.jstree, changed.jstree\n\t\t */\n\t\tdelete_node : function (obj) {\n\t\t\tvar t1, t2, par, pos, tmp, i, j, k, l, c, top, lft;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.delete_node(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\tpar = this.get_node(obj.parent);\n\t\t\tpos = $.inArray(obj.id, par.children);\n\t\t\tc = false;\n\t\t\tif(!this.check(\"delete_node\", obj, par, pos)) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(pos !== -1) {\n\t\t\t\tpar.children = $.vakata.array_remove(par.children, pos);\n\t\t\t}\n\t\t\ttmp = obj.children_d.concat([]);\n\t\t\ttmp.push(obj.id);\n\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\tthis._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) {\n\t\t\t\t\treturn $.inArray(v, tmp) === -1;\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor(k = 0, l = tmp.length; k < l; k++) {\n\t\t\t\tif(this._model.data[tmp[k]].state.selected) {\n\t\t\t\t\tc = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (c) {\n\t\t\t\tthis._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) {\n\t\t\t\t\treturn $.inArray(v, tmp) === -1;\n\t\t\t\t});\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when a node is deleted\n\t\t\t * @event\n\t\t\t * @name delete_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {String} parent the parent's ID\n\t\t\t */\n\t\t\tthis.trigger('delete_node', { \"node\" : obj, \"parent\" : par.id });\n\t\t\tif(c) {\n\t\t\t\tthis.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id });\n\t\t\t}\n\t\t\tfor(k = 0, l = tmp.length; k < l; k++) {\n\t\t\t\tdelete this._model.data[tmp[k]];\n\t\t\t}\n\t\t\tif($.inArray(this._data.core.focused, tmp) !== -1) {\n\t\t\t\tthis._data.core.focused = null;\n\t\t\t\ttop = this.element[0].scrollTop;\n\t\t\t\tlft = this.element[0].scrollLeft;\n\t\t\t\tif(par.id === $.jstree.root) {\n\t\t\t\t\tif (this._model.data[$.jstree.root].children[0]) {\n\t\t\t\t\t\tthis.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').trigger('focus');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.get_node(par, true).children('.jstree-anchor').trigger('focus');\n\t\t\t\t}\n\t\t\t\tthis.element[0].scrollTop = top;\n\t\t\t\tthis.element[0].scrollLeft = lft;\n\t\t\t}\n\t\t\tthis.redraw_node(par, true);\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * check if an operation is premitted on the tree. Used internally.\n\t\t * @private\n\t\t * @name check(chk, obj, par, pos)\n\t\t * @param {String} chk the operation to check, can be \"create_node\", \"rename_node\", \"delete_node\", \"copy_node\" or \"move_node\"\n\t\t * @param {mixed} obj the node\n\t\t * @param {mixed} par the parent\n\t\t * @param {mixed} pos the position to insert at, or if \"rename_node\" - the new name\n\t\t * @param {mixed} more some various additional information, for example if a \"move_node\" operations is triggered by DND this will be the hovered node\n\t\t * @return {Boolean}\n\t\t */\n\t\tcheck : function (chk, obj, par, pos, more) {\n\t\t\tobj = obj && obj.id ? obj : this.get_node(obj);\n\t\t\tpar = par && par.id ? par : this.get_node(par);\n\t\t\tvar tmp = chk.match(/^(move_node|copy_node|create_node)$/i) ? par : obj,\n\t\t\t\tchc = this.settings.core.check_callback;\n\t\t\tif(chk === \"move_node\" || chk === \"copy_node\") {\n\t\t\t\tif((!more || !more.is_multi) && (chk === \"move_node\" && $.inArray(obj.id, par.children) === pos)) {\n\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_08', 'reason' : 'Moving node to its current position', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif((!more || !more.is_multi) && (obj.id === par.id || (chk === \"move_node\" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) {\n\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(tmp && tmp.data) { tmp = tmp.data; }\n\t\t\tif(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) {\n\t\t\t\tif(tmp.functions[chk] === false) {\n\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t}\n\t\t\t\treturn tmp.functions[chk];\n\t\t\t}\n\t\t\tif(chc === false || ($.vakata.is_function(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) {\n\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * get the last error\n\t\t * @name last_error()\n\t\t * @return {Object}\n\t\t */\n\t\tlast_error : function () {\n\t\t\treturn this._data.core.last_error;\n\t\t},\n\t\t/**\n\t\t * move a node to a new parent\n\t\t * @name move_node(obj, par [, pos, callback, is_loaded])\n\t\t * @param {mixed} obj the node to move, pass an array to move multiple nodes\n\t\t * @param {mixed} par the new parent\n\t\t * @param {mixed} pos the position to insert at (besides integer values, \"first\" and \"last\" are supported, as well as \"before\" and \"after\"), defaults to integer `0`\n\t\t * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position\n\t\t * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded\n\t\t * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn\n\t\t * @param {Boolean} instance internal parameter indicating if the node comes from another instance\n\t\t * @trigger move_node.jstree\n\t\t */\n\t\tmove_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) {\n\t\t\tvar t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p;\n\n\t\t\tpar = this.get_node(par);\n\t\t\tpos = pos === undefined ? 0 : pos;\n\t\t\tif(!par) { return false; }\n\t\t\tif(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {\n\t\t\t\treturn this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); });\n\t\t\t}\n\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tif(obj.length === 1) {\n\t\t\t\t\tobj = obj[0];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t//obj = obj.slice();\n\t\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\t\tif((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) {\n\t\t\t\t\t\t\tpar = tmp;\n\t\t\t\t\t\t\tpos = \"after\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.redraw();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tobj = obj && obj.id ? obj : this.get_node(obj);\n\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\n\t\t\told_par = (obj.parent || $.jstree.root).toString();\n\t\t\tnew_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent);\n\t\t\told_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));\n\t\t\tis_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);\n\t\t\told_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1;\n\t\t\tif(old_ins && old_ins._id) {\n\t\t\t\tobj = old_ins._model.data[obj.id];\n\t\t\t}\n\n\t\t\tif(is_multi) {\n\t\t\t\tif((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) {\n\t\t\t\t\tif(old_ins) { old_ins.delete_node(obj); }\n\t\t\t\t\treturn tmp;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t//var m = this._model.data;\n\t\t\tif(par.id === $.jstree.root) {\n\t\t\t\tif(pos === \"before\") { pos = \"first\"; }\n\t\t\t\tif(pos === \"after\") { pos = \"last\"; }\n\t\t\t}\n\t\t\tswitch(pos) {\n\t\t\t\tcase \"before\":\n\t\t\t\t\tpos = $.inArray(par.id, new_par.children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"after\" :\n\t\t\t\t\tpos = $.inArray(par.id, new_par.children) + 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"inside\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\tpos = 0;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"last\":\n\t\t\t\t\tpos = new_par.children.length;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(!pos) { pos = 0; }\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(pos > new_par.children.length) { pos = new_par.children.length; }\n\t\t\tif(!this.check(\"move_node\", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(obj.parent === new_par.id) {\n\t\t\t\tdpc = new_par.children.concat();\n\t\t\t\ttmp = $.inArray(obj.id, dpc);\n\t\t\t\tif(tmp !== -1) {\n\t\t\t\t\tdpc = $.vakata.array_remove(dpc, tmp);\n\t\t\t\t\tif(pos > tmp) { pos--; }\n\t\t\t\t}\n\t\t\t\ttmp = [];\n\t\t\t\tfor(i = 0, j = dpc.length; i < j; i++) {\n\t\t\t\t\ttmp[i >= pos ? i+1 : i] = dpc[i];\n\t\t\t\t}\n\t\t\t\ttmp[pos] = obj.id;\n\t\t\t\tnew_par.children = tmp;\n\t\t\t\tthis._node_changed(new_par.id);\n\t\t\t\tthis.redraw(new_par.id === $.jstree.root);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// clean old parent and up\n\t\t\t\ttmp = obj.children_d.concat();\n\t\t\t\ttmp.push(obj.id);\n\t\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\t\tdpc = [];\n\t\t\t\t\tp = old_ins._model.data[obj.parents[i]].children_d;\n\t\t\t\t\tfor(k = 0, l = p.length; k < l; k++) {\n\t\t\t\t\t\tif($.inArray(p[k], tmp) === -1) {\n\t\t\t\t\t\t\tdpc.push(p[k]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\told_ins._model.data[obj.parents[i]].children_d = dpc;\n\t\t\t\t}\n\t\t\t\told_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id);\n\n\t\t\t\t// insert into new parent and up\n\t\t\t\tfor(i = 0, j = new_par.parents.length; i < j; i++) {\n\t\t\t\t\tthis._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp);\n\t\t\t\t}\n\t\t\t\tdpc = [];\n\t\t\t\tfor(i = 0, j = new_par.children.length; i < j; i++) {\n\t\t\t\t\tdpc[i >= pos ? i+1 : i] = new_par.children[i];\n\t\t\t\t}\n\t\t\t\tdpc[pos] = obj.id;\n\t\t\t\tnew_par.children = dpc;\n\t\t\t\tnew_par.children_d.push(obj.id);\n\t\t\t\tnew_par.children_d = new_par.children_d.concat(obj.children_d);\n\n\t\t\t\t// update object\n\t\t\t\tobj.parent = new_par.id;\n\t\t\t\ttmp = new_par.parents.concat();\n\t\t\t\ttmp.unshift(new_par.id);\n\t\t\t\tp = obj.parents.length;\n\t\t\t\tobj.parents = tmp;\n\n\t\t\t\t// update object children\n\t\t\t\ttmp = tmp.concat();\n\t\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\t\tthis._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1);\n\t\t\t\t\tArray.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp);\n\t\t\t\t}\n\n\t\t\t\tif(old_par === $.jstree.root || new_par.id === $.jstree.root) {\n\t\t\t\t\tthis._model.force_full_redraw = true;\n\t\t\t\t}\n\t\t\t\tif(!this._model.force_full_redraw) {\n\t\t\t\t\tthis._node_changed(old_par);\n\t\t\t\t\tthis._node_changed(new_par.id);\n\t\t\t\t}\n\t\t\t\tif(!skip_redraw) {\n\t\t\t\t\tthis.redraw();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(callback) { callback.call(this, obj, new_par, pos); }\n\t\t\t/**\n\t\t\t * triggered when a node is moved\n\t\t\t * @event\n\t\t\t * @name move_node.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {String} parent the parent's ID\n\t\t\t * @param {Number} position the position of the node among the parent's children\n\t\t\t * @param {String} old_parent the old parent of the node\n\t\t\t * @param {Number} old_position the old position of the node\n\t\t\t * @param {Boolean} is_multi do the node and new parent belong to different instances\n\t\t\t * @param {jsTree} old_instance the instance the node came from\n\t\t\t * @param {jsTree} new_instance the instance of the new parent\n\t\t\t */\n\t\t\tthis.trigger('move_node', { \"node\" : obj, \"parent\" : new_par.id, \"position\" : pos, \"old_parent\" : old_par, \"old_position\" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });\n\t\t\treturn obj.id;\n\t\t},\n\t\t/**\n\t\t * copy a node to a new parent\n\t\t * @name copy_node(obj, par [, pos, callback, is_loaded])\n\t\t * @param {mixed} obj the node to copy, pass an array to copy multiple nodes\n\t\t * @param {mixed} par the new parent\n\t\t * @param {mixed} pos the position to insert at (besides integer values, \"first\" and \"last\" are supported, as well as \"before\" and \"after\"), defaults to integer `0`\n\t\t * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position\n\t\t * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded\n\t\t * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn\n\t\t * @param {Boolean} instance internal parameter indicating if the node comes from another instance\n\t\t * @trigger model.jstree copy_node.jstree\n\t\t */\n\t\tcopy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) {\n\t\t\tvar t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi;\n\n\t\t\tpar = this.get_node(par);\n\t\t\tpos = pos === undefined ? 0 : pos;\n\t\t\tif(!par) { return false; }\n\t\t\tif(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {\n\t\t\t\treturn this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); });\n\t\t\t}\n\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tif(obj.length === 1) {\n\t\t\t\t\tobj = obj[0];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t//obj = obj.slice();\n\t\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\t\tif((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) {\n\t\t\t\t\t\t\tpar = tmp;\n\t\t\t\t\t\t\tpos = \"after\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.redraw();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tobj = obj && obj.id ? obj : this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\n\t\t\told_par = (obj.parent || $.jstree.root).toString();\n\t\t\tnew_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent);\n\t\t\told_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));\n\t\t\tis_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);\n\n\t\t\tif(old_ins && old_ins._id) {\n\t\t\t\tobj = old_ins._model.data[obj.id];\n\t\t\t}\n\n\t\t\tif(par.id === $.jstree.root) {\n\t\t\t\tif(pos === \"before\") { pos = \"first\"; }\n\t\t\t\tif(pos === \"after\") { pos = \"last\"; }\n\t\t\t}\n\t\t\tswitch(pos) {\n\t\t\t\tcase \"before\":\n\t\t\t\t\tpos = $.inArray(par.id, new_par.children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"after\" :\n\t\t\t\t\tpos = $.inArray(par.id, new_par.children) + 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"inside\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\tpos = 0;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"last\":\n\t\t\t\t\tpos = new_par.children.length;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(!pos) { pos = 0; }\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(pos > new_par.children.length) { pos = new_par.children.length; }\n\t\t\tif(!this.check(\"copy_node\", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tnode = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj;\n\t\t\tif(!node) { return false; }\n\t\t\tif(node.id === true) { delete node.id; }\n\t\t\tnode = this._parse_model_from_json(node, new_par.id, new_par.parents.concat());\n\t\t\tif(!node) { return false; }\n\t\t\ttmp = this.get_node(node);\n\t\t\tif(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; }\n\t\t\tdpc = [];\n\t\t\tdpc.push(node);\n\t\t\tdpc = dpc.concat(tmp.children_d);\n\t\t\tthis.trigger('model', { \"nodes\" : dpc, \"parent\" : new_par.id });\n\n\t\t\t// insert into new parent and up\n\t\t\tfor(i = 0, j = new_par.parents.length; i < j; i++) {\n\t\t\t\tthis._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc);\n\t\t\t}\n\t\t\tdpc = [];\n\t\t\tfor(i = 0, j = new_par.children.length; i < j; i++) {\n\t\t\t\tdpc[i >= pos ? i+1 : i] = new_par.children[i];\n\t\t\t}\n\t\t\tdpc[pos] = tmp.id;\n\t\t\tnew_par.children = dpc;\n\t\t\tnew_par.children_d.push(tmp.id);\n\t\t\tnew_par.children_d = new_par.children_d.concat(tmp.children_d);\n\n\t\t\tif(new_par.id === $.jstree.root) {\n\t\t\t\tthis._model.force_full_redraw = true;\n\t\t\t}\n\t\t\tif(!this._model.force_full_redraw) {\n\t\t\t\tthis._node_changed(new_par.id);\n\t\t\t}\n\t\t\tif(!skip_redraw) {\n\t\t\t\tthis.redraw(new_par.id === $.jstree.root);\n\t\t\t}\n\t\t\tif(callback) { callback.call(this, tmp, new_par, pos); }\n\t\t\t/**\n\t\t\t * triggered when a node is copied\n\t\t\t * @event\n\t\t\t * @name copy_node.jstree\n\t\t\t * @param {Object} node the copied node\n\t\t\t * @param {Object} original the original node\n\t\t\t * @param {String} parent the parent's ID\n\t\t\t * @param {Number} position the position of the node among the parent's children\n\t\t\t * @param {String} old_parent the old parent of the node\n\t\t\t * @param {Number} old_position the position of the original node\n\t\t\t * @param {Boolean} is_multi do the node and new parent belong to different instances\n\t\t\t * @param {jsTree} old_instance the instance the node came from\n\t\t\t * @param {jsTree} new_instance the instance of the new parent\n\t\t\t */\n\t\t\tthis.trigger('copy_node', { \"node\" : tmp, \"original\" : obj, \"parent\" : new_par.id, \"position\" : pos, \"old_parent\" : old_par, \"old_position\" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });\n\t\t\treturn tmp.id;\n\t\t},\n\t\t/**\n\t\t * cut a node (a later call to `paste(obj)` would move the node)\n\t\t * @name cut(obj)\n\t\t * @param {mixed} obj multiple objects can be passed using an array\n\t\t * @trigger cut.jstree\n\t\t */\n\t\tcut : function (obj) {\n\t\t\tif(!obj) { obj = this._data.core.selected.concat(); }\n\t\t\tif(!$.vakata.is_array(obj)) { obj = [obj]; }\n\t\t\tif(!obj.length) { return false; }\n\t\t\tvar tmp = [], o, t1, t2;\n\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\to = this.get_node(obj[t1]);\n\t\t\t\tif(o && o.id && o.id !== $.jstree.root) { tmp.push(o); }\n\t\t\t}\n\t\t\tif(!tmp.length) { return false; }\n\t\t\tccp_node = tmp;\n\t\t\tccp_inst = this;\n\t\t\tccp_mode = 'move_node';\n\t\t\t/**\n\t\t\t * triggered when nodes are added to the buffer for moving\n\t\t\t * @event\n\t\t\t * @name cut.jstree\n\t\t\t * @param {Array} node\n\t\t\t */\n\t\t\tthis.trigger('cut', { \"node\" : obj });\n\t\t},\n\t\t/**\n\t\t * copy a node (a later call to `paste(obj)` would copy the node)\n\t\t * @name copy(obj)\n\t\t * @param {mixed} obj multiple objects can be passed using an array\n\t\t * @trigger copy.jstree\n\t\t */\n\t\tcopy : function (obj) {\n\t\t\tif(!obj) { obj = this._data.core.selected.concat(); }\n\t\t\tif(!$.vakata.is_array(obj)) { obj = [obj]; }\n\t\t\tif(!obj.length) { return false; }\n\t\t\tvar tmp = [], o, t1, t2;\n\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\to = this.get_node(obj[t1]);\n\t\t\t\tif(o && o.id && o.id !== $.jstree.root) { tmp.push(o); }\n\t\t\t}\n\t\t\tif(!tmp.length) { return false; }\n\t\t\tccp_node = tmp;\n\t\t\tccp_inst = this;\n\t\t\tccp_mode = 'copy_node';\n\t\t\t/**\n\t\t\t * triggered when nodes are added to the buffer for copying\n\t\t\t * @event\n\t\t\t * @name copy.jstree\n\t\t\t * @param {Array} node\n\t\t\t */\n\t\t\tthis.trigger('copy', { \"node\" : obj });\n\t\t},\n\t\t/**\n\t\t * get the current buffer (any nodes that are waiting for a paste operation)\n\t\t * @name get_buffer()\n\t\t * @return {Object} an object consisting of `mode` (\"copy_node\" or \"move_node\"), `node` (an array of objects) and `inst` (the instance)\n\t\t */\n\t\tget_buffer : function () {\n\t\t\treturn { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst };\n\t\t},\n\t\t/**\n\t\t * check if there is something in the buffer to paste\n\t\t * @name can_paste()\n\t\t * @return {Boolean}\n\t\t */\n\t\tcan_paste : function () {\n\t\t\treturn ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node];\n\t\t},\n\t\t/**\n\t\t * copy or move the previously cut or copied nodes to a new parent\n\t\t * @name paste(obj [, pos])\n\t\t * @param {mixed} obj the new parent\n\t\t * @param {mixed} pos the position to insert at (besides integer, \"first\" and \"last\" are supported), defaults to integer `0`\n\t\t * @trigger paste.jstree\n\t\t */\n\t\tpaste : function (obj, pos) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }\n\t\t\tif(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) {\n\t\t\t\t/**\n\t\t\t\t * triggered when paste is invoked\n\t\t\t\t * @event\n\t\t\t\t * @name paste.jstree\n\t\t\t\t * @param {String} parent the ID of the receiving node\n\t\t\t\t * @param {Array} node the nodes in the buffer\n\t\t\t\t * @param {String} mode the performed operation - \"copy_node\" or \"move_node\"\n\t\t\t\t */\n\t\t\t\tthis.trigger('paste', { \"parent\" : obj.id, \"node\" : ccp_node, \"mode\" : ccp_mode });\n\t\t\t}\n\t\t\tccp_node = false;\n\t\t\tccp_mode = false;\n\t\t\tccp_inst = false;\n\t\t},\n\t\t/**\n\t\t * clear the buffer of previously copied or cut nodes\n\t\t * @name clear_buffer()\n\t\t * @trigger clear_buffer.jstree\n\t\t */\n\t\tclear_buffer : function () {\n\t\t\tccp_node = false;\n\t\t\tccp_mode = false;\n\t\t\tccp_inst = false;\n\t\t\t/**\n\t\t\t * triggered when the copy / cut buffer is cleared\n\t\t\t * @event\n\t\t\t * @name clear_buffer.jstree\n\t\t\t */\n\t\t\tthis.trigger('clear_buffer');\n\t\t},\n\t\t/**\n\t\t * put a node in edit mode (input field to rename the node)\n\t\t * @name edit(obj [, default_text, callback])\n\t\t * @param {mixed} obj\n\t\t * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used)\n\t\t * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise), a boolean indicating if the user cancelled the edit and the original unescaped value provided by the user. You can also access the node's title using .text\n\t\t */\n\t\tedit : function (obj, default_text, callback) {\n\t\t\tvar rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false;\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) { return false; }\n\t\t\tif(!this.check(\"edit\", obj, this.get_parent(obj))) {\n\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ttmp = obj;\n\t\t\tdefault_text = typeof default_text === 'string' ? default_text : obj.text;\n\t\t\tthis.set_text(obj, \"\");\n\t\t\tobj = this._open_to(obj);\n\t\t\ttmp.text = default_text;\n\n\t\t\trtl = this._data.core.rtl;\n\t\t\tw = this.element.width();\n\t\t\tthis._data.core.focused = tmp.id;\n\t\t\ta = obj.children('.jstree-anchor').trigger('focus');\n\t\t\ts = $('');\n\t\t\t/*!\n\t\t\toi = obj.children(\"i:visible\"),\n\t\t\tai = a.children(\"i:visible\"),\n\t\t\tw1 = oi.width() * oi.length,\n\t\t\tw2 = ai.width() * ai.length,\n\t\t\t*/\n\t\t\tt = default_text;\n\t\t\th1 = $(\"<\"+\"div>
        \", { css : { \"position\" : \"absolute\", \"top\" : \"-200px\", \"left\" : (rtl ? \"0px\" : \"-1000px\"), \"visibility\" : \"hidden\" } }).appendTo(document.body);\n\t\t\th2 = $(\"<\"+\"input />\", {\n\t\t\t\t\t\t\"value\" : t,\n\t\t\t\t\t\t\"class\" : \"jstree-rename-input\",\n\t\t\t\t\t\t// \"size\" : t.length,\n\t\t\t\t\t\t\"css\" : {\n\t\t\t\t\t\t\t\"padding\" : \"0\",\n\t\t\t\t\t\t\t\"border\" : \"1px solid silver\",\n\t\t\t\t\t\t\t\"box-sizing\" : \"border-box\",\n\t\t\t\t\t\t\t\"display\" : \"inline-block\",\n\t\t\t\t\t\t\t\"height\" : (this._data.core.li_height) + \"px\",\n\t\t\t\t\t\t\t\"lineHeight\" : (this._data.core.li_height) + \"px\",\n\t\t\t\t\t\t\t\"width\" : \"150px\" // will be set a bit further down\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"blur\" : function (e) {\n\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvar i = s.children(\".jstree-rename-input\"),\n\t\t\t\t\t\t\t\tv = i.val(),\n\t\t\t\t\t\t\t\tf = this.settings.core.force_text,\n\t\t\t\t\t\t\t\tnv;\n\t\t\t\t\t\t\tif(v === \"\") { v = t; }\n\t\t\t\t\t\t\th1.remove();\n\t\t\t\t\t\t\ts.replaceWith(a);\n\t\t\t\t\t\t\ts.remove();\n\t\t\t\t\t\t\tt = f ? t : $('
        ').append($.parseHTML(t)).html();\n\t\t\t\t\t\t\tobj = this.get_node(obj);\n\t\t\t\t\t\t\tthis.set_text(obj, t);\n\t\t\t\t\t\t\tnv = !!this.rename_node(obj, f ? $('
        ').text(v).text() : $('
        ').append($.parseHTML(v)).html());\n\t\t\t\t\t\t\tif(!nv) {\n\t\t\t\t\t\t\t\tthis.set_text(obj, t); // move this up? and fix #483\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._data.core.focused = tmp.id;\n\t\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\t\tvar node = this.get_node(tmp.id, true);\n\t\t\t\t\t\t\t\tif(node.length) {\n\t\t\t\t\t\t\t\t\tthis._data.core.focused = tmp.id;\n\t\t\t\t\t\t\t\t\tnode.children('.jstree-anchor').trigger('focus');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}.bind(this), 0);\n\t\t\t\t\t\t\tif(callback) {\n\t\t\t\t\t\t\t\tcallback.call(this, tmp, nv, cancel, v);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\th2 = null;\n\t\t\t\t\t\t}.bind(this),\n\t\t\t\t\t\t\"keydown\" : function (e) {\n\t\t\t\t\t\t\tvar key = e.which;\n\t\t\t\t\t\t\tif(key === 27) {\n\t\t\t\t\t\t\t\tcancel = true;\n\t\t\t\t\t\t\t\tthis.value = t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) {\n\t\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(key === 27 || key === 13) {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tthis.blur();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"click\" : function (e) { e.stopImmediatePropagation(); },\n\t\t\t\t\t\t\"mousedown\" : function (e) { e.stopImmediatePropagation(); },\n\t\t\t\t\t\t\"keyup\" : function (e) {\n\t\t\t\t\t\t\th2.width(Math.min(h1.text(\"pW\" + this.value).width(),w));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"keypress\" : function(e) {\n\t\t\t\t\t\t\tif(e.which === 13) { return false; }\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\tfn = {\n\t\t\t\t\t\tfontFamily\t\t: a.css('fontFamily')\t\t|| '',\n\t\t\t\t\t\tfontSize\t\t: a.css('fontSize')\t\t\t|| '',\n\t\t\t\t\t\tfontWeight\t\t: a.css('fontWeight')\t\t|| '',\n\t\t\t\t\t\tfontStyle\t\t: a.css('fontStyle')\t\t|| '',\n\t\t\t\t\t\tfontStretch\t\t: a.css('fontStretch')\t\t|| '',\n\t\t\t\t\t\tfontVariant\t\t: a.css('fontVariant')\t\t|| '',\n\t\t\t\t\t\tletterSpacing\t: a.css('letterSpacing')\t|| '',\n\t\t\t\t\t\twordSpacing\t\t: a.css('wordSpacing')\t\t|| ''\n\t\t\t\t};\n\t\t\ts.attr('class', a.attr('class')).append(a.contents().clone()).append(h2);\n\t\t\ta.replaceWith(s);\n\t\t\th1.css(fn);\n\t\t\th2.css(fn).width(Math.min(h1.text(\"pW\" + h2[0].value).width(),w))[0].select();\n\t\t\t$(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) {\n\t\t\t\tif (h2 && e.target !== h2) {\n\t\t\t\t\t$(h2).trigger('blur');\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\n\t\t/**\n\t\t * changes the theme\n\t\t * @name set_theme(theme_name [, theme_url])\n\t\t * @param {String} theme_name the name of the new theme to apply\n\t\t * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory.\n\t\t * @trigger set_theme.jstree\n\t\t */\n\t\tset_theme : function (theme_name, theme_url) {\n\t\t\tif(!theme_name) { return false; }\n\t\t\tif(theme_url === true) {\n\t\t\t\tvar dir = this.settings.core.themes.dir;\n\t\t\t\tif(!dir) { dir = $.jstree.path + '/themes'; }\n\t\t\t\ttheme_url = dir + '/' + theme_name + '/style.css';\n\t\t\t}\n\t\t\tif(theme_url && $.inArray(theme_url, themes_loaded) === -1) {\n\t\t\t\t$('head').append('<'+'link rel=\"stylesheet\" href=\"' + theme_url + '\" type=\"text/css\" />');\n\t\t\t\tthemes_loaded.push(theme_url);\n\t\t\t}\n\t\t\tif(this._data.core.themes.name) {\n\t\t\t\tthis.element.removeClass('jstree-' + this._data.core.themes.name);\n\t\t\t}\n\t\t\tthis._data.core.themes.name = theme_name;\n\t\t\tthis.element.addClass('jstree-' + theme_name);\n\t\t\tthis.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive');\n\t\t\t/**\n\t\t\t * triggered when a theme is set\n\t\t\t * @event\n\t\t\t * @name set_theme.jstree\n\t\t\t * @param {String} theme the new theme\n\t\t\t */\n\t\t\tthis.trigger('set_theme', { 'theme' : theme_name });\n\t\t},\n\t\t/**\n\t\t * gets the name of the currently applied theme name\n\t\t * @name get_theme()\n\t\t * @return {String}\n\t\t */\n\t\tget_theme : function () { return this._data.core.themes.name; },\n\t\t/**\n\t\t * changes the theme variant (if the theme has variants)\n\t\t * @name set_theme_variant(variant_name)\n\t\t * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed)\n\t\t */\n\t\tset_theme_variant : function (variant_name) {\n\t\t\tif(this._data.core.themes.variant) {\n\t\t\t\tthis.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);\n\t\t\t}\n\t\t\tthis._data.core.themes.variant = variant_name;\n\t\t\tif(variant_name) {\n\t\t\t\tthis.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * gets the name of the currently applied theme variant\n\t\t * @name get_theme()\n\t\t * @return {String}\n\t\t */\n\t\tget_theme_variant : function () { return this._data.core.themes.variant; },\n\t\t/**\n\t\t * shows a striped background on the container (if the theme supports it)\n\t\t * @name show_stripes()\n\t\t */\n\t\tshow_stripes : function () {\n\t\t\tthis._data.core.themes.stripes = true;\n\t\t\tthis.get_container_ul().addClass(\"jstree-striped\");\n\t\t\t/**\n\t\t\t * triggered when stripes are shown\n\t\t\t * @event\n\t\t\t * @name show_stripes.jstree\n\t\t\t */\n\t\t\tthis.trigger('show_stripes');\n\t\t},\n\t\t/**\n\t\t * hides the striped background on the container\n\t\t * @name hide_stripes()\n\t\t */\n\t\thide_stripes : function () {\n\t\t\tthis._data.core.themes.stripes = false;\n\t\t\tthis.get_container_ul().removeClass(\"jstree-striped\");\n\t\t\t/**\n\t\t\t * triggered when stripes are hidden\n\t\t\t * @event\n\t\t\t * @name hide_stripes.jstree\n\t\t\t */\n\t\t\tthis.trigger('hide_stripes');\n\t\t},\n\t\t/**\n\t\t * toggles the striped background on the container\n\t\t * @name toggle_stripes()\n\t\t */\n\t\ttoggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } },\n\t\t/**\n\t\t * shows the connecting dots (if the theme supports it)\n\t\t * @name show_dots()\n\t\t */\n\t\tshow_dots : function () {\n\t\t\tthis._data.core.themes.dots = true;\n\t\t\tthis.get_container_ul().removeClass(\"jstree-no-dots\");\n\t\t\t/**\n\t\t\t * triggered when dots are shown\n\t\t\t * @event\n\t\t\t * @name show_dots.jstree\n\t\t\t */\n\t\t\tthis.trigger('show_dots');\n\t\t},\n\t\t/**\n\t\t * hides the connecting dots\n\t\t * @name hide_dots()\n\t\t */\n\t\thide_dots : function () {\n\t\t\tthis._data.core.themes.dots = false;\n\t\t\tthis.get_container_ul().addClass(\"jstree-no-dots\");\n\t\t\t/**\n\t\t\t * triggered when dots are hidden\n\t\t\t * @event\n\t\t\t * @name hide_dots.jstree\n\t\t\t */\n\t\t\tthis.trigger('hide_dots');\n\t\t},\n\t\t/**\n\t\t * toggles the connecting dots\n\t\t * @name toggle_dots()\n\t\t */\n\t\ttoggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },\n\t\t/**\n\t\t * show the node icons\n\t\t * @name show_icons()\n\t\t */\n\t\tshow_icons : function () {\n\t\t\tthis._data.core.themes.icons = true;\n\t\t\tthis.get_container_ul().removeClass(\"jstree-no-icons\");\n\t\t\t/**\n\t\t\t * triggered when icons are shown\n\t\t\t * @event\n\t\t\t * @name show_icons.jstree\n\t\t\t */\n\t\t\tthis.trigger('show_icons');\n\t\t},\n\t\t/**\n\t\t * hide the node icons\n\t\t * @name hide_icons()\n\t\t */\n\t\thide_icons : function () {\n\t\t\tthis._data.core.themes.icons = false;\n\t\t\tthis.get_container_ul().addClass(\"jstree-no-icons\");\n\t\t\t/**\n\t\t\t * triggered when icons are hidden\n\t\t\t * @event\n\t\t\t * @name hide_icons.jstree\n\t\t\t */\n\t\t\tthis.trigger('hide_icons');\n\t\t},\n\t\t/**\n\t\t * toggle the node icons\n\t\t * @name toggle_icons()\n\t\t */\n\t\ttoggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } },\n\t\t/**\n\t\t * show the node ellipsis\n\t\t * @name show_icons()\n\t\t */\n\t\tshow_ellipsis : function () {\n\t\t\tthis._data.core.themes.ellipsis = true;\n\t\t\tthis.get_container_ul().addClass(\"jstree-ellipsis\");\n\t\t\t/**\n\t\t\t * triggered when ellisis is shown\n\t\t\t * @event\n\t\t\t * @name show_ellipsis.jstree\n\t\t\t */\n\t\t\tthis.trigger('show_ellipsis');\n\t\t},\n\t\t/**\n\t\t * hide the node ellipsis\n\t\t * @name hide_ellipsis()\n\t\t */\n\t\thide_ellipsis : function () {\n\t\t\tthis._data.core.themes.ellipsis = false;\n\t\t\tthis.get_container_ul().removeClass(\"jstree-ellipsis\");\n\t\t\t/**\n\t\t\t * triggered when ellisis is hidden\n\t\t\t * @event\n\t\t\t * @name hide_ellipsis.jstree\n\t\t\t */\n\t\t\tthis.trigger('hide_ellipsis');\n\t\t},\n\t\t/**\n\t\t * toggle the node ellipsis\n\t\t * @name toggle_icons()\n\t\t */\n\t\ttoggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } },\n\t\t/**\n\t\t * set the node icon for a node\n\t\t * @name set_icon(obj, icon)\n\t\t * @param {mixed} obj\n\t\t * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class\n\t\t */\n\t\tset_icon : function (obj, icon) {\n\t\t\tvar t1, t2, dom, old;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.set_icon(obj[t1], icon);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\told = obj.icon;\n\t\t\tobj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon;\n\t\t\tdom = this.get_node(obj, true).children(\".jstree-anchor\").children(\".jstree-themeicon\");\n\t\t\tif(icon === false) {\n\t\t\t\tdom.removeClass('jstree-themeicon-custom ' + old).css(\"background\",\"\").removeAttr(\"rel\");\n\t\t\t\tthis.hide_icon(obj);\n\t\t\t}\n\t\t\telse if(icon === true || icon === null || icon === undefined || icon === '') {\n\t\t\t\tdom.removeClass('jstree-themeicon-custom ' + old).css(\"background\",\"\").removeAttr(\"rel\");\n\t\t\t\tif(old === false) { this.show_icon(obj); }\n\t\t\t}\n\t\t\telse if(icon.indexOf(\"/\") === -1 && icon.indexOf(\".\") === -1) {\n\t\t\t\tdom.removeClass(old).css(\"background\",\"\");\n\t\t\t\tdom.addClass(icon + ' jstree-themeicon-custom').attr(\"rel\",icon);\n\t\t\t\tif(old === false) { this.show_icon(obj); }\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdom.removeClass(old).css(\"background\",\"\");\n\t\t\t\tdom.addClass('jstree-themeicon-custom').css(\"background\", \"url('\" + icon + \"') center center no-repeat\").attr(\"rel\",icon);\n\t\t\t\tif(old === false) { this.show_icon(obj); }\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * get the node icon for a node\n\t\t * @name get_icon(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {String}\n\t\t */\n\t\tget_icon : function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn (!obj || obj.id === $.jstree.root) ? false : obj.icon;\n\t\t},\n\t\t/**\n\t\t * hide the icon on an individual node\n\t\t * @name hide_icon(obj)\n\t\t * @param {mixed} obj\n\t\t */\n\t\thide_icon : function (obj) {\n\t\t\tvar t1, t2;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.hide_icon(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj === $.jstree.root) { return false; }\n\t\t\tobj.icon = false;\n\t\t\tthis.get_node(obj, true).children(\".jstree-anchor\").children(\".jstree-themeicon\").addClass('jstree-themeicon-hidden');\n\t\t\treturn true;\n\t\t},\n\t\t/**\n\t\t * show the icon on an individual node\n\t\t * @name show_icon(obj)\n\t\t * @param {mixed} obj\n\t\t */\n\t\tshow_icon : function (obj) {\n\t\t\tvar t1, t2, dom;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.show_icon(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj === $.jstree.root) { return false; }\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tobj.icon = dom.length ? dom.children(\".jstree-anchor\").children(\".jstree-themeicon\").attr('rel') : true;\n\t\t\tif(!obj.icon) { obj.icon = true; }\n\t\t\tdom.children(\".jstree-anchor\").children(\".jstree-themeicon\").removeClass('jstree-themeicon-hidden');\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t// helpers\n\t$.vakata = {};\n\t// collect attributes\n\t$.vakata.attributes = function(node, with_values) {\n\t\tnode = $(node)[0];\n\t\tvar attr = with_values ? {} : [];\n\t\tif(node && node.attributes) {\n\t\t\t$.each(node.attributes, function (i, v) {\n\t\t\t\tif($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; }\n\t\t\t\tif(v.value !== null && $.vakata.trim(v.value) !== '') {\n\t\t\t\t\tif(with_values) { attr[v.name] = v.value; }\n\t\t\t\t\telse { attr.push(v.name); }\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn attr;\n\t};\n\t$.vakata.array_unique = function(array) {\n\t\tvar a = [], i, j, l, o = {};\n\t\tfor(i = 0, l = array.length; i < l; i++) {\n\t\t\tif(o[array[i]] === undefined) {\n\t\t\t\ta.push(array[i]);\n\t\t\t\to[array[i]] = true;\n\t\t\t}\n\t\t}\n\t\treturn a;\n\t};\n\t// remove item from array\n\t$.vakata.array_remove = function(array, from) {\n\t\tarray.splice(from, 1);\n\t\treturn array;\n\t\t//var rest = array.slice((to || from) + 1 || array.length);\n\t\t//array.length = from < 0 ? array.length + from : from;\n\t\t//array.push.apply(array, rest);\n\t\t//return array;\n\t};\n\t// remove item from array\n\t$.vakata.array_remove_item = function(array, item) {\n\t\tvar tmp = $.inArray(item, array);\n\t\treturn tmp !== -1 ? $.vakata.array_remove(array, tmp) : array;\n\t};\n\t$.vakata.array_filter = function(c,a,b,d,e) {\n\t\tif (c.filter) {\n\t\t\treturn c.filter(a, b);\n\t\t}\n\t\td=[];\n\t\tfor (e in c) {\n\t\t\tif (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) {\n\t\t\t\td.push(c[e]);\n\t\t\t}\n\t\t}\n\t\treturn d;\n\t};\n\t$.vakata.trim = function (text) {\n\t\treturn String.prototype.trim ? \n\t\t\tString.prototype.trim.call(text.toString()) :\n\t\t\ttext.toString().replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t};\n\t$.vakata.is_function = function(obj) {\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n\t};\n\t$.vakata.is_array = Array.isArray || function (obj) {\n\t\treturn Object.prototype.toString.call(obj) === \"[object Array]\";\n\t};\n\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind#polyfill\n\tif (!Function.prototype.bind) {\n\t\tFunction.prototype.bind = function () {\n\t\t\tvar thatFunc = this, thatArg = arguments[0];\n\t\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\t\t\tif (typeof thatFunc !== 'function') {\n\t\t\t\t// closest thing possible to the ECMAScript 5\n\t\t\t\t// internal IsCallable function\n\t\t\t\tthrow new TypeError('Function.prototype.bind - what is trying to be bound is not callable');\n\t\t\t}\n\t\t\treturn function(){\n\t\t\t\tvar funcArgs = args.concat(Array.prototype.slice.call(arguments));\n\t\t\t\treturn thatFunc.apply(thatArg, funcArgs);\n\t\t\t};\n\t\t};\n\t}\n\n\n/**\n * ### Changed plugin\n *\n * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes.\n */\n\n\t$.jstree.plugins.changed = function (options, parent) {\n\t\tvar last = [];\n\t\tthis.trigger = function (ev, data) {\n\t\t\tvar i, j;\n\t\t\tif(!data) {\n\t\t\t\tdata = {};\n\t\t\t}\n\t\t\tif(ev.replace('.jstree','') === 'changed') {\n\t\t\t\tdata.changed = { selected : [], deselected : [] };\n\t\t\t\tvar tmp = {};\n\t\t\t\tfor(i = 0, j = last.length; i < j; i++) {\n\t\t\t\t\ttmp[last[i]] = 1;\n\t\t\t\t}\n\t\t\t\tfor(i = 0, j = data.selected.length; i < j; i++) {\n\t\t\t\t\tif(!tmp[data.selected[i]]) {\n\t\t\t\t\t\tdata.changed.selected.push(data.selected[i]);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\ttmp[data.selected[i]] = 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor(i = 0, j = last.length; i < j; i++) {\n\t\t\t\t\tif(tmp[last[i]] === 1) {\n\t\t\t\t\t\tdata.changed.deselected.push(last[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlast = data.selected.slice();\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered when selection changes (the \"changed\" plugin enhances the original event with more data)\n\t\t\t * @event\n\t\t\t * @name changed.jstree\n\t\t\t * @param {Object} node\n\t\t\t * @param {Object} action the action that caused the selection to change\n\t\t\t * @param {Array} selected the current selection\n\t\t\t * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event\n\t\t\t * @param {Object} event the event (if any) that triggered this changed event\n\t\t\t * @plugin changed\n\t\t\t */\n\t\t\tparent.trigger.call(this, ev, data);\n\t\t};\n\t\tthis.refresh = function (skip_loading, forget_state) {\n\t\t\tlast = [];\n\t\t\treturn parent.refresh.apply(this, arguments);\n\t\t};\n\t};\n\n/**\n * ### Checkbox plugin\n *\n * This plugin renders checkbox icons in front of each node, making multiple selection much easier.\n * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.\n */\n\n\tvar _i = document.createElement('I');\n\t_i.className = 'jstree-icon jstree-checkbox';\n\t_i.setAttribute('role', 'presentation');\n\t/**\n\t * stores all defaults for the checkbox plugin\n\t * @name $.jstree.defaults.checkbox\n\t * @plugin checkbox\n\t */\n\t$.jstree.defaults.checkbox = {\n\t\t/**\n\t\t * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.\n\t\t * @name $.jstree.defaults.checkbox.visible\n\t\t * @plugin checkbox\n\t\t */\n\t\tvisible\t\t\t\t: true,\n\t\t/**\n\t\t * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.\n\t\t * @name $.jstree.defaults.checkbox.three_state\n\t\t * @plugin checkbox\n\t\t */\n\t\tthree_state\t\t\t: true,\n\t\t/**\n\t\t * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.\n\t\t * @name $.jstree.defaults.checkbox.whole_node\n\t\t * @plugin checkbox\n\t\t */\n\t\twhole_node\t\t\t: true,\n\t\t/**\n\t\t * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.\n\t\t * @name $.jstree.defaults.checkbox.keep_selected_style\n\t\t * @plugin checkbox\n\t\t */\n\t\tkeep_selected_style\t: true,\n\t\t/**\n\t\t * This setting controls how cascading and undetermined nodes are applied.\n\t\t * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used.\n\t\t * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.\n\t\t * @name $.jstree.defaults.checkbox.cascade\n\t\t * @plugin checkbox\n\t\t */\n\t\tcascade\t\t\t\t: '',\n\t\t/**\n\t\t * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.\n\t\t * @name $.jstree.defaults.checkbox.tie_selection\n\t\t * @plugin checkbox\n\t\t */\n\t\ttie_selection\t\t: true,\n\n\t\t/**\n\t\t * This setting controls if cascading down affects disabled checkboxes\n\t\t * @name $.jstree.defaults.checkbox.cascade_to_disabled\n\t\t * @plugin checkbox\n\t\t */\n\t\tcascade_to_disabled : true,\n\n\t\t/**\n\t\t * This setting controls if cascading down affects hidden checkboxes\n\t\t * @name $.jstree.defaults.checkbox.cascade_to_hidden\n\t\t * @plugin checkbox\n\t\t */\n\t\tcascade_to_hidden : true\n\t};\n\t$.jstree.plugins.checkbox = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\t\t\tthis._data.checkbox.uto = false;\n\t\t\tthis._data.checkbox.selected = [];\n\t\t\tif(this.settings.checkbox.three_state) {\n\t\t\t\tthis.settings.checkbox.cascade = 'up+down+undetermined';\n\t\t\t}\n\t\t\tthis.element\n\t\t\t\t.on(\"init.jstree\", function () {\n\t\t\t\t\t\tthis._data.checkbox.visible = this.settings.checkbox.visible;\n\t\t\t\t\t\tif(!this.settings.checkbox.keep_selected_style) {\n\t\t\t\t\t\t\tthis.element.addClass('jstree-checkbox-no-clicked');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.settings.checkbox.tie_selection) {\n\t\t\t\t\t\t\tthis.element.addClass('jstree-checkbox-selection');\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"loading.jstree\", function () {\n\t\t\t\t\t\tthis[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();\n\t\t\t\t\t}.bind(this));\n\t\t\tif(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {\n\t\t\t\tthis.element\n\t\t\t\t\t.on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', function () {\n\t\t\t\t\t\t\t// only if undetermined is in setting\n\t\t\t\t\t\t\tif(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }\n\t\t\t\t\t\t\tthis._data.checkbox.uto = setTimeout(this._undetermined.bind(this), 50);\n\t\t\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t\tif(!this.settings.checkbox.tie_selection) {\n\t\t\t\tthis.element\n\t\t\t\t\t.on('model.jstree', function (e, data) {\n\t\t\t\t\t\tvar m = this._model.data,\n\t\t\t\t\t\t\tp = m[data.parent],\n\t\t\t\t\t\t\tdpc = data.nodes,\n\t\t\t\t\t\t\ti, j;\n\t\t\t\t\t\tfor(i = 0, j = dpc.length; i < j; i++) {\n\t\t\t\t\t\t\tm[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);\n\t\t\t\t\t\t\tif(m[dpc[i]].state.checked) {\n\t\t\t\t\t\t\t\tthis._data.checkbox.selected.push(dpc[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t\tif(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) {\n\t\t\t\tthis.element\n\t\t\t\t\t.on('model.jstree', function (e, data) {\n\t\t\t\t\t\t\tvar m = this._model.data,\n\t\t\t\t\t\t\t\tp = m[data.parent],\n\t\t\t\t\t\t\t\tdpc = data.nodes,\n\t\t\t\t\t\t\t\tchd = [],\n\t\t\t\t\t\t\t\tc, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;\n\n\t\t\t\t\t\t\tif(s.indexOf('down') !== -1) {\n\t\t\t\t\t\t\t\t// apply down\n\t\t\t\t\t\t\t\tif(p.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\t\tfor(i = 0, j = dpc.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\tm[dpc[i]].state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tfor(i = 0, j = dpc.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\tif(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\t\t\t\tfor(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {\n\t\t\t\t\t\t\t\t\t\t\t\tm[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif(s.indexOf('up') !== -1) {\n\t\t\t\t\t\t\t\t// apply up\n\t\t\t\t\t\t\t\tfor(i = 0, j = p.children_d.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\tif(!m[p.children_d[i]].children.length) {\n\t\t\t\t\t\t\t\t\t\tchd.push(m[p.children_d[i]].parent);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tchd = $.vakata.array_unique(chd);\n\t\t\t\t\t\t\t\tfor(k = 0, l = chd.length; k < l; k++) {\n\t\t\t\t\t\t\t\t\tp = m[chd[k]];\n\t\t\t\t\t\t\t\t\twhile(p && p.id !== $.jstree.root) {\n\t\t\t\t\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\t\t\t\t\tfor(i = 0, j = p.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\t\tc += m[p.children[i]].state[ t ? 'selected' : 'checked' ];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif(c === j) {\n\t\t\t\t\t\t\t\t\t\t\tp.state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);\n\t\t\t\t\t\t\t\t\t\t\ttmp = this.get_node(p, true);\n\t\t\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', true).addClass( t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tp = this.get_node(p.parent);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected);\n\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t.on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', function (e, data) {\n\t\t\t\t\t\t\tvar self = this,\n\t\t\t\t\t\t\t\tobj = data.node,\n\t\t\t\t\t\t\t\tm = this._model.data,\n\t\t\t\t\t\t\t\tpar = this.get_node(obj.parent),\n\t\t\t\t\t\t\t\ti, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,\n\t\t\t\t\t\t\t\tsel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected;\n\n\t\t\t\t\t\t\tfor (i = 0, j = cur.length; i < j; i++) {\n\t\t\t\t\t\t\t\tsel[cur[i]] = true;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// apply down\n\t\t\t\t\t\t\tif(s.indexOf('down') !== -1) {\n\t\t\t\t\t\t\t\t//this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));\n\t\t\t\t\t\t\t\tvar selectedIds = this._cascade_new_checked_state(obj.id, true);\n\t\t\t\t\t\t\t\tvar temp = obj.children_d.concat(obj.id);\n\t\t\t\t\t\t\t\tfor (i = 0, j = temp.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\tif (selectedIds.indexOf(temp[i]) > -1) {\n\t\t\t\t\t\t\t\t\t\tsel[temp[i]] = true;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\tdelete sel[temp[i]];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// apply up\n\t\t\t\t\t\t\tif(s.indexOf('up') !== -1) {\n\t\t\t\t\t\t\t\twhile(par && par.id !== $.jstree.root) {\n\t\t\t\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\t\t\t\tfor(i = 0, j = par.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\tc += m[par.children[i]].state[ t ? 'selected' : 'checked' ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(c === j) {\n\t\t\t\t\t\t\t\t\t\tpar.state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t\tsel[par.id] = true;\n\t\t\t\t\t\t\t\t\t\t//this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);\n\t\t\t\t\t\t\t\t\t\ttmp = this.get_node(par, true);\n\t\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tpar = this.get_node(par.parent);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tcur = [];\n\t\t\t\t\t\t\tfor (i in sel) {\n\t\t\t\t\t\t\t\tif (sel.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\tcur.push(i);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = cur;\n\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t.on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', function (e, data) {\n\t\t\t\t\t\t\tvar obj = this.get_node($.jstree.root),\n\t\t\t\t\t\t\t\tm = this._model.data,\n\t\t\t\t\t\t\t\ti, j, tmp;\n\t\t\t\t\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\t\t\t\t\ttmp = m[obj.children_d[i]];\n\t\t\t\t\t\t\t\tif(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {\n\t\t\t\t\t\t\t\t\ttmp.original.state.undetermined = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t.on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', function (e, data) {\n\t\t\t\t\t\t\tvar self = this,\n\t\t\t\t\t\t\t\tobj = data.node,\n\t\t\t\t\t\t\t\tdom = this.get_node(obj, true),\n\t\t\t\t\t\t\t\ti, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,\n\t\t\t\t\t\t\t\tcur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {},\n\t\t\t\t\t\t\t\tstillSelectedIds = [],\n\t\t\t\t\t\t\t\tallIds = obj.children_d.concat(obj.id);\n\n\t\t\t\t\t\t\t// apply down\n\t\t\t\t\t\t\tif(s.indexOf('down') !== -1) {\n\t\t\t\t\t\t\t\tvar selectedIds = this._cascade_new_checked_state(obj.id, false);\n\n\t\t\t\t\t\t\t\tcur = $.vakata.array_filter(cur, function(id) {\n\t\t\t\t\t\t\t\t\treturn allIds.indexOf(id) === -1 || selectedIds.indexOf(id) > -1;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// only apply up if cascade up is enabled and if this node is not selected\n\t\t\t\t\t\t\t// (if all child nodes are disabled and cascade_to_disabled === false then this node will till be selected).\n\t\t\t\t\t\t\tif(s.indexOf('up') !== -1 && cur.indexOf(obj.id) === -1) {\n\t\t\t\t\t\t\t\tfor(i = 0, j = obj.parents.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\ttmp = this._model.data[obj.parents[i]];\n\t\t\t\t\t\t\t\t\ttmp.state[ t ? 'selected' : 'checked' ] = false;\n\t\t\t\t\t\t\t\t\tif(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {\n\t\t\t\t\t\t\t\t\t\ttmp.original.state.undetermined = false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttmp = this.get_node(obj.parents[i], true);\n\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcur = $.vakata.array_filter(cur, function(id) {\n\t\t\t\t\t\t\t\t\treturn obj.parents.indexOf(id) === -1;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = cur;\n\t\t\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t\tif(this.settings.checkbox.cascade.indexOf('up') !== -1) {\n\t\t\t\tthis.element\n\t\t\t\t\t.on('delete_node.jstree', function (e, data) {\n\t\t\t\t\t\t\t// apply up (whole handler)\n\t\t\t\t\t\t\tvar p = this.get_node(data.parent),\n\t\t\t\t\t\t\t\tm = this._model.data,\n\t\t\t\t\t\t\t\ti, j, c, tmp, t = this.settings.checkbox.tie_selection;\n\t\t\t\t\t\t\twhile(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\t\t\tfor(i = 0, j = p.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\tc += m[p.children[i]].state[ t ? 'selected' : 'checked' ];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(j > 0 && c === j) {\n\t\t\t\t\t\t\t\t\tp.state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);\n\t\t\t\t\t\t\t\t\ttmp = this.get_node(p, true);\n\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp = this.get_node(p.parent);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t.on('move_node.jstree', function (e, data) {\n\t\t\t\t\t\t\t// apply up (whole handler)\n\t\t\t\t\t\t\tvar is_multi = data.is_multi,\n\t\t\t\t\t\t\t\told_par = data.old_parent,\n\t\t\t\t\t\t\t\tnew_par = this.get_node(data.parent),\n\t\t\t\t\t\t\t\tm = this._model.data,\n\t\t\t\t\t\t\t\tp, c, i, j, tmp, t = this.settings.checkbox.tie_selection;\n\t\t\t\t\t\t\tif(!is_multi) {\n\t\t\t\t\t\t\t\tp = this.get_node(old_par);\n\t\t\t\t\t\t\t\twhile(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\t\t\t\tfor(i = 0, j = p.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\tc += m[p.children[i]].state[ t ? 'selected' : 'checked' ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(j > 0 && c === j) {\n\t\t\t\t\t\t\t\t\t\tp.state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);\n\t\t\t\t\t\t\t\t\t\ttmp = this.get_node(p, true);\n\t\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tp = this.get_node(p.parent);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp = new_par;\n\t\t\t\t\t\t\twhile(p && p.id !== $.jstree.root) {\n\t\t\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\t\t\tfor(i = 0, j = p.children.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\tc += m[p.children[i]].state[ t ? 'selected' : 'checked' ];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(c === j) {\n\t\t\t\t\t\t\t\t\tif(!p.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\t\t\tp.state[ t ? 'selected' : 'checked' ] = true;\n\t\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);\n\t\t\t\t\t\t\t\t\t\ttmp = this.get_node(p, true);\n\t\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tif(p.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\t\t\t\t\t\tp.state[ t ? 'selected' : 'checked' ] = false;\n\t\t\t\t\t\t\t\t\t\tthis._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id);\n\t\t\t\t\t\t\t\t\t\ttmp = this.get_node(p, true);\n\t\t\t\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\t\t\t\ttmp.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp = this.get_node(p.parent);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t};\n\t\t/**\n\t\t * get an array of all nodes whose state is \"undetermined\"\n\t\t * @name get_undetermined([full])\n\t\t * @param {boolean} full: if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.get_undetermined = function (full) {\n\t\t\tif (this.settings.checkbox.cascade.indexOf('undetermined') === -1) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tvar i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this, r = [];\n\t\t\tfor(i = 0, j = s.length; i < j; i++) {\n\t\t\t\tif(m[s[i]] && m[s[i]].parents) {\n\t\t\t\t\tfor(k = 0, l = m[s[i]].parents.length; k < l; k++) {\n\t\t\t\t\t\tif(o[m[s[i]].parents[k]] !== undefined) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(m[s[i]].parents[k] !== $.jstree.root) {\n\t\t\t\t\t\t\to[m[s[i]].parents[k]] = true;\n\t\t\t\t\t\t\tp.push(m[s[i]].parents[k]);\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// attempt for server side undetermined state\n\t\t\tthis.element.find('.jstree-closed').not(':has(.jstree-children)')\n\t\t\t\t.each(function () {\n\t\t\t\t\tvar tmp = tt.get_node(this), tmp2;\n\t\t\t\t\t\n\t\t\t\t\tif(!tmp) { return; }\n\t\t\t\t\t\n\t\t\t\t\tif(!tmp.state.loaded) {\n\t\t\t\t\t\tif(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {\n\t\t\t\t\t\t\tif(o[tmp.id] === undefined && tmp.id !== $.jstree.root) {\n\t\t\t\t\t\t\t\to[tmp.id] = true;\n\t\t\t\t\t\t\t\tp.push(tmp.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor(k = 0, l = tmp.parents.length; k < l; k++) {\n\t\t\t\t\t\t\t\tif(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) {\n\t\t\t\t\t\t\t\t\to[tmp.parents[k]] = true;\n\t\t\t\t\t\t\t\t\tp.push(tmp.parents[k]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(i = 0, j = tmp.children_d.length; i < j; i++) {\n\t\t\t\t\t\t\ttmp2 = m[tmp.children_d[i]];\n\t\t\t\t\t\t\tif(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {\n\t\t\t\t\t\t\t\tif(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) {\n\t\t\t\t\t\t\t\t\to[tmp2.id] = true;\n\t\t\t\t\t\t\t\t\tp.push(tmp2.id);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor(k = 0, l = tmp2.parents.length; k < l; k++) {\n\t\t\t\t\t\t\t\t\tif(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) {\n\t\t\t\t\t\t\t\t\t\to[tmp2.parents[k]] = true;\n\t\t\t\t\t\t\t\t\t\tp.push(tmp2.parents[k]);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\tfor (i = 0, j = p.length; i < j; i++) {\n\t\t\t\tif(!m[p[i]].state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\tr.push(full ? m[p[i]] : p[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn r;\n\t\t};\n\t\t/**\n\t\t * set the undetermined state where and if necessary. Used internally.\n\t\t * @private\n\t\t * @name _undetermined()\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis._undetermined = function () {\n\t\t\tif(this.element === null) { return; }\n\t\t\tvar p = this.get_undetermined(false), i, j, s;\n\n\t\t\tthis.element.find('.jstree-undetermined').removeClass('jstree-undetermined');\n\t\t\tfor (i = 0, j = p.length; i < j; i++) {\n\t\t\t\ts = this.get_node(p[i], true);\n\t\t\t\tif(s && s.length) {\n\t\t\t\t\ts.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined');\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tthis.redraw_node = function(obj, deep, is_callback, force_render) {\n\t\t\tobj = parent.redraw_node.apply(this, arguments);\n\t\t\tif(obj) {\n\t\t\t\tvar i, j, tmp = null, icon = null;\n\t\t\t\tfor(i = 0, j = obj.childNodes.length; i < j; i++) {\n\t\t\t\t\tif(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf(\"jstree-anchor\") !== -1) {\n\t\t\t\t\t\ttmp = obj.childNodes[i];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(tmp) {\n\t\t\t\t\tif(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }\n\t\t\t\t\ticon = _i.cloneNode(false);\n\t\t\t\t\tif(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; }\n\t\t\t\t\ttmp.insertBefore(icon, tmp.childNodes[0]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {\n\t\t\t\tif(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }\n\t\t\t\tthis._data.checkbox.uto = setTimeout(this._undetermined.bind(this), 50);\n\t\t\t}\n\t\t\treturn obj;\n\t\t};\n\t\t/**\n\t\t * show the node checkbox icons\n\t\t * @name show_checkboxes()\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass(\"jstree-no-checkboxes\"); };\n\t\t/**\n\t\t * hide the node checkbox icons\n\t\t * @name hide_checkboxes()\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass(\"jstree-no-checkboxes\"); };\n\t\t/**\n\t\t * toggle the node icons\n\t\t * @name toggle_checkboxes()\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };\n\t\t/**\n\t\t * checks if a node is in an undetermined state\n\t\t * @name is_undetermined(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t */\n\t\tthis.is_undetermined = function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tvar s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data;\n\t\t\tif(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(!obj.state.loaded && obj.original.state.undetermined === true) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\tif($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t\t/**\n\t\t * disable a node's checkbox\n\t\t * @name disable_checkbox(obj)\n\t\t * @param {mixed} obj an array can be used too\n\t\t * @trigger disable_checkbox.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.disable_checkbox = function (obj) {\n\t\t\tvar t1, t2, dom;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.disable_checkbox(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(!obj.state.checkbox_disabled) {\n\t\t\t\tobj.state.checkbox_disabled = true;\n\t\t\t\tif(dom && dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled');\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node's checkbox is disabled\n\t\t\t\t * @event\n\t\t\t\t * @name disable_checkbox.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @plugin checkbox\n\t\t\t\t */\n\t\t\t\tthis.trigger('disable_checkbox', { 'node' : obj });\n\t\t\t}\n\t\t};\n\t\t/**\n\t\t * enable a node's checkbox\n\t\t * @name enable_checkbox(obj)\n\t\t * @param {mixed} obj an array can be used too\n\t\t * @trigger enable_checkbox.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.enable_checkbox = function (obj) {\n\t\t\tvar t1, t2, dom;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.enable_checkbox(obj[t1]);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(obj.state.checkbox_disabled) {\n\t\t\t\tobj.state.checkbox_disabled = false;\n\t\t\t\tif(dom && dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled');\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node's checkbox is enabled\n\t\t\t\t * @event\n\t\t\t\t * @name enable_checkbox.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @plugin checkbox\n\t\t\t\t */\n\t\t\t\tthis.trigger('enable_checkbox', { 'node' : obj });\n\t\t\t}\n\t\t};\n\n\t\tthis.activate_node = function (obj, e) {\n\t\t\tif($(e.target).hasClass('jstree-checkbox-disabled')) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {\n\t\t\t\te.ctrlKey = true;\n\t\t\t}\n\t\t\tif(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) {\n\t\t\t\treturn parent.activate_node.call(this, obj, e);\n\t\t\t}\n\t\t\tif(this.is_disabled(obj)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif(this.is_checked(obj)) {\n\t\t\t\tthis.uncheck_node(obj, e);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.check_node(obj, e);\n\t\t\t}\n\t\t\tthis.trigger('activate_node', { 'node' : this.get_node(obj) });\n\t\t};\n\t\tthis.delete_node = function (obj) {\n\t\t\tif(this.settings.checkbox.tie_selection || $.vakata.is_array(obj)) {\n\t\t\t\treturn parent.delete_node(obj);\n\t\t\t}\n\t\t\tvar tmp, k, l, c = false;\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\ttmp = obj.children_d.concat([]);\n\t\t\ttmp.push(obj.id);\n\t\t\tfor(k = 0, l = tmp.length; k < l; k++) {\n\t\t\t\tif(this._model.data[tmp[k]].state.checked) {\n\t\t\t\t\tc = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (c) {\n\t\t\t\tthis._data.checkbox.selected = $.vakata.array_filter(this._data.checkbox.selected, function (v) {\n\t\t\t\t\treturn $.inArray(v, tmp) === -1;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn parent.delete_node.call(this, obj);\n\t\t};\n\n\t\t/**\n\t\t * Cascades checked state to a node and all its descendants. This function does NOT affect hidden and disabled nodes (or their descendants).\n\t\t * However if these unaffected nodes are already selected their ids will be included in the returned array.\n\t\t * @private\n\t\t * @name _cascade_new_checked_state(id, checkedState)\n\t\t * @param {string} id the node ID\n\t\t * @param {bool} checkedState should the nodes be checked or not\n\t\t * @returns {Array} Array of all node id's (in this tree branch) that are checked.\n\t\t */\n\t\tthis._cascade_new_checked_state = function (id, checkedState) {\n\t\t\tvar self = this;\n\t\t\tvar t = this.settings.checkbox.tie_selection;\n\t\t\tvar node = this._model.data[id];\n\t\t\tvar selectedNodeIds = [];\n\t\t\tvar selectedChildrenIds = [], i, j, selectedChildIds;\n\n\t\t\tif (\n\t\t\t\t(this.settings.checkbox.cascade_to_disabled || !node.state.disabled) &&\n\t\t\t\t(this.settings.checkbox.cascade_to_hidden || !node.state.hidden)\n\t\t\t) {\n\t\t\t\t//First try and check/uncheck the children\n\t\t\t\tif (node.children) {\n\t\t\t\t\tfor (i = 0, j = node.children.length; i < j; i++) {\n\t\t\t\t\t\tvar childId = node.children[i];\n\t\t\t\t\t\tselectedChildIds = self._cascade_new_checked_state(childId, checkedState);\n\t\t\t\t\t\tselectedNodeIds = selectedNodeIds.concat(selectedChildIds);\n\t\t\t\t\t\tif (selectedChildIds.indexOf(childId) > -1) {\n\t\t\t\t\t\t\tselectedChildrenIds.push(childId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar dom = self.get_node(node, true);\n\n\t\t\t\t//A node's state is undetermined if some but not all of it's children are checked/selected .\n\t\t\t\tvar undetermined = selectedChildrenIds.length > 0 && selectedChildrenIds.length < node.children.length;\n\n\t\t\t\tif(node.original && node.original.state && node.original.state.undetermined) {\n\t\t\t\t\tnode.original.state.undetermined = undetermined;\n\t\t\t\t}\n\n\t\t\t\t//If a node is undetermined then remove selected class\n\t\t\t\tif (undetermined) {\n\t\t\t\t\tnode.state[ t ? 'selected' : 'checked' ] = false;\n\t\t\t\t\tdom.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t}\n\t\t\t\t//Otherwise, if the checkedState === true (i.e. the node is being checked now) and all of the node's children are checked (if it has any children),\n\t\t\t\t//check the node and style it correctly.\n\t\t\t\telse if (checkedState && selectedChildrenIds.length === node.children.length) {\n\t\t\t\t\tnode.state[ t ? 'selected' : 'checked' ] = checkedState;\n\t\t\t\t\tselectedNodeIds.push(node.id);\n\n\t\t\t\t\tdom.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnode.state[ t ? 'selected' : 'checked' ] = false;\n\t\t\t\t\tdom.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tselectedChildIds = this.get_checked_descendants(id);\n\n\t\t\t\tif (node.state[ t ? 'selected' : 'checked' ]) {\n\t\t\t\t\tselectedChildIds.push(node.id);\n\t\t\t\t}\n\n\t\t\t\tselectedNodeIds = selectedNodeIds.concat(selectedChildIds);\n\t\t\t}\n\n\t\t\treturn selectedNodeIds;\n\t\t};\n\n\t\t/**\n\t\t * Gets ids of nodes selected in branch (of tree) specified by id (does not include the node specified by id)\n\t\t * @name get_checked_descendants(obj)\n\t\t * @param {string} id the node ID\n\t\t * @return {Array} array of IDs\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.get_checked_descendants = function (id) {\n\t\t\tvar self = this;\n\t\t\tvar t = self.settings.checkbox.tie_selection;\n\t\t\tvar node = self._model.data[id];\n\n\t\t\treturn $.vakata.array_filter(node.children_d, function(_id) {\n\t\t\t\treturn self._model.data[_id].state[ t ? 'selected' : 'checked' ];\n\t\t\t});\n\t\t};\n\n\t\t/**\n\t\t * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally)\n\t\t * @name check_node(obj)\n\t\t * @param {mixed} obj an array can be used to check multiple nodes\n\t\t * @trigger check_node.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.check_node = function (obj, e) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); }\n\t\t\tvar dom, t1, t2, th;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.check_node(obj[t1], e);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(!obj.state.checked) {\n\t\t\t\tobj.state.checked = true;\n\t\t\t\tthis._data.checkbox.selected.push(obj.id);\n\t\t\t\tif(dom && dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').addClass('jstree-checked');\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is checked (only if tie_selection in checkbox settings is false)\n\t\t\t\t * @event\n\t\t\t\t * @name check_node.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @param {Array} selected the current selection\n\t\t\t\t * @param {Object} event the event (if any) that triggered this check_node\n\t\t\t\t * @plugin checkbox\n\t\t\t\t */\n\t\t\t\tthis.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });\n\t\t\t}\n\t\t};\n\t\t/**\n\t\t * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally)\n\t\t * @name uncheck_node(obj)\n\t\t * @param {mixed} obj an array can be used to uncheck multiple nodes\n\t\t * @trigger uncheck_node.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.uncheck_node = function (obj, e) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); }\n\t\t\tvar t1, t2, dom;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.uncheck_node(obj[t1], e);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdom = this.get_node(obj, true);\n\t\t\tif(obj.state.checked) {\n\t\t\t\tobj.state.checked = false;\n\t\t\t\tthis._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id);\n\t\t\t\tif(dom.length) {\n\t\t\t\t\tdom.children('.jstree-anchor').removeClass('jstree-checked');\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered when an node is unchecked (only if tie_selection in checkbox settings is false)\n\t\t\t\t * @event\n\t\t\t\t * @name uncheck_node.jstree\n\t\t\t\t * @param {Object} node\n\t\t\t\t * @param {Array} selected the current selection\n\t\t\t\t * @param {Object} event the event (if any) that triggered this uncheck_node\n\t\t\t\t * @plugin checkbox\n\t\t\t\t */\n\t\t\t\tthis.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });\n\t\t\t}\n\t\t};\n\t\t\n\t\t/**\n\t\t * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally)\n\t\t * @name check_all()\n\t\t * @trigger check_all.jstree, changed.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.check_all = function () {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.select_all(); }\n\t\t\tvar tmp = this._data.checkbox.selected.concat([]), i, j;\n\t\t\tthis._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat();\n\t\t\tfor(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {\n\t\t\t\tif(this._model.data[this._data.checkbox.selected[i]]) {\n\t\t\t\t\tthis._model.data[this._data.checkbox.selected[i]].state.checked = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.redraw(true);\n\t\t\t/**\n\t\t\t * triggered when all nodes are checked (only if tie_selection in checkbox settings is false)\n\t\t\t * @event\n\t\t\t * @name check_all.jstree\n\t\t\t * @param {Array} selected the current selection\n\t\t\t * @plugin checkbox\n\t\t\t */\n\t\t\tthis.trigger('check_all', { 'selected' : this._data.checkbox.selected });\n\t\t};\n\t\t/**\n\t\t * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally)\n\t\t * @name uncheck_all()\n\t\t * @trigger uncheck_all.jstree\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.uncheck_all = function () {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.deselect_all(); }\n\t\t\tvar tmp = this._data.checkbox.selected.concat([]), i, j;\n\t\t\tfor(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {\n\t\t\t\tif(this._model.data[this._data.checkbox.selected[i]]) {\n\t\t\t\t\tthis._model.data[this._data.checkbox.selected[i]].state.checked = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._data.checkbox.selected = [];\n\t\t\tthis.element.find('.jstree-checked').removeClass('jstree-checked');\n\t\t\t/**\n\t\t\t * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false)\n\t\t\t * @event\n\t\t\t * @name uncheck_all.jstree\n\t\t\t * @param {Object} node the previous selection\n\t\t\t * @param {Array} selected the current selection\n\t\t\t * @plugin checkbox\n\t\t\t */\n\t\t\tthis.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp });\n\t\t};\n\t\t/**\n\t\t * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected)\n\t\t * @name is_checked(obj)\n\t\t * @param {mixed} obj\n\t\t * @return {Boolean}\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.is_checked = function (obj) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\treturn obj.state.checked;\n\t\t};\n\t\t/**\n\t\t * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected)\n\t\t * @name get_checked([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.get_checked = function (full) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.get_selected(full); }\n\t\t\treturn full ? $.map(this._data.checkbox.selected, function (i) { return this.get_node(i); }.bind(this)) : this._data.checkbox.selected.slice();\n\t\t};\n\t\t/**\n\t\t * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected)\n\t\t * @name get_top_checked([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.get_top_checked = function (full) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); }\n\t\t\tvar tmp = this.get_checked(true),\n\t\t\t\tobj = {}, i, j, k, l;\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tobj[tmp[i].id] = tmp[i];\n\t\t\t}\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tfor(k = 0, l = tmp[i].children_d.length; k < l; k++) {\n\t\t\t\t\tif(obj[tmp[i].children_d[k]]) {\n\t\t\t\t\t\tdelete obj[tmp[i].children_d[k]];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp = [];\n\t\t\tfor(i in obj) {\n\t\t\t\tif(obj.hasOwnProperty(i)) {\n\t\t\t\t\ttmp.push(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn full ? $.map(tmp, function (i) { return this.get_node(i); }.bind(this)) : tmp;\n\t\t};\n\t\t/**\n\t\t * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected)\n\t\t * @name get_bottom_checked([full])\n\t\t * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned\n\t\t * @return {Array}\n\t\t * @plugin checkbox\n\t\t */\n\t\tthis.get_bottom_checked = function (full) {\n\t\t\tif(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); }\n\t\t\tvar tmp = this.get_checked(true),\n\t\t\t\tobj = [], i, j;\n\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\tif(!tmp[i].children.length) {\n\t\t\t\t\tobj.push(tmp[i].id);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn full ? $.map(obj, function (i) { return this.get_node(i); }.bind(this)) : obj;\n\t\t};\n\t\tthis.load_node = function (obj, callback) {\n\t\t\tvar k, l, i, j, c, tmp;\n\t\t\tif(!$.vakata.is_array(obj) && !this.settings.checkbox.tie_selection) {\n\t\t\t\ttmp = this.get_node(obj);\n\t\t\t\tif(tmp && tmp.state.loaded) {\n\t\t\t\t\tfor(k = 0, l = tmp.children_d.length; k < l; k++) {\n\t\t\t\t\t\tif(this._model.data[tmp.children_d[k]].state.checked) {\n\t\t\t\t\t\t\tc = true;\n\t\t\t\t\t\t\tthis._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]);\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\treturn parent.load_node.apply(this, arguments);\n\t\t};\n\t\tthis.get_state = function () {\n\t\t\tvar state = parent.get_state.apply(this, arguments);\n\t\t\tif(this.settings.checkbox.tie_selection) { return state; }\n\t\t\tstate.checkbox = this._data.checkbox.selected.slice();\n\t\t\treturn state;\n\t\t};\n\t\tthis.set_state = function (state, callback) {\n\t\t\tvar res = parent.set_state.apply(this, arguments);\n\t\t\tif(res && state.checkbox) {\n\t\t\t\tif(!this.settings.checkbox.tie_selection) {\n\t\t\t\t\tthis.uncheck_all();\n\t\t\t\t\tvar _this = this;\n\t\t\t\t\t$.each(state.checkbox, function (i, v) {\n\t\t\t\t\t\t_this.check_node(v);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tdelete state.checkbox;\n\t\t\t\tthis.set_state(state, callback);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn res;\n\t\t};\n\t\tthis.refresh = function (skip_loading, forget_state) {\n\t\t\tif(this.settings.checkbox.tie_selection) {\n\t\t\t\tthis._data.checkbox.selected = [];\n\t\t\t}\n\t\t\treturn parent.refresh.apply(this, arguments);\n\t\t};\n\t};\n\n\t// include the checkbox plugin by default\n\t// $.jstree.defaults.plugins.push(\"checkbox\");\n\n\n/**\n * ### Conditionalselect plugin\n *\n * This plugin allows defining a callback to allow or deny node selection by user input (activate node method).\n */\n\n\t/**\n\t * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`.\n\t * @name $.jstree.defaults.checkbox.visible\n\t * @plugin checkbox\n\t */\n\t$.jstree.defaults.conditionalselect = function () { return true; };\n\t$.jstree.plugins.conditionalselect = function (options, parent) {\n\t\t// own function\n\t\tthis.activate_node = function (obj, e) {\n\t\t\tif(this.settings.conditionalselect.call(this, this.get_node(obj), e)) {\n\t\t\t\treturn parent.activate_node.call(this, obj, e);\n\t\t\t}\n\t\t};\n\t};\n\n\n/**\n * ### Contextmenu plugin\n *\n * Shows a context menu when a node is right-clicked.\n */\n\n\t/**\n\t * stores all defaults for the contextmenu plugin\n\t * @name $.jstree.defaults.contextmenu\n\t * @plugin contextmenu\n\t */\n\t$.jstree.defaults.contextmenu = {\n\t\t/**\n\t\t * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`.\n\t\t * @name $.jstree.defaults.contextmenu.select_node\n\t\t * @plugin contextmenu\n\t\t */\n\t\tselect_node : true,\n\t\t/**\n\t\t * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used.\n\t\t * @name $.jstree.defaults.contextmenu.show_at_node\n\t\t * @plugin contextmenu\n\t\t */\n\t\tshow_at_node : true,\n\t\t/**\n\t\t * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too).\n\t\t *\n\t\t * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu.\n\t\t *\n\t\t * * `separator_before` - a boolean indicating if there should be a separator before this item\n\t\t * * `separator_after` - a boolean indicating if there should be a separator after this item\n\t\t * * `_disabled` - a boolean indicating if this action should be disabled\n\t\t * * `label` - a string - the name of the action (could be a function returning a string)\n\t\t * * `title` - a string - an optional tooltip for the item\n\t\t * * `action` - a function to be executed if this item is chosen, the function will receive \n\t\t * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class\n\t\t * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)\n\t\t * * `shortcut_label` - shortcut label (like for example `F2` for rename)\n\t\t * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered\n\t\t *\n\t\t * @name $.jstree.defaults.contextmenu.items\n\t\t * @plugin contextmenu\n\t\t */\n\t\titems : function (o, cb) { // Could be an object directly\n\t\t\treturn {\n\t\t\t\t\"create\" : {\n\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\"separator_after\"\t: true,\n\t\t\t\t\t\"_disabled\"\t\t\t: false, //(this.check(\"create_node\", data.reference, {}, \"last\")),\n\t\t\t\t\t\"label\"\t\t\t\t: \"Create\",\n\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\tinst.create_node(obj, {}, \"last\", function (new_node) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tinst.edit(new_node);\n\t\t\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t\t\tsetTimeout(function () { inst.edit(new_node); },0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"rename\" : {\n\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\"_disabled\"\t\t\t: false, //(this.check(\"rename_node\", data.reference, this.get_parent(data.reference), \"\")),\n\t\t\t\t\t\"label\"\t\t\t\t: \"Rename\",\n\t\t\t\t\t/*!\n\t\t\t\t\t\"shortcut\"\t\t\t: 113,\n\t\t\t\t\t\"shortcut_label\"\t: 'F2',\n\t\t\t\t\t\"icon\"\t\t\t\t: \"glyphicon glyphicon-leaf\",\n\t\t\t\t\t*/\n\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\tinst.edit(obj);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"remove\" : {\n\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\"icon\"\t\t\t\t: false,\n\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\"_disabled\"\t\t\t: false, //(this.check(\"delete_node\", data.reference, this.get_parent(data.reference), \"\")),\n\t\t\t\t\t\"label\"\t\t\t\t: \"Delete\",\n\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\tif(inst.is_selected(obj)) {\n\t\t\t\t\t\t\tinst.delete_node(inst.get_selected());\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tinst.delete_node(obj);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"ccp\" : {\n\t\t\t\t\t\"separator_before\"\t: true,\n\t\t\t\t\t\"icon\"\t\t\t\t: false,\n\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\"label\"\t\t\t\t: \"Edit\",\n\t\t\t\t\t\"action\"\t\t\t: false,\n\t\t\t\t\t\"submenu\" : {\n\t\t\t\t\t\t\"cut\" : {\n\t\t\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\t\t\"label\"\t\t\t\t: \"Cut\",\n\t\t\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\t\t\tif(inst.is_selected(obj)) {\n\t\t\t\t\t\t\t\t\tinst.cut(inst.get_top_selected());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinst.cut(obj);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"copy\" : {\n\t\t\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\t\t\"icon\"\t\t\t\t: false,\n\t\t\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\t\t\"label\"\t\t\t\t: \"Copy\",\n\t\t\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\t\t\tif(inst.is_selected(obj)) {\n\t\t\t\t\t\t\t\t\tinst.copy(inst.get_top_selected());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tinst.copy(obj);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"paste\" : {\n\t\t\t\t\t\t\t\"separator_before\"\t: false,\n\t\t\t\t\t\t\t\"icon\"\t\t\t\t: false,\n\t\t\t\t\t\t\t\"_disabled\"\t\t\t: function (data) {\n\t\t\t\t\t\t\t\treturn !$.jstree.reference(data.reference).can_paste();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"separator_after\"\t: false,\n\t\t\t\t\t\t\t\"label\"\t\t\t\t: \"Paste\",\n\t\t\t\t\t\t\t\"action\"\t\t\t: function (data) {\n\t\t\t\t\t\t\t\tvar inst = $.jstree.reference(data.reference),\n\t\t\t\t\t\t\t\t\tobj = inst.get_node(data.reference);\n\t\t\t\t\t\t\t\tinst.paste(obj);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\n\t$.jstree.plugins.contextmenu = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\n\t\t\tvar last_ts = 0, cto = null, ex, ey;\n\t\t\tthis.element\n\t\t\t\t.on(\"init.jstree loading.jstree ready.jstree\", function () {\n\t\t\t\t\t\tthis.get_container_ul().addClass('jstree-contextmenu');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"contextmenu.jstree\", \".jstree-anchor\", function (e, data) {\n\t\t\t\t\t\tif (e.target.tagName.toLowerCase() === 'input') {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tlast_ts = e.ctrlKey ? +new Date() : 0;\n\t\t\t\t\t\tif(data || cto) {\n\t\t\t\t\t\t\tlast_ts = (+new Date()) + 10000;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(cto) {\n\t\t\t\t\t\t\tclearTimeout(cto);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!this.is_loading(e.currentTarget)) {\n\t\t\t\t\t\t\tthis.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"click.jstree\", \".jstree-anchor\", function (e) {\n\t\t\t\t\t\tif(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click\n\t\t\t\t\t\t\t$.vakata.context.hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlast_ts = 0;\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"touchstart.jstree\", \".jstree-anchor\", function (e) {\n\t\t\t\t\t\tif(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tex = e.originalEvent.changedTouches[0].clientX;\n\t\t\t\t\t\tey = e.originalEvent.changedTouches[0].clientY;\n\t\t\t\t\t\tcto = setTimeout(function () {\n\t\t\t\t\t\t\t$(e.currentTarget).trigger('contextmenu', true);\n\t\t\t\t\t\t}, 750);\n\t\t\t\t\t})\n\t\t\t\t.on('touchmove.vakata.jstree', function (e) {\n\t\t\t\t\t\tif(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 10 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 10)) {\n\t\t\t\t\t\t\tclearTimeout(cto);\n\t\t\t\t\t\t\t$.vakata.context.hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t.on('touchend.vakata.jstree', function (e) {\n\t\t\t\t\t\tif(cto) {\n\t\t\t\t\t\t\tclearTimeout(cto);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t/*!\n\t\t\tif(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) {\n\t\t\t\tvar el = null, tm = null;\n\t\t\t\tthis.element\n\t\t\t\t\t.on(\"touchstart\", \".jstree-anchor\", function (e) {\n\t\t\t\t\t\tel = e.currentTarget;\n\t\t\t\t\t\ttm = +new Date();\n\t\t\t\t\t\t$(document).one(\"touchend\", function (e) {\n\t\t\t\t\t\t\te.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset);\n\t\t\t\t\t\t\te.currentTarget = e.target;\n\t\t\t\t\t\t\ttm = ((+(new Date())) - tm);\n\t\t\t\t\t\t\tif(e.target === el && tm > 600 && tm < 1000) {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t$(el).trigger('contextmenu', e);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tel = null;\n\t\t\t\t\t\t\ttm = null;\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t}\n\t\t\t*/\n\t\t\t$(document).on(\"context_hide.vakata.jstree\", function (e, data) {\n\t\t\t\tthis._data.contextmenu.visible = false;\n\t\t\t\t$(data.reference).removeClass('jstree-context');\n\t\t\t}.bind(this));\n\t\t};\n\t\tthis.teardown = function () {\n\t\t\tif(this._data.contextmenu.visible) {\n\t\t\t\t$.vakata.context.hide();\n\t\t\t}\n\t\t\t$(document).off(\"context_hide.vakata.jstree\");\n\t\t\tparent.teardown.call(this);\n\t\t};\n\n\t\t/**\n\t\t * prepare and show the context menu for a node\n\t\t * @name show_contextmenu(obj [, x, y])\n\t\t * @param {mixed} obj the node\n\t\t * @param {Number} x the x-coordinate relative to the document to show the menu at\n\t\t * @param {Number} y the y-coordinate relative to the document to show the menu at\n\t\t * @param {Object} e the event if available that triggered the contextmenu\n\t\t * @plugin contextmenu\n\t\t * @trigger show_contextmenu.jstree\n\t\t */\n\t\tthis.show_contextmenu = function (obj, x, y, e) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj || obj.id === $.jstree.root) { return false; }\n\t\t\tvar s = this.settings.contextmenu,\n\t\t\t\td = this.get_node(obj, true),\n\t\t\t\ta = d.children(\".jstree-anchor\"),\n\t\t\t\to = false,\n\t\t\t\ti = false;\n\t\t\tif(s.show_at_node || x === undefined || y === undefined) {\n\t\t\t\to = a.offset();\n\t\t\t\tx = o.left;\n\t\t\t\ty = o.top + this._data.core.li_height;\n\t\t\t}\n\t\t\tif(this.settings.contextmenu.select_node && !this.is_selected(obj)) {\n\t\t\t\tthis.activate_node(obj, e);\n\t\t\t}\n\n\t\t\ti = s.items;\n\t\t\tif($.vakata.is_function(i)) {\n\t\t\t\ti = i.call(this, obj, function (i) {\n\t\t\t\t\tthis._show_contextmenu(obj, x, y, i);\n\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t\tif($.isPlainObject(i)) {\n\t\t\t\tthis._show_contextmenu(obj, x, y, i);\n\t\t\t}\n\t\t};\n\t\t/**\n\t\t * show the prepared context menu for a node\n\t\t * @name _show_contextmenu(obj, x, y, i)\n\t\t * @param {mixed} obj the node\n\t\t * @param {Number} x the x-coordinate relative to the document to show the menu at\n\t\t * @param {Number} y the y-coordinate relative to the document to show the menu at\n\t\t * @param {Number} i the object of items to show\n\t\t * @plugin contextmenu\n\t\t * @trigger show_contextmenu.jstree\n\t\t * @private\n\t\t */\n\t\tthis._show_contextmenu = function (obj, x, y, i) {\n\t\t\tvar d = this.get_node(obj, true),\n\t\t\t\ta = d.children(\".jstree-anchor\");\n\t\t\t$(document).one(\"context_show.vakata.jstree\", function (e, data) {\n\t\t\t\tvar cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';\n\t\t\t\t$(data.element).addClass(cls);\n\t\t\t\ta.addClass('jstree-context');\n\t\t\t}.bind(this));\n\t\t\tthis._data.contextmenu.visible = true;\n\t\t\t$.vakata.context.show(a, { 'x' : x, 'y' : y }, i);\n\t\t\t/**\n\t\t\t * triggered when the contextmenu is shown for a node\n\t\t\t * @event\n\t\t\t * @name show_contextmenu.jstree\n\t\t\t * @param {Object} node the node\n\t\t\t * @param {Number} x the x-coordinate of the menu relative to the document\n\t\t\t * @param {Number} y the y-coordinate of the menu relative to the document\n\t\t\t * @plugin contextmenu\n\t\t\t */\n\t\t\tthis.trigger('show_contextmenu', { \"node\" : obj, \"x\" : x, \"y\" : y });\n\t\t};\n\t};\n\n\t// contextmenu helper\n\t(function ($) {\n\t\tvar right_to_left = false,\n\t\t\tvakata_context = {\n\t\t\t\telement\t\t: false,\n\t\t\t\treference\t: false,\n\t\t\t\tposition_x\t: 0,\n\t\t\t\tposition_y\t: 0,\n\t\t\t\titems\t\t: [],\n\t\t\t\thtml\t\t: \"\",\n\t\t\t\tis_visible\t: false\n\t\t\t};\n\n\t\t$.vakata.context = {\n\t\t\tsettings : {\n\t\t\t\thide_onmouseleave\t: 0,\n\t\t\t\ticons\t\t\t\t: true\n\t\t\t},\n\t\t\t_trigger : function (event_name) {\n\t\t\t\t$(document).triggerHandler(\"context_\" + event_name + \".vakata\", {\n\t\t\t\t\t\"reference\"\t: vakata_context.reference,\n\t\t\t\t\t\"element\"\t: vakata_context.element,\n\t\t\t\t\t\"position\"\t: {\n\t\t\t\t\t\t\"x\" : vakata_context.position_x,\n\t\t\t\t\t\t\"y\" : vakata_context.position_y\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\t_execute : function (i) {\n\t\t\t\ti = vakata_context.items[i];\n\t\t\t\treturn i && (!i._disabled || ($.vakata.is_function(i._disabled) && !i._disabled({ \"item\" : i, \"reference\" : vakata_context.reference, \"element\" : vakata_context.element }))) && i.action ? i.action.call(null, {\n\t\t\t\t\t\t\t\"item\"\t\t: i,\n\t\t\t\t\t\t\t\"reference\"\t: vakata_context.reference,\n\t\t\t\t\t\t\t\"element\"\t: vakata_context.element,\n\t\t\t\t\t\t\t\"position\"\t: {\n\t\t\t\t\t\t\t\t\"x\" : vakata_context.position_x,\n\t\t\t\t\t\t\t\t\"y\" : vakata_context.position_y\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}) : false;\n\t\t\t},\n\t\t\t_parse : function (o, is_callback) {\n\t\t\t\tif(!o) { return false; }\n\t\t\t\tif(!is_callback) {\n\t\t\t\t\tvakata_context.html\t\t= \"\";\n\t\t\t\t\tvakata_context.items\t= [];\n\t\t\t\t}\n\t\t\t\tvar str = \"\",\n\t\t\t\t\tsep = false,\n\t\t\t\t\ttmp;\n\n\t\t\t\tif(is_callback) { str += \"<\"+\"ul>\"; }\n\t\t\t\t$.each(o, function (i, val) {\n\t\t\t\t\tif(!val) { return true; }\n\t\t\t\t\tvakata_context.items.push(val);\n\t\t\t\t\tif(!sep && val.separator_before) {\n\t\t\t\t\t\tstr += \"<\"+\"li class='vakata-context-separator'><\"+\"a href='#' \" + ($.vakata.context.settings.icons ? '' : 'class=\"vakata-context-no-icons\"') + \"> <\"+\"/a><\"+\"/li>\";\n\t\t\t\t\t}\n\t\t\t\t\tsep = false;\n\t\t\t\t\tstr += \"<\"+\"li class='\" + (val._class || \"\") + (val._disabled === true || ($.vakata.is_function(val._disabled) && val._disabled({ \"item\" : val, \"reference\" : vakata_context.reference, \"element\" : vakata_context.element })) ? \" vakata-contextmenu-disabled \" : \"\") + \"' \"+(val.shortcut?\" data-shortcut='\"+val.shortcut+\"' \":'')+\">\";\n\t\t\t\t\tstr += \"<\"+\"a href='#' rel='\" + (vakata_context.items.length - 1) + \"' \" + (val.title ? \"title='\" + val.title + \"'\" : \"\") + \">\";\n\t\t\t\t\tif($.vakata.context.settings.icons) {\n\t\t\t\t\t\tstr += \"<\"+\"i \";\n\t\t\t\t\t\tif(val.icon) {\n\t\t\t\t\t\t\tif(val.icon.indexOf(\"/\") !== -1 || val.icon.indexOf(\".\") !== -1) { str += \" style='background:url(\\\"\" + val.icon + \"\\\") center center no-repeat' \"; }\n\t\t\t\t\t\t\telse { str += \" class='\" + val.icon + \"' \"; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstr += \"><\"+\"/i><\"+\"span class='vakata-contextmenu-sep'> <\"+\"/span>\";\n\t\t\t\t\t}\n\t\t\t\t\tstr += ($.vakata.is_function(val.label) ? val.label({ \"item\" : i, \"reference\" : vakata_context.reference, \"element\" : vakata_context.element }) : val.label) + (val.shortcut?' '+ (val.shortcut_label || '') +'':'') + \"<\"+\"/a>\";\n\t\t\t\t\tif(val.submenu) {\n\t\t\t\t\t\ttmp = $.vakata.context._parse(val.submenu, true);\n\t\t\t\t\t\tif(tmp) { str += tmp; }\n\t\t\t\t\t}\n\t\t\t\t\tstr += \"<\"+\"/li>\";\n\t\t\t\t\tif(val.separator_after) {\n\t\t\t\t\t\tstr += \"<\"+\"li class='vakata-context-separator'><\"+\"a href='#' \" + ($.vakata.context.settings.icons ? '' : 'class=\"vakata-context-no-icons\"') + \"> <\"+\"/a><\"+\"/li>\";\n\t\t\t\t\t\tsep = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tstr = str.replace(/
      • <\\/li\\>$/,\"\");\n\t\t\t\tif(is_callback) { str += \"\"; }\n\t\t\t\t/**\n\t\t\t\t * triggered on the document when the contextmenu is parsed (HTML is built)\n\t\t\t\t * @event\n\t\t\t\t * @plugin contextmenu\n\t\t\t\t * @name context_parse.vakata\n\t\t\t\t * @param {jQuery} reference the element that was right clicked\n\t\t\t\t * @param {jQuery} element the DOM element of the menu itself\n\t\t\t\t * @param {Object} position the x & y coordinates of the menu\n\t\t\t\t */\n\t\t\t\tif(!is_callback) { vakata_context.html = str; $.vakata.context._trigger(\"parse\"); }\n\t\t\t\treturn str.length > 10 ? str : false;\n\t\t\t},\n\t\t\t_show_submenu : function (o) {\n\t\t\t\to = $(o);\n\t\t\t\tif(!o.length || !o.children(\"ul\").length) { return; }\n\t\t\t\tvar e = o.children(\"ul\"),\n\t\t\t\t\txl = o.offset().left,\n\t\t\t\t\tx = xl + o.outerWidth(),\n\t\t\t\t\ty = o.offset().top,\n\t\t\t\t\tw = e.width(),\n\t\t\t\t\th = e.height(),\n\t\t\t\t\tdw = $(window).width() + $(window).scrollLeft(),\n\t\t\t\t\tdh = $(window).height() + $(window).scrollTop();\n\t\t\t\t// може да се спести е една проверка - дали няма някой от класовете вече нагоре\n\t\t\t\tif(right_to_left) {\n\t\t\t\t\to[x - (w + 10 + o.outerWidth()) < 0 ? \"addClass\" : \"removeClass\"](\"vakata-context-left\");\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to[x + w > dw && xl > dw - x ? \"addClass\" : \"removeClass\"](\"vakata-context-right\");\n\t\t\t\t}\n\t\t\t\tif(y + h + 10 > dh) {\n\t\t\t\t\te.css(\"bottom\",\"-1px\");\n\t\t\t\t}\n\n\t\t\t\t//if does not fit - stick it to the side\n\t\t\t\tif (o.hasClass('vakata-context-right')) {\n\t\t\t\t\tif (xl < w) {\n\t\t\t\t\t\te.css(\"margin-right\", xl - w);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (dw - x < w) {\n\t\t\t\t\t\te.css(\"margin-left\", dw - x - w);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\te.show();\n\t\t\t},\n\t\t\tshow : function (reference, position, data) {\n\t\t\t\tvar o, e, x, y, w, h, dw, dh, cond = true;\n\t\t\t\tif(vakata_context.element && vakata_context.element.length) {\n\t\t\t\t\tvakata_context.element.width('');\n\t\t\t\t}\n\t\t\t\tswitch(cond) {\n\t\t\t\t\tcase (!position && !reference):\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase (!!position && !!reference):\n\t\t\t\t\t\tvakata_context.reference\t= reference;\n\t\t\t\t\t\tvakata_context.position_x\t= position.x;\n\t\t\t\t\t\tvakata_context.position_y\t= position.y;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase (!position && !!reference):\n\t\t\t\t\t\tvakata_context.reference\t= reference;\n\t\t\t\t\t\to = reference.offset();\n\t\t\t\t\t\tvakata_context.position_x\t= o.left + reference.outerHeight();\n\t\t\t\t\t\tvakata_context.position_y\t= o.top;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase (!!position && !reference):\n\t\t\t\t\t\tvakata_context.position_x\t= position.x;\n\t\t\t\t\t\tvakata_context.position_y\t= position.y;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(!!reference && !data && $(reference).data('vakata_contextmenu')) {\n\t\t\t\t\tdata = $(reference).data('vakata_contextmenu');\n\t\t\t\t}\n\t\t\t\tif($.vakata.context._parse(data)) {\n\t\t\t\t\tvakata_context.element.html(vakata_context.html);\n\t\t\t\t}\n\t\t\t\tif(vakata_context.items.length) {\n\t\t\t\t\tvakata_context.element.appendTo(document.body);\n\t\t\t\t\te = vakata_context.element;\n\t\t\t\t\tx = vakata_context.position_x;\n\t\t\t\t\ty = vakata_context.position_y;\n\t\t\t\t\tw = e.width();\n\t\t\t\t\th = e.height();\n\t\t\t\t\tdw = $(window).width() + $(window).scrollLeft();\n\t\t\t\t\tdh = $(window).height() + $(window).scrollTop();\n\t\t\t\t\tif(right_to_left) {\n\t\t\t\t\t\tx -= (e.outerWidth() - $(reference).outerWidth());\n\t\t\t\t\t\tif(x < $(window).scrollLeft() + 20) {\n\t\t\t\t\t\t\tx = $(window).scrollLeft() + 20;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(x + w + 20 > dw) {\n\t\t\t\t\t\tx = dw - (w + 20);\n\t\t\t\t\t}\n\t\t\t\t\tif(y + h + 20 > dh) {\n\t\t\t\t\t\ty = dh - (h + 20);\n\t\t\t\t\t}\n\n\t\t\t\t\tvakata_context.element\n\t\t\t\t\t\t.css({ \"left\" : x, \"top\" : y })\n\t\t\t\t\t\t.show()\n\t\t\t\t\t\t.find('a').first().trigger('focus').parent().addClass(\"vakata-context-hover\");\n\t\t\t\t\tvakata_context.is_visible = true;\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered on the document when the contextmenu is shown\n\t\t\t\t\t * @event\n\t\t\t\t\t * @plugin contextmenu\n\t\t\t\t\t * @name context_show.vakata\n\t\t\t\t\t * @param {jQuery} reference the element that was right clicked\n\t\t\t\t\t * @param {jQuery} element the DOM element of the menu itself\n\t\t\t\t\t * @param {Object} position the x & y coordinates of the menu\n\t\t\t\t\t */\n\t\t\t\t\t$.vakata.context._trigger(\"show\");\n\t\t\t\t}\n\t\t\t},\n\t\t\thide : function () {\n\t\t\t\tif(vakata_context.is_visible) {\n\t\t\t\t\tvakata_context.element.hide().find(\"ul\").hide().end().find(':focus').trigger('blur').end().detach();\n\t\t\t\t\tvakata_context.is_visible = false;\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered on the document when the contextmenu is hidden\n\t\t\t\t\t * @event\n\t\t\t\t\t * @plugin contextmenu\n\t\t\t\t\t * @name context_hide.vakata\n\t\t\t\t\t * @param {jQuery} reference the element that was right clicked\n\t\t\t\t\t * @param {jQuery} element the DOM element of the menu itself\n\t\t\t\t\t * @param {Object} position the x & y coordinates of the menu\n\t\t\t\t\t */\n\t\t\t\t\t$.vakata.context._trigger(\"hide\");\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\t$(function () {\n\t\t\tright_to_left = $(document.body).css(\"direction\") === \"rtl\";\n\t\t\tvar to = false;\n\n\t\t\tvakata_context.element = $(\"
          \");\n\t\t\tvakata_context.element\n\t\t\t\t.on(\"mouseenter\", \"li\", function (e) {\n\t\t\t\t\te.stopImmediatePropagation();\n\n\t\t\t\t\tif($.contains(this, e.relatedTarget)) {\n\t\t\t\t\t\t// премахнато заради delegate mouseleave по-долу\n\t\t\t\t\t\t// $(this).find(\".vakata-context-hover\").removeClass(\"vakata-context-hover\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(to) { clearTimeout(to); }\n\t\t\t\t\tvakata_context.element.find(\".vakata-context-hover\").removeClass(\"vakata-context-hover\").end();\n\n\t\t\t\t\t$(this)\n\t\t\t\t\t\t.siblings().find(\"ul\").hide().end().end()\n\t\t\t\t\t\t.parentsUntil(\".vakata-context\", \"li\").addBack().addClass(\"vakata-context-hover\");\n\t\t\t\t\t$.vakata.context._show_submenu(this);\n\t\t\t\t})\n\t\t\t\t// тестово - дали не натоварва?\n\t\t\t\t.on(\"mouseleave\", \"li\", function (e) {\n\t\t\t\t\tif($.contains(this, e.relatedTarget)) { return; }\n\t\t\t\t\t$(this).find(\".vakata-context-hover\").addBack().removeClass(\"vakata-context-hover\");\n\t\t\t\t})\n\t\t\t\t.on(\"mouseleave\", function (e) {\n\t\t\t\t\t$(this).find(\".vakata-context-hover\").removeClass(\"vakata-context-hover\");\n\t\t\t\t\tif($.vakata.context.settings.hide_onmouseleave) {\n\t\t\t\t\t\tto = setTimeout(\n\t\t\t\t\t\t\t(function (t) {\n\t\t\t\t\t\t\t\treturn function () { $.vakata.context.hide(); };\n\t\t\t\t\t\t\t}(this)), $.vakata.context.settings.hide_onmouseleave);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.on(\"click\", \"a\", function (e) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t//})\n\t\t\t\t//.on(\"mouseup\", \"a\", function (e) {\n\t\t\t\t\tif(!$(this).trigger('blur').parent().hasClass(\"vakata-context-disabled\") && $.vakata.context._execute($(this).attr(\"rel\")) !== false) {\n\t\t\t\t\t\t$.vakata.context.hide();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.on('keydown', 'a', function (e) {\n\t\t\t\t\t\tvar o = null;\n\t\t\t\t\t\tswitch(e.which) {\n\t\t\t\t\t\t\tcase 13:\n\t\t\t\t\t\t\tcase 32:\n\t\t\t\t\t\t\t\te.type = \"click\";\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t$(e.currentTarget).trigger(e);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 37:\n\t\t\t\t\t\t\t\tif(vakata_context.is_visible) {\n\t\t\t\t\t\t\t\t\tvakata_context.element.find(\".vakata-context-hover\").last().closest(\"li\").first().find(\"ul\").hide().find(\".vakata-context-hover\").removeClass(\"vakata-context-hover\").end().end().children('a').trigger('focus');\n\t\t\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 38:\n\t\t\t\t\t\t\t\tif(vakata_context.is_visible) {\n\t\t\t\t\t\t\t\t\to = vakata_context.element.find(\"ul:visible\").addBack().last().children(\".vakata-context-hover\").removeClass(\"vakata-context-hover\").prevAll(\"li:not(.vakata-context-separator)\").first();\n\t\t\t\t\t\t\t\t\tif(!o.length) { o = vakata_context.element.find(\"ul:visible\").addBack().last().children(\"li:not(.vakata-context-separator)\").last(); }\n\t\t\t\t\t\t\t\t\to.addClass(\"vakata-context-hover\").children('a').trigger('focus');\n\t\t\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 39:\n\t\t\t\t\t\t\t\tif(vakata_context.is_visible) {\n\t\t\t\t\t\t\t\t\tvakata_context.element.find(\".vakata-context-hover\").last().children(\"ul\").show().children(\"li:not(.vakata-context-separator)\").removeClass(\"vakata-context-hover\").first().addClass(\"vakata-context-hover\").children('a').trigger('focus');\n\t\t\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 40:\n\t\t\t\t\t\t\t\tif(vakata_context.is_visible) {\n\t\t\t\t\t\t\t\t\to = vakata_context.element.find(\"ul:visible\").addBack().last().children(\".vakata-context-hover\").removeClass(\"vakata-context-hover\").nextAll(\"li:not(.vakata-context-separator)\").first();\n\t\t\t\t\t\t\t\t\tif(!o.length) { o = vakata_context.element.find(\"ul:visible\").addBack().last().children(\"li:not(.vakata-context-separator)\").first(); }\n\t\t\t\t\t\t\t\t\to.addClass(\"vakata-context-hover\").children('a').trigger('focus');\n\t\t\t\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 27:\n\t\t\t\t\t\t\t\t$.vakata.context.hide();\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t//console.log(e.which);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t.on('keydown', function (e) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tvar a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent();\n\t\t\t\t\tif(a.parent().not('.vakata-context-disabled')) {\n\t\t\t\t\t\ta.trigger('click');\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t$(document)\n\t\t\t\t.on(\"mousedown.vakata.jstree\", function (e) {\n\t\t\t\t\tif(vakata_context.is_visible && vakata_context.element[0] !== e.target && !$.contains(vakata_context.element[0], e.target)) {\n\t\t\t\t\t\t$.vakata.context.hide();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.on(\"context_show.vakata.jstree\", function (e, data) {\n\t\t\t\t\tvakata_context.element.find(\"li:has(ul)\").children(\"a\").addClass(\"vakata-context-parent\");\n\t\t\t\t\tif(right_to_left) {\n\t\t\t\t\t\tvakata_context.element.addClass(\"vakata-context-rtl\").css(\"direction\", \"rtl\");\n\t\t\t\t\t}\n\t\t\t\t\t// also apply a RTL class?\n\t\t\t\t\tvakata_context.element.find(\"ul\").hide().end();\n\t\t\t\t});\n\t\t});\n\t}($));\n\t// $.jstree.defaults.plugins.push(\"contextmenu\");\n\n\n/**\n * ### Drag'n'drop plugin\n *\n * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations.\n */\n\n\t/**\n\t * stores all defaults for the drag'n'drop plugin\n\t * @name $.jstree.defaults.dnd\n\t * @plugin dnd\n\t */\n\t$.jstree.defaults.dnd = {\n\t\t/**\n\t\t * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`.\n\t\t * @name $.jstree.defaults.dnd.copy\n\t\t * @plugin dnd\n\t\t */\n\t\tcopy : true,\n\t\t/**\n\t\t * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`.\n\t\t * @name $.jstree.defaults.dnd.open_timeout\n\t\t * @plugin dnd\n\t\t */\n\t\topen_timeout : 500,\n\t\t/**\n\t\t * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging\n\t\t * @name $.jstree.defaults.dnd.is_draggable\n\t\t * @plugin dnd\n\t\t */\n\t\tis_draggable : true,\n\t\t/**\n\t\t * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true`\n\t\t * @name $.jstree.defaults.dnd.check_while_dragging\n\t\t * @plugin dnd\n\t\t */\n\t\tcheck_while_dragging : true,\n\t\t/**\n\t\t * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false`\n\t\t * @name $.jstree.defaults.dnd.always_copy\n\t\t * @plugin dnd\n\t\t */\n\t\talways_copy : false,\n\t\t/**\n\t\t * when dropping a node \"inside\", this setting indicates the position the node should go to - it can be an integer or a string: \"first\" (same as 0) or \"last\", default is `0`\n\t\t * @name $.jstree.defaults.dnd.inside_pos\n\t\t * @plugin dnd\n\t\t */\n\t\tinside_pos : 0,\n\t\t/**\n\t\t * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node\n\t\t * @name $.jstree.defaults.dnd.drag_selection\n\t\t * @plugin dnd\n\t\t */\n\t\tdrag_selection : true,\n\t\t/**\n\t\t * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string \"selected\" which means only selected nodes can be dragged on touch devices.\n\t\t * @name $.jstree.defaults.dnd.touch\n\t\t * @plugin dnd\n\t\t */\n\t\ttouch : true,\n\t\t/**\n\t\t * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target.\n\t\t * @name $.jstree.defaults.dnd.large_drop_target\n\t\t * @plugin dnd\n\t\t */\n\t\tlarge_drop_target : false,\n\t\t/**\n\t\t * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to \"selected\".\n\t\t * @name $.jstree.defaults.dnd.large_drag_target\n\t\t * @plugin dnd\n\t\t */\n\t\tlarge_drag_target : false,\n\t\t/**\n\t\t * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls.\n\t\t * @reference http://caniuse.com/#feat=dragndrop\n\t\t * @name $.jstree.defaults.dnd.use_html5\n\t\t * @plugin dnd\n\t\t */\n\t\tuse_html5: false,\n\t\t/**\n\t\t * controls whether items can be dropped anywhere on the tree.\n\t\t * @name $.jstree.defaults.dnd.blank_space_drop\n\t\t * @plugin dnd\n\t\t */\n\t\tblank_space_drop: false\n\t};\n\tvar drg, elm;\n\t// TODO: now check works by checking for each node individually, how about max_children, unique, etc?\n\t$.jstree.plugins.dnd = function (options, parent) {\n\t\tthis.init = function (el, options) {\n\t\t\tparent.init.call(this, el, options);\n\t\t\tthis.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span'));\n\t\t};\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\n\t\t\tthis.element\n\t\t\t\t.on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', function (e) {\n\t\t\t\t\t\tif(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(e.type === \"touchstart\" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar obj = this.get_node(e.target),\n\t\t\t\t\t\t\tmlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1,\n\t\t\t\t\t\t\ttxt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));\n\t\t\t\t\t\tif(this.settings.core.force_text) {\n\t\t\t\t\t\t\ttxt = $.vakata.html.escape(txt);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === \"touchstart\" || e.type === \"dragstart\") &&\n\t\t\t\t\t\t\t(this.settings.dnd.is_draggable === true || ($.vakata.is_function(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e)))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tdrg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] };\n\t\t\t\t\t\t\telm = e.currentTarget;\n\t\t\t\t\t\t\tif (this.settings.dnd.use_html5) {\n\t\t\t\t\t\t\t\t$.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.element.trigger('mousedown.jstree');\n\t\t\t\t\t\t\t\treturn $.vakata.dnd.start(e, drg, '
          ' + txt + '+
          ');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this));\n\t\t\tif (this.settings.dnd.use_html5) {\n\t\t\t\tthis.element\n\t\t\t\t\t.on('dragover.jstree', function (e) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t$.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t})\n\t\t\t\t\t//.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) {\n\t\t\t\t\t//\t\te.preventDefault();\n\t\t\t\t\t//\t\t$.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t\t//\t\treturn false;\n\t\t\t\t\t//\t}, this))\n\t\t\t\t\t.on('drop.jstree', function (e) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t$.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t};\n\t\tthis.redraw_node = function(obj, deep, callback, force_render) {\n\t\t\tobj = parent.redraw_node.apply(this, arguments);\n\t\t\tif (obj && this.settings.dnd.use_html5) {\n\t\t\t\tif (this.settings.dnd.large_drag_target) {\n\t\t\t\t\tobj.setAttribute('draggable', true);\n\t\t\t\t} else {\n\t\t\t\t\tvar i, j, tmp = null;\n\t\t\t\t\tfor(i = 0, j = obj.childNodes.length; i < j; i++) {\n\t\t\t\t\t\tif(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf(\"jstree-anchor\") !== -1) {\n\t\t\t\t\t\t\ttmp = obj.childNodes[i];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(tmp) {\n\t\t\t\t\t\ttmp.setAttribute('draggable', true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn obj;\n\t\t};\n\t};\n\n\t$(function() {\n\t\t// bind only once for all instances\n\t\tvar lastmv = false,\n\t\t\tlaster = false,\n\t\t\tlastev = false,\n\t\t\topento = false,\n\t\t\tmarker = $('
           
          ').hide(); //.appendTo('body');\n\n\t\t$(document)\n\t\t\t.on('dragover.vakata.jstree', function (e) {\n\t\t\t\tif (elm) {\n\t\t\t\t\t$.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('drop.vakata.jstree', function (e) {\n\t\t\t\tif (elm) {\n\t\t\t\t\t$.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg });\n\t\t\t\t\telm = null;\n\t\t\t\t\tdrg = null;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.on('dnd_start.vakata.jstree', function (e, data) {\n\t\t\t\tlastmv = false;\n\t\t\t\tlastev = false;\n\t\t\t\tif(!data || !data.data || !data.data.jstree) { return; }\n\t\t\t\tmarker.appendTo(document.body); //.show();\n\t\t\t})\n\t\t\t.on('dnd_move.vakata.jstree', function (e, data) {\n\t\t\t\tvar isDifferentNode = data.event.target !== lastev.target;\n\t\t\t\tif(opento) {\n\t\t\t\t\tif (!data.event || data.event.type !== 'dragover' || isDifferentNode) {\n\t\t\t\t\t\tclearTimeout(opento);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(!data || !data.data || !data.data.jstree) { return; }\n\n\t\t\t\t// if we are hovering the marker image do nothing (can happen on \"inside\" drags)\n\t\t\t\tif(data.event.target.id && data.event.target.id === 'jstree-marker') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastev = data.event;\n\n\t\t\t\tvar ins = $.jstree.reference(data.event.target),\n\t\t\t\t\tref = false,\n\t\t\t\t\toff = false,\n\t\t\t\t\trel = false,\n\t\t\t\t\ttmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn, c;\n\t\t\t\t// if we are over an instance\n\t\t\t\tif(ins && ins._data && ins._data.dnd) {\n\t\t\t\t\tmarker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ));\n\t\t\t\t\tis_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)));\n\t\t\t\t\tdata.helper\n\t\t\t\t\t\t.children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ))\n\t\t\t\t\t\t.find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ]();\n\n\t\t\t\t\t// if are hovering the container itself add a new root node\n\t\t\t\t\t//console.log(data.event);\n\t\t\t\t\tif( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && (ins.get_container_ul().children().length === 0 || ins.settings.dnd.blank_space_drop)) {\n\t\t\t\t\t\tok = true;\n\t\t\t\t\t\tfor(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {\n\t\t\t\t\t\t\tok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? \"copy_node\" : \"move_node\"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) });\n\t\t\t\t\t\t\tif(!ok) { break; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(ok) {\n\t\t\t\t\t\t\tlastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' };\n\t\t\t\t\t\t\tmarker.hide();\n\t\t\t\t\t\t\tdata.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');\n\t\t\t\t\t\t\tif (data.event.originalEvent && data.event.originalEvent.dataTransfer) {\n\t\t\t\t\t\t\t\tdata.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// if we are hovering a tree node\n\t\t\t\t\t\tref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor');\n\t\t\t\t\t\t\n\t\t\t\t\t\tif(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {\n\t\t\t\t\t\t\toff = ref.offset();\n\t\t\t\t\t\t\trel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top;\n\t\t\t\t\t\t\th = ref.outerHeight();\n\t\t\t\t\t\t\tif(rel < h / 3) {\n\t\t\t\t\t\t\t\to = ['b', 'i', 'a'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if(rel > h - h / 3) {\n\t\t\t\t\t\t\t\to = ['a', 'i', 'b'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\to = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$.each(o, function (j, v) {\n\t\t\t\t\t\t\t\tswitch(v) {\n\t\t\t\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\t\t\t\t\tl = off.left - 6;\n\t\t\t\t\t\t\t\t\t\tt = off.top;\n\t\t\t\t\t\t\t\t\t\tp = ins.get_parent(ref);\n\t\t\t\t\t\t\t\t\t\ti = ref.parent().index();\n\t\t\t\t\t\t\t\t\t\tc = 'jstree-below';\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'i':\n\t\t\t\t\t\t\t\t\t\tip = ins.settings.dnd.inside_pos;\n\t\t\t\t\t\t\t\t\t\ttm = ins.get_node(ref.parent());\n\t\t\t\t\t\t\t\t\t\tl = off.left - 2;\n\t\t\t\t\t\t\t\t\t\tt = off.top + h / 2 + 1;\n\t\t\t\t\t\t\t\t\t\tp = tm.id;\n\t\t\t\t\t\t\t\t\t\ti = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length));\n\t\t\t\t\t\t\t\t\t\tc = 'jstree-inside';\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'a':\n\t\t\t\t\t\t\t\t\t\tl = off.left - 6;\n\t\t\t\t\t\t\t\t\t\tt = off.top + h;\n\t\t\t\t\t\t\t\t\t\tp = ins.get_parent(ref);\n\t\t\t\t\t\t\t\t\t\ti = ref.parent().index() + 1;\n\t\t\t\t\t\t\t\t\t\tc = 'jstree-above';\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tok = true;\n\t\t\t\t\t\t\t\tfor(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {\n\t\t\t\t\t\t\t\t\top = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? \"copy_node\" : \"move_node\";\n\t\t\t\t\t\t\t\t\tps = i;\n\t\t\t\t\t\t\t\t\tif(op === \"move_node\" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) {\n\t\t\t\t\t\t\t\t\t\tpr = ins.get_node(p);\n\t\t\t\t\t\t\t\t\t\tif(ps > $.inArray(data.data.nodes[t1], pr.children)) {\n\t\t\t\t\t\t\t\t\t\t\tps -= 1;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) );\n\t\t\t\t\t\t\t\t\tif(!ok) {\n\t\t\t\t\t\t\t\t\t\tif(ins && ins.last_error) { laster = ins.last_error(); }\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) {\n\t\t\t\t\t\t\t\t\tif (!data.event || data.event.type !== 'dragover' || isDifferentNode) {\n\t\t\t\t\t\t\t\t\t\tif (opento) { clearTimeout(opento); }\n\t\t\t\t\t\t\t\t\t\topento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(ok) {\n\t\t\t\t\t\t\t\t\tpn = ins.get_node(p, true);\n\t\t\t\t\t\t\t\t\tif (!pn.hasClass('.jstree-dnd-parent')) {\n\t\t\t\t\t\t\t\t\t\t$('.jstree-dnd-parent').removeClass('jstree-dnd-parent');\n\t\t\t\t\t\t\t\t\t\tpn.addClass('jstree-dnd-parent');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tlastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i };\n\t\t\t\t\t\t\t\t\tmarker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();\n\t\t\t\t\t\t\t\t\tmarker.removeClass('jstree-above jstree-inside jstree-below').addClass(c);\n\t\t\t\t\t\t\t\t\tdata.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');\n\t\t\t\t\t\t\t\t\tif (data.event.originalEvent && data.event.originalEvent.dataTransfer) {\n\t\t\t\t\t\t\t\t\t\tdata.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tlaster = {};\n\t\t\t\t\t\t\t\t\to = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif(o === true) { return; }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$('.jstree-dnd-parent').removeClass('jstree-dnd-parent');\n\t\t\t\tlastmv = false;\n\t\t\t\tdata.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');\n\t\t\t\tif (data.event.originalEvent && data.event.originalEvent.dataTransfer) {\n\t\t\t\t\t//data.event.originalEvent.dataTransfer.dropEffect = 'none';\n\t\t\t\t}\n\t\t\t\tmarker.hide();\n\t\t\t})\n\t\t\t.on('dnd_scroll.vakata.jstree', function (e, data) {\n\t\t\t\tif(!data || !data.data || !data.data.jstree) { return; }\n\t\t\t\tmarker.hide();\n\t\t\t\tlastmv = false;\n\t\t\t\tlastev = false;\n\t\t\t\tdata.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');\n\t\t\t})\n\t\t\t.on('dnd_stop.vakata.jstree', function (e, data) {\n\t\t\t\t$('.jstree-dnd-parent').removeClass('jstree-dnd-parent');\n\t\t\t\tif(opento) { clearTimeout(opento); }\n\t\t\t\tif(!data || !data.data || !data.data.jstree) { return; }\n\t\t\t\tmarker.hide().detach();\n\t\t\t\tvar i, j, nodes = [];\n\t\t\t\tif(lastmv) {\n\t\t\t\t\tfor(i = 0, j = data.data.nodes.length; i < j; i++) {\n\t\t\t\t\t\tnodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i];\n\t\t\t\t\t}\n\t\t\t\t\tlastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ti = $(data.event.target).closest('.jstree');\n\t\t\t\t\tif(i.length && laster && laster.error && laster.error === 'check') {\n\t\t\t\t\t\ti = i.jstree(true);\n\t\t\t\t\t\tif(i) {\n\t\t\t\t\t\t\ti.settings.core.error.call(this, laster);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastev = false;\n\t\t\t\tlastmv = false;\n\t\t\t})\n\t\t\t.on('keyup.jstree keydown.jstree', function (e, data) {\n\t\t\t\tdata = $.vakata.dnd._get();\n\t\t\t\tif(data && data.data && data.data.jstree) {\n\t\t\t\t\tif (e.type === \"keyup\" && e.which === 27) {\n\t\t\t\t\t\tif (opento) { clearTimeout(opento); }\n\t\t\t\t\t\tlastmv = false;\n\t\t\t\t\t\tlaster = false;\n\t\t\t\t\t\tlastev = false;\n\t\t\t\t\t\topento = false;\n\t\t\t\t\t\tmarker.hide().detach();\n\t\t\t\t\t\t$.vakata.dnd._clean();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdata.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ]();\n\t\t\t\t\t\tif(lastev) {\n\t\t\t\t\t\t\tlastev.metaKey = e.metaKey;\n\t\t\t\t\t\t\tlastev.ctrlKey = e.ctrlKey;\n\t\t\t\t\t\t\t$.vakata.dnd._trigger('move', lastev);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t});\n\n\t// helpers\n\t(function ($) {\n\t\t$.vakata.html = {\n\t\t\tdiv : $('
          '),\n\t\t\tescape : function (str) {\n\t\t\t\treturn $.vakata.html.div.text(str).html();\n\t\t\t},\n\t\t\tstrip : function (str) {\n\t\t\t\treturn $.vakata.html.div.empty().append($.parseHTML(str)).text();\n\t\t\t}\n\t\t};\n\t\t// private variable\n\t\tvar vakata_dnd = {\n\t\t\telement\t: false,\n\t\t\ttarget\t: false,\n\t\t\tis_down\t: false,\n\t\t\tis_drag\t: false,\n\t\t\thelper\t: false,\n\t\t\thelper_w: 0,\n\t\t\tdata\t: false,\n\t\t\tinit_x\t: 0,\n\t\t\tinit_y\t: 0,\n\t\t\tscroll_l: 0,\n\t\t\tscroll_t: 0,\n\t\t\tscroll_e: false,\n\t\t\tscroll_i: false,\n\t\t\tis_touch: false\n\t\t};\n\t\t$.vakata.dnd = {\n\t\t\tsettings : {\n\t\t\t\tscroll_speed\t\t: 10,\n\t\t\t\tscroll_proximity\t: 20,\n\t\t\t\thelper_left\t\t\t: 5,\n\t\t\t\thelper_top\t\t\t: 10,\n\t\t\t\tthreshold\t\t\t: 5,\n\t\t\t\tthreshold_touch\t\t: 10\n\t\t\t},\n\t\t\t_trigger : function (event_name, e, data) {\n\t\t\t\tif (data === undefined) {\n\t\t\t\t\tdata = $.vakata.dnd._get();\n\t\t\t\t}\n\t\t\t\tdata.event = e;\n\t\t\t\t$(document).triggerHandler(\"dnd_\" + event_name + \".vakata\", data);\n\t\t\t},\n\t\t\t_get : function () {\n\t\t\t\treturn {\n\t\t\t\t\t\"data\"\t\t: vakata_dnd.data,\n\t\t\t\t\t\"element\"\t: vakata_dnd.element,\n\t\t\t\t\t\"helper\"\t: vakata_dnd.helper\n\t\t\t\t};\n\t\t\t},\n\t\t\t_clean : function () {\n\t\t\t\tif(vakata_dnd.helper) { vakata_dnd.helper.remove(); }\n\t\t\t\tif(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }\n\t\t\t\tvakata_dnd = {\n\t\t\t\t\telement\t: false,\n\t\t\t\t\ttarget\t: false,\n\t\t\t\t\tis_down\t: false,\n\t\t\t\t\tis_drag\t: false,\n\t\t\t\t\thelper\t: false,\n\t\t\t\t\thelper_w: 0,\n\t\t\t\t\tdata\t: false,\n\t\t\t\t\tinit_x\t: 0,\n\t\t\t\t\tinit_y\t: 0,\n\t\t\t\t\tscroll_l: 0,\n\t\t\t\t\tscroll_t: 0,\n\t\t\t\t\tscroll_e: false,\n\t\t\t\t\tscroll_i: false,\n\t\t\t\t\tis_touch: false\n\t\t\t\t};\n\t\t\t\telm = null;\n\t\t\t\t$(document).off(\"mousemove.vakata.jstree touchmove.vakata.jstree\", $.vakata.dnd.drag);\n\t\t\t\t$(document).off(\"mouseup.vakata.jstree touchend.vakata.jstree\", $.vakata.dnd.stop);\n\t\t\t},\n\t\t\t_scroll : function (init_only) {\n\t\t\t\tif(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) {\n\t\t\t\t\tif(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif(!vakata_dnd.scroll_i) {\n\t\t\t\t\tvakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif(init_only === true) { return false; }\n\n\t\t\t\tvar i = vakata_dnd.scroll_e.scrollTop(),\n\t\t\t\t\tj = vakata_dnd.scroll_e.scrollLeft();\n\t\t\t\tvakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed);\n\t\t\t\tvakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed);\n\t\t\t\tif(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) {\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered on the document when a drag causes an element to scroll\n\t\t\t\t\t * @event\n\t\t\t\t\t * @plugin dnd\n\t\t\t\t\t * @name dnd_scroll.vakata\n\t\t\t\t\t * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start\n\t\t\t\t\t * @param {DOM} element the DOM element being dragged\n\t\t\t\t\t * @param {jQuery} helper the helper shown next to the mouse\n\t\t\t\t\t * @param {jQuery} event the element that is scrolling\n\t\t\t\t\t */\n\t\t\t\t\t$.vakata.dnd._trigger(\"scroll\", vakata_dnd.scroll_e);\n\t\t\t\t}\n\t\t\t},\n\t\t\tstart : function (e, data, html) {\n\t\t\t\tif(e.type === \"touchstart\" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {\n\t\t\t\t\te.pageX = e.originalEvent.changedTouches[0].pageX;\n\t\t\t\t\te.pageY = e.originalEvent.changedTouches[0].pageY;\n\t\t\t\t\te.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);\n\t\t\t\t}\n\t\t\t\tif(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); }\n\t\t\t\ttry {\n\t\t\t\t\te.currentTarget.unselectable = \"on\";\n\t\t\t\t\te.currentTarget.onselectstart = function() { return false; };\n\t\t\t\t\tif(e.currentTarget.style) {\n\t\t\t\t\t\te.currentTarget.style.touchAction = \"none\";\n\t\t\t\t\t\te.currentTarget.style.msTouchAction = \"none\";\n\t\t\t\t\t\te.currentTarget.style.MozUserSelect = \"none\";\n\t\t\t\t\t}\n\t\t\t\t} catch(ignore) { }\n\t\t\t\tvakata_dnd.init_x\t= e.pageX;\n\t\t\t\tvakata_dnd.init_y\t= e.pageY;\n\t\t\t\tvakata_dnd.data\t\t= data;\n\t\t\t\tvakata_dnd.is_down\t= true;\n\t\t\t\tvakata_dnd.element\t= e.currentTarget;\n\t\t\t\tvakata_dnd.target\t= e.target;\n\t\t\t\tvakata_dnd.is_touch\t= e.type === \"touchstart\";\n\t\t\t\tif(html !== false) {\n\t\t\t\t\tvakata_dnd.helper = $(\"
          \").html(html).css({\n\t\t\t\t\t\t\"display\"\t\t: \"block\",\n\t\t\t\t\t\t\"margin\"\t\t: \"0\",\n\t\t\t\t\t\t\"padding\"\t\t: \"0\",\n\t\t\t\t\t\t\"position\"\t\t: \"absolute\",\n\t\t\t\t\t\t\"top\"\t\t\t: \"-2000px\",\n\t\t\t\t\t\t\"lineHeight\"\t: \"16px\",\n\t\t\t\t\t\t\"zIndex\"\t\t: \"10000\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t$(document).on(\"mousemove.vakata.jstree touchmove.vakata.jstree\", $.vakata.dnd.drag);\n\t\t\t\t$(document).on(\"mouseup.vakata.jstree touchend.vakata.jstree\", $.vakata.dnd.stop);\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tdrag : function (e) {\n\t\t\t\tif(e.type === \"touchmove\" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {\n\t\t\t\t\te.pageX = e.originalEvent.changedTouches[0].pageX;\n\t\t\t\t\te.pageY = e.originalEvent.changedTouches[0].pageY;\n\t\t\t\t\te.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);\n\t\t\t\t}\n\t\t\t\tif(!vakata_dnd.is_down) { return; }\n\t\t\t\tif(!vakata_dnd.is_drag) {\n\t\t\t\t\tif(\n\t\t\t\t\t\tMath.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) ||\n\t\t\t\t\t\tMath.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif(vakata_dnd.helper) {\n\t\t\t\t\t\t\tvakata_dnd.helper.appendTo(document.body);\n\t\t\t\t\t\t\tvakata_dnd.helper_w = vakata_dnd.helper.outerWidth();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvakata_dnd.is_drag = true;\n\t\t\t\t\t\t$(vakata_dnd.target).one('click.vakata', false);\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * triggered on the document when a drag starts\n\t\t\t\t\t\t * @event\n\t\t\t\t\t\t * @plugin dnd\n\t\t\t\t\t\t * @name dnd_start.vakata\n\t\t\t\t\t\t * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start\n\t\t\t\t\t\t * @param {DOM} element the DOM element being dragged\n\t\t\t\t\t\t * @param {jQuery} helper the helper shown next to the mouse\n\t\t\t\t\t\t * @param {Object} event the event that caused the start (probably mousemove)\n\t\t\t\t\t\t */\n\t\t\t\t\t\t$.vakata.dnd._trigger(\"start\", e);\n\t\t\t\t\t}\n\t\t\t\t\telse { return; }\n\t\t\t\t}\n\n\t\t\t\tvar d = false, w = false,\n\t\t\t\t\tdh = false, wh = false,\n\t\t\t\t\tdw = false, ww = false,\n\t\t\t\t\tdt = false, dl = false,\n\t\t\t\t\tht = false, hl = false;\n\n\t\t\t\tvakata_dnd.scroll_t = 0;\n\t\t\t\tvakata_dnd.scroll_l = 0;\n\t\t\t\tvakata_dnd.scroll_e = false;\n\t\t\t\t$($(e.target).parentsUntil(\"body\").addBack().get().reverse())\n\t\t\t\t\t.filter(function () {\n\t\t\t\t\t\treturn\tthis.ownerDocument && (/^auto|scroll$/).test($(this).css(\"overflow\")) &&\n\t\t\t\t\t\t\t\t(this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);\n\t\t\t\t\t})\n\t\t\t\t\t.each(function () {\n\t\t\t\t\t\tvar t = $(this), o = t.offset();\n\t\t\t\t\t\tif(this.scrollHeight > this.offsetHeight) {\n\t\t\t\t\t\t\tif(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity)\t{ vakata_dnd.scroll_t = 1; }\n\t\t\t\t\t\t\tif(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity)\t\t\t\t{ vakata_dnd.scroll_t = -1; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.scrollWidth > this.offsetWidth) {\n\t\t\t\t\t\t\tif(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity)\t{ vakata_dnd.scroll_l = 1; }\n\t\t\t\t\t\t\tif(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity)\t\t\t\t{ vakata_dnd.scroll_l = -1; }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {\n\t\t\t\t\t\t\tvakata_dnd.scroll_e = $(this);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\tif(!vakata_dnd.scroll_e) {\n\t\t\t\t\td = $(document); w = $(window);\n\t\t\t\t\tdh = d.height(); wh = w.height();\n\t\t\t\t\tdw = d.width(); ww = w.width();\n\t\t\t\t\tdt = d.scrollTop(); dl = d.scrollLeft();\n\t\t\t\t\tif(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity)\t\t{ vakata_dnd.scroll_t = -1; }\n\t\t\t\t\tif(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity)\t{ vakata_dnd.scroll_t = 1; }\n\t\t\t\t\tif(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity)\t\t{ vakata_dnd.scroll_l = -1; }\n\t\t\t\t\tif(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity)\t{ vakata_dnd.scroll_l = 1; }\n\t\t\t\t\tif(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {\n\t\t\t\t\t\tvakata_dnd.scroll_e = d;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); }\n\n\t\t\t\tif(vakata_dnd.helper) {\n\t\t\t\t\tht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10);\n\t\t\t\t\thl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10);\n\t\t\t\t\tif(dh && ht + 25 > dh) { ht = dh - 50; }\n\t\t\t\t\tif(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); }\n\t\t\t\t\tvakata_dnd.helper.css({\n\t\t\t\t\t\tleft\t: hl + \"px\",\n\t\t\t\t\t\ttop\t\t: ht + \"px\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * triggered on the document when a drag is in progress\n\t\t\t\t * @event\n\t\t\t\t * @plugin dnd\n\t\t\t\t * @name dnd_move.vakata\n\t\t\t\t * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start\n\t\t\t\t * @param {DOM} element the DOM element being dragged\n\t\t\t\t * @param {jQuery} helper the helper shown next to the mouse\n\t\t\t\t * @param {Object} event the event that caused this to trigger (most likely mousemove)\n\t\t\t\t */\n\t\t\t\t$.vakata.dnd._trigger(\"move\", e);\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tstop : function (e) {\n\t\t\t\tif(e.type === \"touchend\" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {\n\t\t\t\t\te.pageX = e.originalEvent.changedTouches[0].pageX;\n\t\t\t\t\te.pageY = e.originalEvent.changedTouches[0].pageY;\n\t\t\t\t\te.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);\n\t\t\t\t}\n\t\t\t\tif(vakata_dnd.is_drag) {\n\t\t\t\t\t/**\n\t\t\t\t\t * triggered on the document when a drag stops (the dragged element is dropped)\n\t\t\t\t\t * @event\n\t\t\t\t\t * @plugin dnd\n\t\t\t\t\t * @name dnd_stop.vakata\n\t\t\t\t\t * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start\n\t\t\t\t\t * @param {DOM} element the DOM element being dragged\n\t\t\t\t\t * @param {jQuery} helper the helper shown next to the mouse\n\t\t\t\t\t * @param {Object} event the event that caused the stop\n\t\t\t\t\t */\n\t\t\t\t\tif (e.target !== vakata_dnd.target) {\n\t\t\t\t\t\t$(vakata_dnd.target).off('click.vakata');\n\t\t\t\t\t}\n\t\t\t\t\t$.vakata.dnd._trigger(\"stop\", e);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif(e.type === \"touchend\" && e.target === vakata_dnd.target) {\n\t\t\t\t\t\tvar to = setTimeout(function () { $(e.target).trigger('click'); }, 100);\n\t\t\t\t\t\t$(e.target).one('click', function() { if(to) { clearTimeout(to); } });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$.vakata.dnd._clean();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\t}($));\n\n\t// include the dnd plugin by default\n\t// $.jstree.defaults.plugins.push(\"dnd\");\n\n\n/**\n * ### Massload plugin\n *\n * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading).\n */\n\n\t/**\n\t * massload configuration\n\t *\n\t * It is possible to set this to a standard jQuery-like AJAX config.\n\t * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used.\n\t *\n\t * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result.\n\t *\n\t * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array.\n\t *\n\t *\t{\n\t *\t\t\"id1\" : [{ \"text\" : \"Child of ID1\", \"id\" : \"c1\" }, { \"text\" : \"Another child of ID1\", \"id\" : \"c2\" }],\n\t *\t\t\"id2\" : [{ \"text\" : \"Child of ID2\", \"id\" : \"c3\" }]\n\t *\t}\n\t * \n\t * @name $.jstree.defaults.massload\n\t * @plugin massload\n\t */\n\t$.jstree.defaults.massload = null;\n\t$.jstree.plugins.massload = function (options, parent) {\n\t\tthis.init = function (el, options) {\n\t\t\tthis._data.massload = {};\n\t\t\tparent.init.call(this, el, options);\n\t\t};\n\t\tthis._load_nodes = function (nodes, callback, is_callback, force_reload) {\n\t\t\tvar s = this.settings.massload,\t\t\t\t\n\t\t\t\ttoLoad = [],\n\t\t\t\tm = this._model.data,\n\t\t\t\ti, j, dom;\n\t\t\tif (!is_callback) {\n\t\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\t\tif(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) {\n\t\t\t\t\t\ttoLoad.push(nodes[i]);\n\t\t\t\t\t\tdom = this.get_node(nodes[i], true);\n\t\t\t\t\t\tif (dom && dom.length) {\n\t\t\t\t\t\t\tdom.addClass(\"jstree-loading\").attr('aria-busy',true);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._data.massload = {};\n\t\t\t\tif (toLoad.length) {\n\t\t\t\t\tif($.vakata.is_function(s)) {\n\t\t\t\t\t\treturn s.call(this, toLoad, function (data) {\n\t\t\t\t\t\t\tvar i, j;\n\t\t\t\t\t\t\tif(data) {\n\t\t\t\t\t\t\t\tfor(i in data) {\n\t\t\t\t\t\t\t\t\tif(data.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\tthis._data.massload[i] = data[i];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\t\t\t\t\tdom = this.get_node(nodes[i], true);\n\t\t\t\t\t\t\t\tif (dom && dom.length) {\n\t\t\t\t\t\t\t\t\tdom.removeClass(\"jstree-loading\").attr('aria-busy',false);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tparent._load_nodes.call(this, nodes, callback, is_callback, force_reload);\n\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t}\n\t\t\t\t\tif(typeof s === 'object' && s && s.url) {\n\t\t\t\t\t\ts = $.extend(true, {}, s);\n\t\t\t\t\t\tif($.vakata.is_function(s.url)) {\n\t\t\t\t\t\t\ts.url = s.url.call(this, toLoad);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif($.vakata.is_function(s.data)) {\n\t\t\t\t\t\t\ts.data = s.data.call(this, toLoad);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $.ajax(s)\n\t\t\t\t\t\t\t.done(function (data,t,x) {\n\t\t\t\t\t\t\t\t\tvar i, j;\n\t\t\t\t\t\t\t\t\tif(data) {\n\t\t\t\t\t\t\t\t\t\tfor(i in data) {\n\t\t\t\t\t\t\t\t\t\t\tif(data.hasOwnProperty(i)) {\n\t\t\t\t\t\t\t\t\t\t\t\tthis._data.massload[i] = data[i];\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tfor(i = 0, j = nodes.length; i < j; i++) {\n\t\t\t\t\t\t\t\t\t\tdom = this.get_node(nodes[i], true);\n\t\t\t\t\t\t\t\t\t\tif (dom && dom.length) {\n\t\t\t\t\t\t\t\t\t\t\tdom.removeClass(\"jstree-loading\").attr('aria-busy',false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparent._load_nodes.call(this, nodes, callback, is_callback, force_reload);\n\t\t\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t\t\t.fail(function (f) {\n\t\t\t\t\t\t\t\t\tparent._load_nodes.call(this, nodes, callback, is_callback, force_reload);\n\t\t\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn parent._load_nodes.call(this, nodes, callback, is_callback, force_reload);\n\t\t};\n\t\tthis._load_node = function (obj, callback) {\n\t\t\tvar data = this._data.massload[obj.id],\n\t\t\t\trslt = null, dom;\n\t\t\tif(data) {\n\t\t\t\trslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data'](\n\t\t\t\t\tobj,\n\t\t\t\t\ttypeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data,\n\t\t\t\t\tfunction (status) { callback.call(this, status); }\n\t\t\t\t);\n\t\t\t\tdom = this.get_node(obj.id, true);\n\t\t\t\tif (dom && dom.length) {\n\t\t\t\t\tdom.removeClass(\"jstree-loading\").attr('aria-busy',false);\n\t\t\t\t}\n\t\t\t\tdelete this._data.massload[obj.id];\n\t\t\t\treturn rslt;\n\t\t\t}\n\t\t\treturn parent._load_node.call(this, obj, callback);\n\t\t};\n\t};\n\n\n/**\n * ### Search plugin\n *\n * Adds search functionality to jsTree.\n */\n\n\t/**\n\t * stores all defaults for the search plugin\n\t * @name $.jstree.defaults.search\n\t * @plugin search\n\t */\n\t$.jstree.defaults.search = {\n\t\t/**\n\t\t * a jQuery-like AJAX config, which jstree uses if a server should be queried for results.\n\t\t *\n\t\t * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.\n\t\t * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to\n\t\t * @name $.jstree.defaults.search.ajax\n\t\t * @plugin search\n\t\t */\n\t\tajax : false,\n\t\t/**\n\t\t * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`.\n\t\t * @name $.jstree.defaults.search.fuzzy\n\t\t * @plugin search\n\t\t */\n\t\tfuzzy : false,\n\t\t/**\n\t\t * Indicates if the search should be case sensitive. Default is `false`.\n\t\t * @name $.jstree.defaults.search.case_sensitive\n\t\t * @plugin search\n\t\t */\n\t\tcase_sensitive : false,\n\t\t/**\n\t\t * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers).\n\t\t * This setting can be changed at runtime when calling the search method. Default is `false`.\n\t\t * @name $.jstree.defaults.search.show_only_matches\n\t\t * @plugin search\n\t\t */\n\t\tshow_only_matches : false,\n\t\t/**\n\t\t * Indicates if the children of matched element are shown (when show_only_matches is true)\n\t\t * This setting can be changed at runtime when calling the search method. Default is `false`.\n\t\t * @name $.jstree.defaults.search.show_only_matches_children\n\t\t * @plugin search\n\t\t */\n\t\tshow_only_matches_children : false,\n\t\t/**\n\t\t * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`.\n\t\t * @name $.jstree.defaults.search.close_opened_onclear\n\t\t * @plugin search\n\t\t */\n\t\tclose_opened_onclear : true,\n\t\t/**\n\t\t * Indicates if only leaf nodes should be included in search results. Default is `false`.\n\t\t * @name $.jstree.defaults.search.search_leaves_only\n\t\t * @plugin search\n\t\t */\n\t\tsearch_leaves_only : false,\n\t\t/**\n\t\t * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution).\n\t\t * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`.\n\t\t * @name $.jstree.defaults.search.search_callback\n\t\t * @plugin search\n\t\t */\n\t\tsearch_callback : false\n\t};\n\n\t$.jstree.plugins.search = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\n\t\t\tthis._data.search.str = \"\";\n\t\t\tthis._data.search.dom = $();\n\t\t\tthis._data.search.res = [];\n\t\t\tthis._data.search.opn = [];\n\t\t\tthis._data.search.som = false;\n\t\t\tthis._data.search.smc = false;\n\t\t\tthis._data.search.hdn = [];\n\n\t\t\tthis.element\n\t\t\t\t.on(\"search.jstree\", function (e, data) {\n\t\t\t\t\t\tif(this._data.search.som && data.res.length) {\n\t\t\t\t\t\t\tvar m = this._model.data, i, j, p = [], k, l;\n\t\t\t\t\t\t\tfor(i = 0, j = data.res.length; i < j; i++) {\n\t\t\t\t\t\t\t\tif(m[data.res[i]] && !m[data.res[i]].state.hidden) {\n\t\t\t\t\t\t\t\t\tp.push(data.res[i]);\n\t\t\t\t\t\t\t\t\tp = p.concat(m[data.res[i]].parents);\n\t\t\t\t\t\t\t\t\tif(this._data.search.smc) {\n\t\t\t\t\t\t\t\t\t\tfor (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) {\n\t\t\t\t\t\t\t\t\t\t\tif (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) {\n\t\t\t\t\t\t\t\t\t\t\t\tp.push(m[data.res[i]].children_d[k]);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root);\n\t\t\t\t\t\t\tthis._data.search.hdn = this.hide_all(true);\n\t\t\t\t\t\t\tthis.show_node(p, true);\n\t\t\t\t\t\t\tthis.redraw(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"clear_search.jstree\", function (e, data) {\n\t\t\t\t\t\tif(this._data.search.som && data.res.length) {\n\t\t\t\t\t\t\tthis.show_node(this._data.search.hdn, true);\n\t\t\t\t\t\t\tthis.redraw(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this));\n\t\t};\n\t\t/**\n\t\t * used to search the tree nodes for a given string\n\t\t * @name search(str [, skip_async])\n\t\t * @param {String} str the search string\n\t\t * @param {Boolean} skip_async if set to true server will not be queried even if configured\n\t\t * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers)\n\t\t * @param {mixed} inside an optional node to whose children to limit the search\n\t\t * @param {Boolean} append if set to true the results of this search are appended to the previous search\n\t\t * @plugin search\n\t\t * @trigger search.jstree\n\t\t */\n\t\tthis.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) {\n\t\t\tif(str === false || $.vakata.trim(str.toString()) === \"\") {\n\t\t\t\treturn this.clear_search();\n\t\t\t}\n\t\t\tinside = this.get_node(inside);\n\t\t\tinside = inside && inside.id ? inside.id : null;\n\t\t\tstr = str.toString();\n\t\t\tvar s = this.settings.search,\n\t\t\t\ta = s.ajax ? s.ajax : false,\n\t\t\t\tm = this._model.data,\n\t\t\t\tf = null,\n\t\t\t\tr = [],\n\t\t\t\tp = [], i, j;\n\t\t\tif(this._data.search.res.length && !append) {\n\t\t\t\tthis.clear_search();\n\t\t\t}\n\t\t\tif(show_only_matches === undefined) {\n\t\t\t\tshow_only_matches = s.show_only_matches;\n\t\t\t}\n\t\t\tif(show_only_matches_children === undefined) {\n\t\t\t\tshow_only_matches_children = s.show_only_matches_children;\n\t\t\t}\n\t\t\tif(!skip_async && a !== false) {\n\t\t\t\tif($.vakata.is_function(a)) {\n\t\t\t\t\treturn a.call(this, str, function (d) {\n\t\t\t\t\t\t\tif(d && d.d) { d = d.d; }\n\t\t\t\t\t\t\tthis._load_nodes(!$.vakata.is_array(d) ? [] : $.vakata.array_unique(d), function () {\n\t\t\t\t\t\t\t\tthis.search(str, true, show_only_matches, inside, append, show_only_matches_children);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}.bind(this), inside);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ta = $.extend({}, a);\n\t\t\t\t\tif(!a.data) { a.data = {}; }\n\t\t\t\t\ta.data.str = str;\n\t\t\t\t\tif(inside) {\n\t\t\t\t\t\ta.data.inside = inside;\n\t\t\t\t\t}\n\t\t\t\t\tif (this._data.search.lastRequest) {\n\t\t\t\t\t\tthis._data.search.lastRequest.abort();\n\t\t\t\t\t}\n\t\t\t\t\tthis._data.search.lastRequest = $.ajax(a)\n\t\t\t\t\t\t.fail(function () {\n\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };\n\t\t\t\t\t\t\tthis.settings.core.error.call(this, this._data.core.last_error);\n\t\t\t\t\t\t}.bind(this))\n\t\t\t\t\t\t.done(function (d) {\n\t\t\t\t\t\t\tif(d && d.d) { d = d.d; }\n\t\t\t\t\t\t\tthis._load_nodes(!$.vakata.is_array(d) ? [] : $.vakata.array_unique(d), function () {\n\t\t\t\t\t\t\t\tthis.search(str, true, show_only_matches, inside, append, show_only_matches_children);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}.bind(this));\n\t\t\t\t\treturn this._data.search.lastRequest;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!append) {\n\t\t\t\tthis._data.search.str = str;\n\t\t\t\tthis._data.search.dom = $();\n\t\t\t\tthis._data.search.res = [];\n\t\t\t\tthis._data.search.opn = [];\n\t\t\t\tthis._data.search.som = show_only_matches;\n\t\t\t\tthis._data.search.smc = show_only_matches_children;\n\t\t\t}\n\n\t\t\tf = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });\n\t\t\t$.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) {\n\t\t\t\tvar v = m[i];\n\t\t\t\tif(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) {\n\t\t\t\t\tr.push(i);\n\t\t\t\t\tp = p.concat(v.parents);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(r.length) {\n\t\t\t\tp = $.vakata.array_unique(p);\n\t\t\t\tfor(i = 0, j = p.length; i < j; i++) {\n\t\t\t\t\tif(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) {\n\t\t\t\t\t\tthis._data.search.opn.push(p[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(!append) {\n\t\t\t\t\tthis._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return \"0123456789\".indexOf(v[0]) !== -1 ? '\\\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\\\$&') : v.replace($.jstree.idregex,'\\\\$&'); }).join(', #')));\n\t\t\t\t\tthis._data.search.res = r;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return \"0123456789\".indexOf(v[0]) !== -1 ? '\\\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\\\$&') : v.replace($.jstree.idregex,'\\\\$&'); }).join(', #'))));\n\t\t\t\t\tthis._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r));\n\t\t\t\t}\n\t\t\t\tthis._data.search.dom.children(\".jstree-anchor\").addClass('jstree-search');\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered after search is complete\n\t\t\t * @event\n\t\t\t * @name search.jstree\n\t\t\t * @param {jQuery} nodes a jQuery collection of matching nodes\n\t\t\t * @param {String} str the search string\n\t\t\t * @param {Array} res a collection of objects represeing the matching nodes\n\t\t\t * @plugin search\n\t\t\t */\n\t\t\tthis.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches });\n\t\t};\n\t\t/**\n\t\t * used to clear the last search (removes classes and shows all nodes if filtering is on)\n\t\t * @name clear_search()\n\t\t * @plugin search\n\t\t * @trigger clear_search.jstree\n\t\t */\n\t\tthis.clear_search = function () {\n\t\t\tif(this.settings.search.close_opened_onclear) {\n\t\t\t\tthis.close_node(this._data.search.opn, 0);\n\t\t\t}\n\t\t\t/**\n\t\t\t * triggered after search is complete\n\t\t\t * @event\n\t\t\t * @name clear_search.jstree\n\t\t\t * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search)\n\t\t\t * @param {String} str the search string (the last search string)\n\t\t\t * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search)\n\t\t\t * @plugin search\n\t\t\t */\n\t\t\tthis.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });\n\t\t\tif(this._data.search.res.length) {\n\t\t\t\tthis._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) {\n\t\t\t\t\treturn \"0123456789\".indexOf(v[0]) !== -1 ? '\\\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\\\$&') : v.replace($.jstree.idregex,'\\\\$&');\n\t\t\t\t}).join(', #')));\n\t\t\t\tthis._data.search.dom.children(\".jstree-anchor\").removeClass(\"jstree-search\");\n\t\t\t}\n\t\t\tthis._data.search.str = \"\";\n\t\t\tthis._data.search.res = [];\n\t\t\tthis._data.search.opn = [];\n\t\t\tthis._data.search.dom = $();\n\t\t};\n\n\t\tthis.redraw_node = function(obj, deep, callback, force_render) {\n\t\t\tobj = parent.redraw_node.apply(this, arguments);\n\t\t\tif(obj) {\n\t\t\t\tif($.inArray(obj.id, this._data.search.res) !== -1) {\n\t\t\t\t\tvar i, j, tmp = null;\n\t\t\t\t\tfor(i = 0, j = obj.childNodes.length; i < j; i++) {\n\t\t\t\t\t\tif(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf(\"jstree-anchor\") !== -1) {\n\t\t\t\t\t\t\ttmp = obj.childNodes[i];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(tmp) {\n\t\t\t\t\t\ttmp.className += ' jstree-search';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn obj;\n\t\t};\n\t};\n\n\t// helpers\n\t(function ($) {\n\t\t// from http://kiro.me/projects/fuse.html\n\t\t$.vakata.search = function(pattern, txt, options) {\n\t\t\toptions = options || {};\n\t\t\toptions = $.extend({}, $.vakata.search.defaults, options);\n\t\t\tif(options.fuzzy !== false) {\n\t\t\t\toptions.fuzzy = true;\n\t\t\t}\n\t\t\tpattern = options.caseSensitive ? pattern : pattern.toLowerCase();\n\t\t\tvar MATCH_LOCATION\t= options.location,\n\t\t\t\tMATCH_DISTANCE\t= options.distance,\n\t\t\t\tMATCH_THRESHOLD\t= options.threshold,\n\t\t\t\tpatternLen = pattern.length,\n\t\t\t\tmatchmask, pattern_alphabet, match_bitapScore, search;\n\t\t\tif(patternLen > 32) {\n\t\t\t\toptions.fuzzy = false;\n\t\t\t}\n\t\t\tif(options.fuzzy) {\n\t\t\t\tmatchmask = 1 << (patternLen - 1);\n\t\t\t\tpattern_alphabet = (function () {\n\t\t\t\t\tvar mask = {},\n\t\t\t\t\t\ti = 0;\n\t\t\t\t\tfor (i = 0; i < patternLen; i++) {\n\t\t\t\t\t\tmask[pattern.charAt(i)] = 0;\n\t\t\t\t\t}\n\t\t\t\t\tfor (i = 0; i < patternLen; i++) {\n\t\t\t\t\t\tmask[pattern.charAt(i)] |= 1 << (patternLen - i - 1);\n\t\t\t\t\t}\n\t\t\t\t\treturn mask;\n\t\t\t\t}());\n\t\t\t\tmatch_bitapScore = function (e, x) {\n\t\t\t\t\tvar accuracy = e / patternLen,\n\t\t\t\t\t\tproximity = Math.abs(MATCH_LOCATION - x);\n\t\t\t\t\tif(!MATCH_DISTANCE) {\n\t\t\t\t\t\treturn proximity ? 1.0 : accuracy;\n\t\t\t\t\t}\n\t\t\t\t\treturn accuracy + (proximity / MATCH_DISTANCE);\n\t\t\t\t};\n\t\t\t}\n\t\t\tsearch = function (text) {\n\t\t\t\ttext = options.caseSensitive ? text.toString() : text.toString().toLowerCase();\n\t\t\t\tif(pattern === text || text.indexOf(pattern) !== -1) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisMatch: true,\n\t\t\t\t\t\tscore: 0\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif(!options.fuzzy) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisMatch: false,\n\t\t\t\t\t\tscore: 1\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tvar i, j,\n\t\t\t\t\ttextLen = text.length,\n\t\t\t\t\tscoreThreshold = MATCH_THRESHOLD,\n\t\t\t\t\tbestLoc = text.indexOf(pattern, MATCH_LOCATION),\n\t\t\t\t\tbinMin, binMid,\n\t\t\t\t\tbinMax = patternLen + textLen,\n\t\t\t\t\tlastRd, start, finish, rd, charMatch,\n\t\t\t\t\tscore = 1,\n\t\t\t\t\tlocations = [];\n\t\t\t\tif (bestLoc !== -1) {\n\t\t\t\t\tscoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);\n\t\t\t\t\tbestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen);\n\t\t\t\t\tif (bestLoc !== -1) {\n\t\t\t\t\t\tscoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbestLoc = -1;\n\t\t\t\tfor (i = 0; i < patternLen; i++) {\n\t\t\t\t\tbinMin = 0;\n\t\t\t\t\tbinMid = binMax;\n\t\t\t\t\twhile (binMin < binMid) {\n\t\t\t\t\t\tif (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) {\n\t\t\t\t\t\t\tbinMin = binMid;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbinMax = binMid;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbinMid = Math.floor((binMax - binMin) / 2 + binMin);\n\t\t\t\t\t}\n\t\t\t\t\tbinMax = binMid;\n\t\t\t\t\tstart = Math.max(1, MATCH_LOCATION - binMid + 1);\n\t\t\t\t\tfinish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen;\n\t\t\t\t\trd = new Array(finish + 2);\n\t\t\t\t\trd[finish + 1] = (1 << i) - 1;\n\t\t\t\t\tfor (j = finish; j >= start; j--) {\n\t\t\t\t\t\tcharMatch = pattern_alphabet[text.charAt(j - 1)];\n\t\t\t\t\t\tif (i === 0) {\n\t\t\t\t\t\t\trd[j] = ((rd[j + 1] << 1) | 1) & charMatch;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (rd[j] & matchmask) {\n\t\t\t\t\t\t\tscore = match_bitapScore(i, j - 1);\n\t\t\t\t\t\t\tif (score <= scoreThreshold) {\n\t\t\t\t\t\t\t\tscoreThreshold = score;\n\t\t\t\t\t\t\t\tbestLoc = j - 1;\n\t\t\t\t\t\t\t\tlocations.push(bestLoc);\n\t\t\t\t\t\t\t\tif (bestLoc > MATCH_LOCATION) {\n\t\t\t\t\t\t\t\t\tstart = Math.max(1, 2 * MATCH_LOCATION - bestLoc);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tlastRd = rd;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tisMatch: bestLoc >= 0,\n\t\t\t\t\tscore: score\n\t\t\t\t};\n\t\t\t};\n\t\t\treturn txt === true ? { 'search' : search } : search(txt);\n\t\t};\n\t\t$.vakata.search.defaults = {\n\t\t\tlocation : 0,\n\t\t\tdistance : 100,\n\t\t\tthreshold : 0.6,\n\t\t\tfuzzy : false,\n\t\t\tcaseSensitive : false\n\t\t};\n\t}($));\n\n\t// include the search plugin by default\n\t// $.jstree.defaults.plugins.push(\"search\");\n\n\n/**\n * ### Sort plugin\n *\n * Automatically sorts all siblings in the tree according to a sorting function.\n */\n\n\t/**\n\t * the settings function used to sort the nodes.\n\t * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`.\n\t * @name $.jstree.defaults.sort\n\t * @plugin sort\n\t */\n\t$.jstree.defaults.sort = function (a, b) {\n\t\t//return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b);\n\t\treturn this.get_text(a) > this.get_text(b) ? 1 : -1;\n\t};\n\t$.jstree.plugins.sort = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\t\t\tthis.element\n\t\t\t\t.on(\"model.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.sort(data.parent, true);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"rename_node.jstree create_node.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.sort(data.parent || data.node.parent, false);\n\t\t\t\t\t\tthis.redraw_node(data.parent || data.node.parent, true);\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"move_node.jstree copy_node.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.sort(data.parent, false);\n\t\t\t\t\t\tthis.redraw_node(data.parent, true);\n\t\t\t\t\t}.bind(this));\n\t\t};\n\t\t/**\n\t\t * used to sort a node's children\n\t\t * @private\n\t\t * @name sort(obj [, deep])\n\t\t * @param {mixed} obj the node\n\t\t * @param {Boolean} deep if set to `true` nodes are sorted recursively.\n\t\t * @plugin sort\n\t\t * @trigger search.jstree\n\t\t */\n\t\tthis.sort = function (obj, deep) {\n\t\t\tvar i, j;\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(obj && obj.children && obj.children.length) {\n\t\t\t\tobj.children.sort(this.settings.sort.bind(this));\n\t\t\t\tif(deep) {\n\t\t\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\t\t\tthis.sort(obj.children_d[i], false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t};\n\n\t// include the sort plugin by default\n\t// $.jstree.defaults.plugins.push(\"sort\");\n\n/**\n * ### State plugin\n *\n * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc)\n */\n\n\tvar to = false;\n\t/**\n\t * stores all defaults for the state plugin\n\t * @name $.jstree.defaults.state\n\t * @plugin state\n\t */\n\t$.jstree.defaults.state = {\n\t\t/**\n\t\t * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`.\n\t\t * @name $.jstree.defaults.state.key\n\t\t * @plugin state\n\t\t */\n\t\tkey\t\t: 'jstree',\n\t\t/**\n\t\t * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`.\n\t\t * @name $.jstree.defaults.state.events\n\t\t * @plugin state\n\t\t */\n\t\tevents\t: 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree',\n\t\t/**\n\t\t * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire.\n\t\t * @name $.jstree.defaults.state.ttl\n\t\t * @plugin state\n\t\t */\n\t\tttl\t\t: false,\n\t\t/**\n\t\t * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state.\n\t\t * @name $.jstree.defaults.state.filter\n\t\t * @plugin state\n\t\t */\n\t\tfilter\t: false,\n\t\t/**\n\t\t * Should loaded nodes be restored (setting this to true means that it is possible that the whole tree will be loaded for some users - use with caution). Defaults to `false`\n\t\t * @name $.jstree.defaults.state.preserve_loaded\n\t\t * @plugin state\n\t\t */\n\t\tpreserve_loaded : false\n\t};\n\t$.jstree.plugins.state = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\t\t\tvar bind = function () {\n\t\t\t\tthis.element.on(this.settings.state.events, function () {\n\t\t\t\t\tif(to) { clearTimeout(to); }\n\t\t\t\t\tto = setTimeout(function () { this.save_state(); }.bind(this), 100);\n\t\t\t\t}.bind(this));\n\t\t\t\t/**\n\t\t\t\t * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore).\n\t\t\t\t * @event\n\t\t\t\t * @name state_ready.jstree\n\t\t\t\t * @plugin state\n\t\t\t\t */\n\t\t\t\tthis.trigger('state_ready');\n\t\t\t}.bind(this);\n\t\t\tthis.element\n\t\t\t\t.on(\"ready.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.element.one(\"restore_state.jstree\", bind);\n\t\t\t\t\t\tif(!this.restore_state()) { bind(); }\n\t\t\t\t\t}.bind(this));\n\t\t};\n\t\t/**\n\t\t * save the state\n\t\t * @name save_state()\n\t\t * @plugin state\n\t\t */\n\t\tthis.save_state = function () {\n\t\t\tvar tm = this.get_state();\n\t\t\tif (!this.settings.state.preserve_loaded) {\n\t\t\t\tdelete tm.core.loaded;\n\t\t\t}\n\t\t\tvar st = { 'state' : tm, 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) };\n\t\t\t$.vakata.storage.set(this.settings.state.key, JSON.stringify(st));\n\t\t};\n\t\t/**\n\t\t * restore the state from the user's computer\n\t\t * @name restore_state()\n\t\t * @plugin state\n\t\t */\n\t\tthis.restore_state = function () {\n\t\t\tvar k = $.vakata.storage.get(this.settings.state.key);\n\t\t\tif(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } }\n\t\t\tif(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; }\n\t\t\tif(!!k && k.state) { k = k.state; }\n\t\t\tif(!!k && $.vakata.is_function(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); }\n\t\t\tif(!!k) {\n\t\t\t\tif (!this.settings.state.preserve_loaded) {\n\t\t\t\t\tdelete k.core.loaded;\n\t\t\t\t}\n\t\t\t\tthis.element.one(\"set_state.jstree\", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); });\n\t\t\t\tthis.set_state(k);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t\t/**\n\t\t * clear the state on the user's computer\n\t\t * @name clear_state()\n\t\t * @plugin state\n\t\t */\n\t\tthis.clear_state = function () {\n\t\t\treturn $.vakata.storage.del(this.settings.state.key);\n\t\t};\n\t};\n\n\t(function ($, undefined) {\n\t\t$.vakata.storage = {\n\t\t\t// simply specifying the functions in FF throws an error\n\t\t\tset : function (key, val) { return window.localStorage.setItem(key, val); },\n\t\t\tget : function (key) { return window.localStorage.getItem(key); },\n\t\t\tdel : function (key) { return window.localStorage.removeItem(key); }\n\t\t};\n\t}($));\n\n\t// include the state plugin by default\n\t// $.jstree.defaults.plugins.push(\"state\");\n\n/**\n * ### Types plugin\n *\n * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group.\n */\n\n\t/**\n\t * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional).\n\t *\n\t * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited.\n\t * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.\n\t * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.\n\t * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme.\n\t * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data)\n\t * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data)\n\t *\n\t * There are two predefined types:\n\t *\n\t * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes.\n\t * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified.\n\t *\n\t * @name $.jstree.defaults.types\n\t * @plugin types\n\t */\n\t$.jstree.defaults.types = {\n\t\t'default' : {}\n\t};\n\t$.jstree.defaults.types[$.jstree.root] = {};\n\n\t$.jstree.plugins.types = function (options, parent) {\n\t\tthis.init = function (el, options) {\n\t\t\tvar i, j;\n\t\t\tif(options && options.types && options.types['default']) {\n\t\t\t\tfor(i in options.types) {\n\t\t\t\t\tif(i !== \"default\" && i !== $.jstree.root && options.types.hasOwnProperty(i)) {\n\t\t\t\t\t\tfor(j in options.types['default']) {\n\t\t\t\t\t\t\tif(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {\n\t\t\t\t\t\t\t\toptions.types[i][j] = options.types['default'][j];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tparent.init.call(this, el, options);\n\t\t\tthis._model.data[$.jstree.root].type = $.jstree.root;\n\t\t};\n\t\tthis.refresh = function (skip_loading, forget_state) {\n\t\t\tparent.refresh.call(this, skip_loading, forget_state);\n\t\t\tthis._model.data[$.jstree.root].type = $.jstree.root;\n\t\t};\n\t\tthis.bind = function () {\n\t\t\tthis.element\n\t\t\t\t.on('model.jstree', function (e, data) {\n\t\t\t\t\t\tvar m = this._model.data,\n\t\t\t\t\t\t\tdpc = data.nodes,\n\t\t\t\t\t\t\tt = this.settings.types,\n\t\t\t\t\t\t\ti, j, c = 'default', k;\n\t\t\t\t\t\tfor(i = 0, j = dpc.length; i < j; i++) {\n\t\t\t\t\t\t\tc = 'default';\n\t\t\t\t\t\t\tif(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {\n\t\t\t\t\t\t\t\tc = m[dpc[i]].original.type;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) {\n\t\t\t\t\t\t\t\tc = m[dpc[i]].data.jstree.type;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tm[dpc[i]].type = c;\n\t\t\t\t\t\t\tif(m[dpc[i]].icon === true && t[c].icon !== undefined) {\n\t\t\t\t\t\t\t\tm[dpc[i]].icon = t[c].icon;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (k in t[c].li_attr) {\n\t\t\t\t\t\t\t\t\tif (t[c].li_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (m[dpc[i]].li_attr[k] === undefined) {\n\t\t\t\t\t\t\t\t\t\t\tm[dpc[i]].li_attr[k] = t[c].li_attr[k];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\t\t\t\t\tm[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class'];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') {\n\t\t\t\t\t\t\t\tfor (k in t[c].a_attr) {\n\t\t\t\t\t\t\t\t\tif (t[c].a_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (m[dpc[i]].a_attr[k] === undefined) {\n\t\t\t\t\t\t\t\t\t\t\tm[dpc[i]].a_attr[k] = t[c].a_attr[k];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (k === 'href' && m[dpc[i]].a_attr[k] === '#') {\n\t\t\t\t\t\t\t\t\t\t\tm[dpc[i]].a_attr['href'] = t[c].a_attr['href'];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\t\t\t\t\tm[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class'];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tm[$.jstree.root].type = $.jstree.root;\n\t\t\t\t\t}.bind(this));\n\t\t\tparent.bind.call(this);\n\t\t};\n\t\tthis.get_json = function (obj, options, flat) {\n\t\t\tvar i, j,\n\t\t\t\tm = this._model.data,\n\t\t\t\topt = options ? $.extend(true, {}, options, {no_id:false}) : {},\n\t\t\t\ttmp = parent.get_json.call(this, obj, opt, flat);\n\t\t\tif(tmp === false) { return false; }\n\t\t\tif($.vakata.is_array(tmp)) {\n\t\t\t\tfor(i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\t\ttmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : \"default\";\n\t\t\t\t\tif(options && options.no_id) {\n\t\t\t\t\t\tdelete tmp[i].id;\n\t\t\t\t\t\tif(tmp[i].li_attr && tmp[i].li_attr.id) {\n\t\t\t\t\t\t\tdelete tmp[i].li_attr.id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(tmp[i].a_attr && tmp[i].a_attr.id) {\n\t\t\t\t\t\t\tdelete tmp[i].a_attr.id;\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\telse {\n\t\t\t\ttmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : \"default\";\n\t\t\t\tif(options && options.no_id) {\n\t\t\t\t\ttmp = this._delete_ids(tmp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn tmp;\n\t\t};\n\t\tthis._delete_ids = function (tmp) {\n\t\t\tif($.vakata.is_array(tmp)) {\n\t\t\t\tfor(var i = 0, j = tmp.length; i < j; i++) {\n\t\t\t\t\ttmp[i] = this._delete_ids(tmp[i]);\n\t\t\t\t}\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\tdelete tmp.id;\n\t\t\tif(tmp.li_attr && tmp.li_attr.id) {\n\t\t\t\tdelete tmp.li_attr.id;\n\t\t\t}\n\t\t\tif(tmp.a_attr && tmp.a_attr.id) {\n\t\t\t\tdelete tmp.a_attr.id;\n\t\t\t}\n\t\t\tif(tmp.children && $.vakata.is_array(tmp.children)) {\n\t\t\t\ttmp.children = this._delete_ids(tmp.children);\n\t\t\t}\n\t\t\treturn tmp;\n\t\t};\n\t\tthis.check = function (chk, obj, par, pos, more) {\n\t\t\tif(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }\n\t\t\tobj = obj && obj.id ? obj : this.get_node(obj);\n\t\t\tpar = par && par.id ? par : this.get_node(par);\n\t\t\tvar m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j;\n\t\t\tm = m && m._model && m._model.data ? m._model.data : null;\n\t\t\tswitch(chk) {\n\t\t\t\tcase \"create_node\":\n\t\t\t\tcase \"move_node\":\n\t\t\t\tcase \"copy_node\":\n\t\t\t\t\tif(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) {\n\t\t\t\t\t\ttmp = this.get_rules(par);\n\t\t\t\t\t\tif(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) {\n\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) {\n\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(m && obj.children_d && obj.parents) {\n\t\t\t\t\t\t\td = 0;\n\t\t\t\t\t\t\tfor(i = 0, j = obj.children_d.length; i < j; i++) {\n\t\t\t\t\t\t\t\td = Math.max(d, m[obj.children_d[i]].parents.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\td = d - obj.parents.length + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(d <= 0 || d === undefined) { d = 1; }\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\tif(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) {\n\t\t\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpar = this.get_node(par.parent);\n\t\t\t\t\t\t\ttmp = this.get_rules(par);\n\t\t\t\t\t\t\td++;\n\t\t\t\t\t\t} while(par);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\t/**\n\t\t * used to retrieve the type settings object for a node\n\t\t * @name get_rules(obj)\n\t\t * @param {mixed} obj the node to find the rules for\n\t\t * @return {Object}\n\t\t * @plugin types\n\t\t */\n\t\tthis.get_rules = function (obj) {\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!obj) { return false; }\n\t\t\tvar tmp = this.get_type(obj, true);\n\t\t\tif(tmp.max_depth === undefined) { tmp.max_depth = -1; }\n\t\t\tif(tmp.max_children === undefined) { tmp.max_children = -1; }\n\t\t\tif(tmp.valid_children === undefined) { tmp.valid_children = -1; }\n\t\t\treturn tmp;\n\t\t};\n\t\t/**\n\t\t * used to retrieve the type string or settings object for a node\n\t\t * @name get_type(obj [, rules])\n\t\t * @param {mixed} obj the node to find the rules for\n\t\t * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned\n\t\t * @return {String|Object}\n\t\t * @plugin types\n\t\t */\n\t\tthis.get_type = function (obj, rules) {\n\t\t\tobj = this.get_node(obj);\n\t\t\treturn (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type);\n\t\t};\n\t\t/**\n\t\t * used to change a node's type\n\t\t * @name set_type(obj, type)\n\t\t * @param {mixed} obj the node to change\n\t\t * @param {String} type the new type\n\t\t * @plugin types\n\t\t */\n\t\tthis.set_type = function (obj, type) {\n\t\t\tvar m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a;\n\t\t\tif($.vakata.is_array(obj)) {\n\t\t\t\tobj = obj.slice();\n\t\t\t\tfor(t1 = 0, t2 = obj.length; t1 < t2; t1++) {\n\t\t\t\t\tthis.set_type(obj[t1], type);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tt = this.settings.types;\n\t\t\tobj = this.get_node(obj);\n\t\t\tif(!t[type] || !obj) { return false; }\n\t\t\td = this.get_node(obj, true);\n\t\t\tif (d && d.length) {\n\t\t\t\ta = d.children('.jstree-anchor');\n\t\t\t}\n\t\t\told_type = obj.type;\n\t\t\told_icon = this.get_icon(obj);\n\t\t\tobj.type = type;\n\t\t\tif(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {\n\t\t\t\tthis.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);\n\t\t\t}\n\n\t\t\t// remove old type props\n\t\t\tif(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') {\n\t\t\t\tfor (k in t[old_type].li_attr) {\n\t\t\t\t\tif (t[old_type].li_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\tm[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], '');\n\t\t\t\t\t\t\tif (d) { d.removeClass(t[old_type].li_attr[k]); }\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) {\n\t\t\t\t\t\t\tm[obj.id].li_attr[k] = null;\n\t\t\t\t\t\t\tif (d) { d.removeAttr(k); }\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\tif(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') {\n\t\t\t\tfor (k in t[old_type].a_attr) {\n\t\t\t\t\tif (t[old_type].a_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\tm[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], '');\n\t\t\t\t\t\t\tif (a) { a.removeClass(t[old_type].a_attr[k]); }\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) {\n\t\t\t\t\t\t\tif (k === 'href') {\n\t\t\t\t\t\t\t\tm[obj.id].a_attr[k] = '#';\n\t\t\t\t\t\t\t\tif (a) { a.attr('href', '#'); }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tdelete m[obj.id].a_attr[k];\n\t\t\t\t\t\t\t\tif (a) { a.removeAttr(k); }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add new props\n\t\t\tif(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') {\n\t\t\t\tfor (k in t[type].li_attr) {\n\t\t\t\t\tif (t[type].li_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (m[obj.id].li_attr[k] === undefined) {\n\t\t\t\t\t\t\tm[obj.id].li_attr[k] = t[type].li_attr[k];\n\t\t\t\t\t\t\tif (d) {\n\t\t\t\t\t\t\t\tif (k === 'class') {\n\t\t\t\t\t\t\t\t\td.addClass(t[type].li_attr[k]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\td.attr(k, t[type].li_attr[k]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\tm[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class'];\n\t\t\t\t\t\t\tif (d) { d.addClass(t[type].li_attr[k]); }\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\tif(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') {\n\t\t\t\tfor (k in t[type].a_attr) {\n\t\t\t\t\tif (t[type].a_attr.hasOwnProperty(k)) {\n\t\t\t\t\t\tif (k === 'id') {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (m[obj.id].a_attr[k] === undefined) {\n\t\t\t\t\t\t\tm[obj.id].a_attr[k] = t[type].a_attr[k];\n\t\t\t\t\t\t\tif (a) {\n\t\t\t\t\t\t\t\tif (k === 'class') {\n\t\t\t\t\t\t\t\t\ta.addClass(t[type].a_attr[k]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\ta.attr(k, t[type].a_attr[k]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (k === 'href' && m[obj.id].a_attr[k] === '#') {\n\t\t\t\t\t\t\tm[obj.id].a_attr['href'] = t[type].a_attr['href'];\n\t\t\t\t\t\t\tif (a) { a.attr('href', t[type].a_attr['href']); }\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (k === 'class') {\n\t\t\t\t\t\t\tm[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class'];\n\t\t\t\t\t\t\tif (a) { a.addClass(t[type].a_attr[k]); }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\t};\n\t// include the types plugin by default\n\t// $.jstree.defaults.plugins.push(\"types\");\n\n\n/**\n * ### Unique plugin\n *\n * Enforces that no nodes with the same name can coexist as siblings.\n */\n\n\t/**\n\t * stores all defaults for the unique plugin\n\t * @name $.jstree.defaults.unique\n\t * @plugin unique\n\t */\n\t$.jstree.defaults.unique = {\n\t\t/**\n\t\t * Indicates if the comparison should be case sensitive. Default is `false`.\n\t\t * @name $.jstree.defaults.unique.case_sensitive\n\t\t * @plugin unique\n\t\t */\n\t\tcase_sensitive : false,\n\t\t/**\n\t\t * Indicates if white space should be trimmed before the comparison. Default is `false`.\n\t\t * @name $.jstree.defaults.unique.trim_whitespace\n\t\t * @plugin unique\n\t\t */\n\t\ttrim_whitespace : false,\n\t\t/**\n\t\t * A callback executed in the instance's scope when a new node is created with no name and a node with the default name already exists, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`.\n\t\t * @name $.jstree.defaults.unique.duplicate\n\t\t * @plugin unique\n\t\t */\n\t\tduplicate : function (name, counter) {\n\t\t\treturn name + ' (' + counter + ')';\n\t\t}\n\t};\n\n\t$.jstree.plugins.unique = function (options, parent) {\n\t\tthis.check = function (chk, obj, par, pos, more) {\n\t\t\tif(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }\n\t\t\tobj = obj && obj.id ? obj : this.get_node(obj);\n\t\t\tpar = par && par.id ? par : this.get_node(par);\n\t\t\tif(!par || !par.children) { return true; }\n\t\t\tvar n = chk === \"rename_node\" ? pos : obj.text,\n\t\t\t\tc = [],\n\t\t\t\ts = this.settings.unique.case_sensitive,\n\t\t\t\tw = this.settings.unique.trim_whitespace,\n\t\t\t\tm = this._model.data, i, j, t;\n\t\t\tfor(i = 0, j = par.children.length; i < j; i++) {\n\t\t\t\tt = m[par.children[i]].text;\n\t\t\t\tif (!s) {\n\t\t\t\t\tt = t.toLowerCase();\n\t\t\t\t}\n\t\t\t\tif (w) {\n\t\t\t\t\tt = t.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t\t\t\t}\n\t\t\t\tc.push(t);\n\t\t\t}\n\t\t\tif(!s) { n = n.toLowerCase(); }\n\t\t\tif (w) { n = n.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, ''); }\n\t\t\tswitch(chk) {\n\t\t\t\tcase \"delete_node\":\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"rename_node\":\n\t\t\t\t\tt = obj.text || '';\n\t\t\t\t\tif (!s) {\n\t\t\t\t\t\tt = t.toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (w) {\n\t\t\t\t\t\tt = t.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t\t\t\t\t}\n\t\t\t\t\ti = ($.inArray(n, c) === -1 || (obj.text && t === n));\n\t\t\t\t\tif(!i) {\n\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t}\n\t\t\t\t\treturn i;\n\t\t\t\tcase \"create_node\":\n\t\t\t\t\ti = ($.inArray(n, c) === -1);\n\t\t\t\t\tif(!i) {\n\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t}\n\t\t\t\t\treturn i;\n\t\t\t\tcase \"copy_node\":\n\t\t\t\t\ti = ($.inArray(n, c) === -1);\n\t\t\t\t\tif(!i) {\n\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t}\n\t\t\t\t\treturn i;\n\t\t\t\tcase \"move_node\":\n\t\t\t\t\ti = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1);\n\t\t\t\t\tif(!i) {\n\t\t\t\t\t\tthis._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };\n\t\t\t\t\t}\n\t\t\t\t\treturn i;\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\tthis.create_node = function (par, node, pos, callback, is_loaded) {\n\t\t\tif(!node || (typeof node === 'object' && node.text === undefined)) {\n\t\t\t\tif(par === null) {\n\t\t\t\t\tpar = $.jstree.root;\n\t\t\t\t}\n\t\t\t\tpar = this.get_node(par);\n\t\t\t\tif(!par) {\n\t\t\t\t\treturn parent.create_node.call(this, par, node, pos, callback, is_loaded);\n\t\t\t\t}\n\t\t\t\tpos = pos === undefined ? \"last\" : pos;\n\t\t\t\tif(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {\n\t\t\t\t\treturn parent.create_node.call(this, par, node, pos, callback, is_loaded);\n\t\t\t\t}\n\t\t\t\tif(!node) { node = {}; }\n\t\t\t\tvar tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, w = this.settings.unique.trim_whitespace, cb = this.settings.unique.duplicate, t;\n\t\t\t\tn = tmp = this.get_string('New node');\n\t\t\t\tdpc = [];\n\t\t\t\tfor(i = 0, j = par.children.length; i < j; i++) {\n\t\t\t\t\tt = m[par.children[i]].text;\n\t\t\t\t\tif (!s) {\n\t\t\t\t\t\tt = t.toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (w) {\n\t\t\t\t\t\tt = t.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t\t\t\t\t}\n\t\t\t\t\tdpc.push(t);\n\t\t\t\t}\n\t\t\t\ti = 1;\n\t\t\t\tt = n;\n\t\t\t\tif (!s) {\n\t\t\t\t\tt = t.toLowerCase();\n\t\t\t\t}\n\t\t\t\tif (w) {\n\t\t\t\t\tt = t.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t\t\t\t}\n\t\t\t\twhile($.inArray(t, dpc) !== -1) {\n\t\t\t\t\tn = cb.call(this, tmp, (++i)).toString();\n\t\t\t\t\tt = n;\n\t\t\t\t\tif (!s) {\n\t\t\t\t\t\tt = t.toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (w) {\n\t\t\t\t\t\tt = t.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode.text = n;\n\t\t\t}\n\t\t\treturn parent.create_node.call(this, par, node, pos, callback, is_loaded);\n\t\t};\n\t};\n\n\t// include the unique plugin by default\n\t// $.jstree.defaults.plugins.push(\"unique\");\n\n\n/**\n * ### Wholerow plugin\n *\n * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers.\n */\n\n\tvar div = document.createElement('DIV');\n\tdiv.setAttribute('unselectable','on');\n\tdiv.setAttribute('role','presentation');\n\tdiv.className = 'jstree-wholerow';\n\tdiv.innerHTML = ' ';\n\t$.jstree.plugins.wholerow = function (options, parent) {\n\t\tthis.bind = function () {\n\t\t\tparent.bind.call(this);\n\n\t\t\tthis.element\n\t\t\t\t.on('ready.jstree set_state.jstree', function () {\n\t\t\t\t\t\tthis.hide_dots();\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"init.jstree loading.jstree ready.jstree\", function () {\n\t\t\t\t\t\t//div.style.height = this._data.core.li_height + 'px';\n\t\t\t\t\t\tthis.get_container_ul().addClass('jstree-wholerow-ul');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"deselect_all.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"changed.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');\n\t\t\t\t\t\tvar tmp = false, i, j;\n\t\t\t\t\t\tfor(i = 0, j = data.selected.length; i < j; i++) {\n\t\t\t\t\t\t\ttmp = this.get_node(data.selected[i], true);\n\t\t\t\t\t\t\tif(tmp && tmp.length) {\n\t\t\t\t\t\t\t\ttmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"open_node.jstree\", function (e, data) {\n\t\t\t\t\t\tthis.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"hover_node.jstree dehover_node.jstree\", function (e, data) {\n\t\t\t\t\t\tif(e.type === \"hover_node\" && this.is_disabled(data.node)) { return; }\n\t\t\t\t\t\tthis.get_node(data.node, true).children('.jstree-wholerow')[e.type === \"hover_node\"?\"addClass\":\"removeClass\"]('jstree-wholerow-hovered');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"contextmenu.jstree\", \".jstree-wholerow\", function (e) {\n\t\t\t\t\t\tif (this._data.contextmenu) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvar tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });\n\t\t\t\t\t\t\t$(e.currentTarget).closest(\".jstree-node\").children(\".jstree-anchor\").first().trigger(tmp);\n\t\t\t\t\t\t}\n\t\t\t\t\t}.bind(this))\n\t\t\t\t/*!\n\t\t\t\t.on(\"mousedown.jstree touchstart.jstree\", \".jstree-wholerow\", function (e) {\n\t\t\t\t\t\tif(e.target === e.currentTarget) {\n\t\t\t\t\t\t\tvar a = $(e.currentTarget).closest(\".jstree-node\").children(\".jstree-anchor\");\n\t\t\t\t\t\t\te.target = a[0];\n\t\t\t\t\t\t\ta.trigger(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t*/\n\t\t\t\t.on(\"click.jstree\", \".jstree-wholerow\", function (e) {\n\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\tvar tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });\n\t\t\t\t\t\t$(e.currentTarget).closest(\".jstree-node\").children(\".jstree-anchor\").first().trigger(tmp).trigger('focus');\n\t\t\t\t\t})\n\t\t\t\t.on(\"dblclick.jstree\", \".jstree-wholerow\", function (e) {\n\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\tvar tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });\n\t\t\t\t\t\t$(e.currentTarget).closest(\".jstree-node\").children(\".jstree-anchor\").first().trigger(tmp).trigger('focus');\n\t\t\t\t\t})\n\t\t\t\t.on(\"click.jstree\", \".jstree-leaf > .jstree-ocl\", function (e) {\n\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\tvar tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });\n\t\t\t\t\t\t$(e.currentTarget).closest(\".jstree-node\").children(\".jstree-anchor\").first().trigger(tmp).trigger('focus');\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"mouseover.jstree\", \".jstree-wholerow, .jstree-icon\", function (e) {\n\t\t\t\t\t\te.stopImmediatePropagation();\n\t\t\t\t\t\tif(!this.is_disabled(e.currentTarget)) {\n\t\t\t\t\t\t\tthis.hover_node(e.currentTarget);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}.bind(this))\n\t\t\t\t.on(\"mouseleave.jstree\", \".jstree-node\", function (e) {\n\t\t\t\t\t\tthis.dehover_node(e.currentTarget);\n\t\t\t\t\t}.bind(this));\n\t\t};\n\t\tthis.teardown = function () {\n\t\t\tif(this.settings.wholerow) {\n\t\t\t\tthis.element.find(\".jstree-wholerow\").remove();\n\t\t\t}\n\t\t\tparent.teardown.call(this);\n\t\t};\n\t\tthis.redraw_node = function(obj, deep, callback, force_render) {\n\t\t\tobj = parent.redraw_node.apply(this, arguments);\n\t\t\tif(obj) {\n\t\t\t\tvar tmp = div.cloneNode(true);\n\t\t\t\t//tmp.style.height = this._data.core.li_height + 'px';\n\t\t\t\tif($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; }\n\t\t\t\tif(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; }\n\t\t\t\tobj.insertBefore(tmp, obj.childNodes[0]);\n\t\t\t}\n\t\t\treturn obj;\n\t\t};\n\t};\n\t// include the wholerow plugin by default\n\t// $.jstree.defaults.plugins.push(\"wholerow\");\n\tif(window.customElements && Object && Object.create) {\n\t\tvar proto = Object.create(HTMLElement.prototype);\n\t\tproto.createdCallback = function () {\n\t\t\tvar c = { core : {}, plugins : [] }, i;\n\t\t\tfor(i in $.jstree.plugins) {\n\t\t\t\tif($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) {\n\t\t\t\t\tc.plugins.push(i);\n\t\t\t\t\tif(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) {\n\t\t\t\t\t\tc[i] = JSON.parse(this.getAttribute(i));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(i in $.jstree.defaults.core) {\n\t\t\t\tif($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) {\n\t\t\t\t\tc.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\t$(this).jstree(c);\n\t\t};\n\t\t// proto.attributeChangedCallback = function (name, previous, value) { };\n\t\ttry {\n\t\t\twindow.customElements.define(\"vakata-jstree\", function() {}, { prototype: proto });\n\t\t} catch (ignore) { }\n\t}\n\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvanN0cmVlL2Rpc3QvanN0cmVlLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBLEtBQUssSUFBMEM7QUFDL0MsRUFBRSxpQ0FBTyxDQUFDLDJDQUFRLENBQUMsb0NBQUUsT0FBTztBQUFBO0FBQUE7QUFBQSxrR0FBQztBQUM3QjtBQUNBLE1BQU0sRUFLSjtBQUNGLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQSxxQ0FBcUMsV0FBVztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDBCQUEwQjtBQUN0QyxZQUFZLFFBQVE7QUFDcEIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNB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O0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLE9BQU87QUFDM0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsT0FBTztBQUMzQztBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEMsT0FBTztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLE9BQU87QUFDMUM7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLE9BQU87QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCLG1DQUFtQyxPQUFPO0FBQzFDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxPQUFPO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsT0FBTztBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLE9BQU87QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0VBQXNFO0FBQ3RFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLE9BQU87QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxPQUFPO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLE9BQU87QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsT0FBTztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsU0FBUztBQUN2QixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCLDRCQUE0QixPQUFPO0FBQ25DO0FBQ0EsNENBQTRDLE9BQU87QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLE9BQU87QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxPQUFPO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxPQUFPO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7O0FBRUE7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxPQUFPO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRjtBQUMzRjtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsMENBQTBDO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsMkNBQTJDO0FBQ2xGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsd0NBQXdDLDBCQUEwQixPQUFPO0FBQ2xIO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTztBQUNyQixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsT0FBTztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsU0FBUztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBLHVDQUF1QyxjQUFjO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsU0FBUztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBLHNDQUFzQyxjQUFjO0FBQ3BEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsNkJBQTZCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQSw4QkFBOEIsT0FBTztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsTUFBTTtBQUNuQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLE9BQU87QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsU0FBUztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0E7QUFDQSxpQ0FBaUMsc0VBQXNFO0FBQ3ZHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLFNBQVM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0EsbUNBQW1DLHNFQUFzRTtBQUN6RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0EsdURBQXVELE9BQU87QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQSwrQkFBK0IsMkNBQTJDO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBLGlDQUFpQyx5REFBeUQ7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxRQUFRO0FBQ3RCLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUMsb0VBQW9FLDBCQUEwQjtBQUM5RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0EsWUFBWTtBQUNaLDhCQUE4QixPQUFPO0FBQ3JDO0FBQ0E7QUFDQSw4QkFBOEIsT0FBTztBQUNyQyw2Q0FBNkMsT0FBTztBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLDBCQUEwQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQSw4QkFBOEIsT0FBTztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQywwQkFBMEI7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLE9BQU87QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRUFBMkU7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBLFNBQVM7QUFDVCxpQ0FBaUMsc0JBQXNCO0FBQ3ZEO0FBQ0EsT0FBTztBQUNQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLDBGQUEwRjtBQUMxRjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLDhCQUE4QixrQkFBa0I7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsY0FBYyxRQUFRO0FBQ3RCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0Esc0NBQXNDLGdDQUFnQztBQUN0RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBO0FBQ0Esc0ZBQXNGLHdGQUF3RjtBQUM5SztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxJQUFJO0FBQ0o7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCO0FBQ3RCO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQSw4SkFBOEo7QUFDOUo7QUFDQTtBQUNBLHVJQUF1SSwwRkFBMEY7QUFDak87QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEU7QUFDMUUsY0FBYztBQUNkO0FBQ0Esb0VBQW9FO0FBQ3BFO0FBQ0EsMkRBQTJELHdGQUF3RjtBQUNuSjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBLDhKQUE4SjtBQUM5SjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QjtBQUNBLHVCQUF1QiwyQkFBMkI7QUFDbEQ7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLHVCQUF1QjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEIsZ0JBQWdCLFFBQVE7QUFDeEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCLGdCQUFnQixRQUFRO0FBQ3hCLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLFFBQVE7QUFDUjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNILEVBQUU7QUFDRjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBLDRDQUE0Qyw0Q0FBNEM7QUFDeEYsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLDRDQUE0QztBQUN0RjtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsNENBQTRDLDRDQUE0QztBQUN4RjtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsMENBQTBDLDRDQUE0QztBQUN0RjtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNB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LE9BQU87QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsbUVBQW1FO0FBQ25FO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxzSEFBc0g7QUFDaEs7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsb0ZBQW9GO0FBQ3ZIO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxzQ0FBc0Msb0ZBQW9GO0FBQzFIO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxtQ0FBbUMsb0ZBQW9GO0FBQ3ZIO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RDtBQUM3RCx3RUFBd0U7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQVMsZ0JBQWdCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsSUFBSSxrQkFBa0I7QUFDcEYsSUFBSTtBQUNKOztBQUVBLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9TbmVhdC8uL25vZGVfbW9kdWxlcy9qc3RyZWUvZGlzdC9qc3RyZWUuanM/NWY2MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbHMgalF1ZXJ5LCBkZWZpbmUsIG1vZHVsZSwgZXhwb3J0cywgcmVxdWlyZSwgd2luZG93LCBkb2N1bWVudCwgcG9zdE1lc3NhZ2UgKi9cbihmdW5jdGlvbiAoZmFjdG9yeSkge1xuXHRcInVzZSBzdHJpY3RcIjtcblx0aWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuXHRcdGRlZmluZShbJ2pxdWVyeSddLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIGlmKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoJ2pxdWVyeScpKTtcblx0fVxuXHRlbHNlIHtcblx0XHRmYWN0b3J5KGpRdWVyeSk7XG5cdH1cbn0oZnVuY3Rpb24gKCQsIHVuZGVmaW5lZCkge1xuXHRcInVzZSBzdHJpY3RcIjtcbi8qIVxuICoganNUcmVlIDMuMy4xNFxuICogaHR0cDovL2pzdHJlZS5jb20vXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE0IEl2YW4gQm96aGFub3YgKGh0dHA6Ly92YWthdGEuY29tKVxuICpcbiAqIExpY2Vuc2VkIHNhbWUgYXMganF1ZXJ5IC0gdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgTGljZW5zZVxuICogICBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICovXG4vKiFcbiAqIGlmIHVzaW5nIGpzbGludCBwbGVhc2UgYWxsb3cgZm9yIHRoZSBqUXVlcnkgZ2xvYmFsIGFuZCB1c2UgZm9sbG93aW5nIG9wdGlvbnM6XG4gKiBqc2xpbnQ6IGxvb3BmdW5jOiB0cnVlLCBicm93c2VyOiB0cnVlLCBhc3M6IHRydWUsIGJpdHdpc2U6IHRydWUsIGNvbnRpbnVlOiB0cnVlLCBub21lbjogdHJ1ZSwgcGx1c3BsdXM6IHRydWUsIHJlZ2V4cDogdHJ1ZSwgdW5wYXJhbTogdHJ1ZSwgdG9kbzogdHJ1ZSwgd2hpdGU6IHRydWVcbiAqL1xuLypqc2hpbnQgLVcwODMgKi9cblxuXHQvLyBwcmV2ZW50IGFub3RoZXIgbG9hZD8gbWF5YmUgdGhlcmUgaXMgYSBiZXR0ZXIgd2F5P1xuXHRpZigkLmpzdHJlZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8qKlxuXHQgKiAjIyMganNUcmVlIGNvcmUgZnVuY3Rpb25hbGl0eVxuXHQgKi9cblxuXHQvLyBpbnRlcm5hbCB2YXJpYWJsZXNcblx0dmFyIGluc3RhbmNlX2NvdW50ZXIgPSAwLFxuXHRcdGNjcF9ub2RlID0gZmFsc2UsXG5cdFx0Y2NwX21vZGUgPSBmYWxzZSxcblx0XHRjY3BfaW5zdCA9IGZhbHNlLFxuXHRcdHRoZW1lc19sb2FkZWQgPSBbXSxcblx0XHRzcmMgPSAkKCdzY3JpcHQ6bGFzdCcpLmF0dHIoJ3NyYycpLFxuXHRcdGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50OyAvLyBsb2NhbCB2YXJpYWJsZSBpcyBhbHdheXMgZmFzdGVyIHRvIGFjY2VzcyB0aGVuIGEgZ2xvYmFsXG5cblx0dmFyIHNldEltbWVkaWF0ZSA9IHdpbmRvdy5zZXRJbW1lZGlhdGU7XG5cdHZhciBQcm9taXNlID0gd2luZG93LlByb21pc2U7XG5cdGlmICghc2V0SW1tZWRpYXRlICYmIFByb21pc2UpIHtcblx0XHQvLyBHb29kIGVub3VnaCBhcHByb3hpbWF0aW9uIG9mIHNldEltbWVkaWF0ZVxuXHRcdHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uIChjYiwgYXJnKSB7XG5cdFx0XHRQcm9taXNlLnJlc29sdmUoYXJnKS50aGVuKGNiKTtcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIGhvbGRzIGFsbCBqc3RyZWUgcmVsYXRlZCBmdW5jdGlvbnMgYW5kIHZhcmlhYmxlcywgaW5jbHVkaW5nIHRoZSBhY3R1YWwgY2xhc3MgYW5kIG1ldGhvZHMgdG8gY3JlYXRlLCBhY2Nlc3MgYW5kIG1hbmlwdWxhdGUgaW5zdGFuY2VzLlxuXHQgKiBAbmFtZSAkLmpzdHJlZVxuXHQgKi9cblx0JC5qc3RyZWUgPSB7XG5cdFx0LyoqXG5cdFx0ICogc3BlY2lmaWVzIHRoZSBqc3RyZWUgdmVyc2lvbiBpbiB1c2Vcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS52ZXJzaW9uXG5cdFx0ICovXG5cdFx0dmVyc2lvbiA6ICczLjMuMTQnLFxuXHRcdC8qKlxuXHRcdCAqIGhvbGRzIGFsbCB0aGUgZGVmYXVsdCBvcHRpb25zIHVzZWQgd2hlbiBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHNcblx0XHQgKi9cblx0XHRkZWZhdWx0cyA6IHtcblx0XHRcdC8qKlxuXHRcdFx0ICogY29uZmlndXJlIHdoaWNoIHBsdWdpbnMgd2lsbCBiZSBhY3RpdmUgb24gYW4gaW5zdGFuY2UuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzLCB3aGVyZSBlYWNoIGVsZW1lbnQgaXMgYSBwbHVnaW4gbmFtZS4gVGhlIGRlZmF1bHQgaXMgYFtdYFxuXHRcdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2luc1xuXHRcdFx0ICovXG5cdFx0XHRwbHVnaW5zIDogW11cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHN0b3JlcyBhbGwgbG9hZGVkIGpzdHJlZSBwbHVnaW5zICh1c2VkIGludGVybmFsbHkpXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUucGx1Z2luc1xuXHRcdCAqL1xuXHRcdHBsdWdpbnMgOiB7fSxcblx0XHRwYXRoIDogc3JjICYmIHNyYy5pbmRleE9mKCcvJykgIT09IC0xID8gc3JjLnJlcGxhY2UoL1xcL1teXFwvXSskLywnJykgOiAnJyxcblx0XHRpZHJlZ2V4IDogL1tcXFxcOiYhXnwoKVxcW1xcXTw+QConK34jXCI7Liw9XFwtIFxcLyR7fSU/YF0vZyxcblx0XHRyb290IDogJyMnXG5cdH07XG5cdFxuXHQvKipcblx0ICogY3JlYXRlcyBhIGpzdHJlZSBpbnN0YW5jZVxuXHQgKiBAbmFtZSAkLmpzdHJlZS5jcmVhdGUoZWwgWywgb3B0aW9uc10pXG5cdCAqIEBwYXJhbSB7RE9NRWxlbWVudHxqUXVlcnl8U3RyaW5nfSBlbCB0aGUgZWxlbWVudCB0byBjcmVhdGUgdGhlIGluc3RhbmNlIG9uLCBjYW4gYmUgalF1ZXJ5IGV4dGVuZGVkIG9yIGEgc2VsZWN0b3Jcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhpcyBpbnN0YW5jZSAoZXh0ZW5kcyBgJC5qc3RyZWUuZGVmYXVsdHNgKVxuXHQgKiBAcmV0dXJuIHtqc1RyZWV9IHRoZSBuZXcgaW5zdGFuY2Vcblx0ICovXG5cdCQuanN0cmVlLmNyZWF0ZSA9IGZ1bmN0aW9uIChlbCwgb3B0aW9ucykge1xuXHRcdHZhciB0bXAgPSBuZXcgJC5qc3RyZWUuY29yZSgrK2luc3RhbmNlX2NvdW50ZXIpLFxuXHRcdFx0b3B0ID0gb3B0aW9ucztcblx0XHRvcHRpb25zID0gJC5leHRlbmQodHJ1ZSwge30sICQuanN0cmVlLmRlZmF1bHRzLCBvcHRpb25zKTtcblx0XHRpZihvcHQgJiYgb3B0LnBsdWdpbnMpIHtcblx0XHRcdG9wdGlvbnMucGx1Z2lucyA9IG9wdC5wbHVnaW5zO1xuXHRcdH1cblx0XHQkLmVhY2gob3B0aW9ucy5wbHVnaW5zLCBmdW5jdGlvbiAoaSwgaykge1xuXHRcdFx0aWYoaSAhPT0gJ2NvcmUnKSB7XG5cdFx0XHRcdHRtcCA9IHRtcC5wbHVnaW4oaywgb3B0aW9uc1trXSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0JChlbCkuZGF0YSgnanN0cmVlJywgdG1wKTtcblx0XHR0bXAuaW5pdChlbCwgb3B0aW9ucyk7XG5cdFx0cmV0dXJuIHRtcDtcblx0fTtcblx0LyoqXG5cdCAqIHJlbW92ZSBhbGwgdHJhY2VzIG9mIGpzdHJlZSBmcm9tIHRoZSBET00gYW5kIGRlc3Ryb3kgYWxsIGluc3RhbmNlc1xuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZXN0cm95KClcblx0ICovXG5cdCQuanN0cmVlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG5cdFx0JCgnLmpzdHJlZTpqc3RyZWUnKS5qc3RyZWUoJ2Rlc3Ryb3knKTtcblx0XHQkKGRvY3VtZW50KS5vZmYoJy5qc3RyZWUnKTtcblx0fTtcblx0LyoqXG5cdCAqIHRoZSBqc3RyZWUgY2xhc3MgY29uc3RydWN0b3IsIHVzZWQgb25seSBpbnRlcm5hbGx5XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBuYW1lICQuanN0cmVlLmNvcmUoaWQpXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBpZCB0aGlzIGluc3RhbmNlJ3MgaW5kZXhcblx0ICovXG5cdCQuanN0cmVlLmNvcmUgPSBmdW5jdGlvbiAoaWQpIHtcblx0XHR0aGlzLl9pZCA9IGlkO1xuXHRcdHRoaXMuX2NudCA9IDA7XG5cdFx0dGhpcy5fd3JrID0gbnVsbDtcblx0XHR0aGlzLl9kYXRhID0ge1xuXHRcdFx0Y29yZSA6IHtcblx0XHRcdFx0dGhlbWVzIDoge1xuXHRcdFx0XHRcdG5hbWUgOiBmYWxzZSxcblx0XHRcdFx0XHRkb3RzIDogZmFsc2UsXG5cdFx0XHRcdFx0aWNvbnMgOiBmYWxzZSxcblx0XHRcdFx0XHRlbGxpcHNpcyA6IGZhbHNlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNlbGVjdGVkIDogW10sXG5cdFx0XHRcdGxhc3RfZXJyb3IgOiB7fSxcblx0XHRcdFx0d29ya2luZyA6IGZhbHNlLFxuXHRcdFx0XHR3b3JrZXJfcXVldWUgOiBbXSxcblx0XHRcdFx0Zm9jdXNlZCA6IG51bGxcblx0XHRcdH1cblx0XHR9O1xuXHR9O1xuXHQvKipcblx0ICogZ2V0IGEgcmVmZXJlbmNlIHRvIGFuIGV4aXN0aW5nIGluc3RhbmNlXG5cdCAqXG5cdCAqIF9fRXhhbXBsZXNfX1xuXHQgKlxuXHQgKlx0Ly8gcHJvdmlkZWQgYSBjb250YWluZXIgd2l0aCBhbiBJRCBvZiBcInRyZWVcIiwgYW5kIGEgbmVzdGVkIG5vZGUgd2l0aCBhbiBJRCBvZiBcImJyYW5jaFwiXG5cdCAqXHQvLyBhbGwgb2YgdGhlcmUgd2lsbCByZXR1cm4gdGhlIHNhbWUgaW5zdGFuY2Vcblx0ICpcdCQuanN0cmVlLnJlZmVyZW5jZSgndHJlZScpO1xuXHQgKlx0JC5qc3RyZWUucmVmZXJlbmNlKCcjdHJlZScpO1xuXHQgKlx0JC5qc3RyZWUucmVmZXJlbmNlKCQoJyN0cmVlJykpO1xuXHQgKlx0JC5qc3RyZWUucmVmZXJlbmNlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlEKCd0cmVlJykpO1xuXHQgKlx0JC5qc3RyZWUucmVmZXJlbmNlKCdicmFuY2gnKTtcblx0ICpcdCQuanN0cmVlLnJlZmVyZW5jZSgnI2JyYW5jaCcpO1xuXHQgKlx0JC5qc3RyZWUucmVmZXJlbmNlKCQoJyNicmFuY2gnKSk7XG5cdCAqXHQkLmpzdHJlZS5yZWZlcmVuY2UoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SUQoJ2JyYW5jaCcpKTtcblx0ICpcblx0ICogQG5hbWUgJC5qc3RyZWUucmVmZXJlbmNlKG5lZWRsZSlcblx0ICogQHBhcmFtIHtET01FbGVtZW50fGpRdWVyeXxTdHJpbmd9IG5lZWRsZVxuXHQgKiBAcmV0dXJuIHtqc1RyZWV8bnVsbH0gdGhlIGluc3RhbmNlIG9yIGBudWxsYCBpZiBub3QgZm91bmRcblx0ICovXG5cdCQuanN0cmVlLnJlZmVyZW5jZSA9IGZ1bmN0aW9uIChuZWVkbGUpIHtcblx0XHR2YXIgdG1wID0gbnVsbCxcblx0XHRcdG9iaiA9IG51bGw7XG5cdFx0aWYobmVlZGxlICYmIG5lZWRsZS5pZCAmJiAoIW5lZWRsZS50YWdOYW1lIHx8ICFuZWVkbGUubm9kZVR5cGUpKSB7IG5lZWRsZSA9IG5lZWRsZS5pZDsgfVxuXG5cdFx0aWYoIW9iaiB8fCAhb2JqLmxlbmd0aCkge1xuXHRcdFx0dHJ5IHsgb2JqID0gJChuZWVkbGUpOyB9IGNhdGNoIChpZ25vcmUpIHsgfVxuXHRcdH1cblx0XHRpZighb2JqIHx8ICFvYmoubGVuZ3RoKSB7XG5cdFx0XHR0cnkgeyBvYmogPSAkKCcjJyArIG5lZWRsZS5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpKTsgfSBjYXRjaCAoaWdub3JlKSB7IH1cblx0XHR9XG5cdFx0aWYob2JqICYmIG9iai5sZW5ndGggJiYgKG9iaiA9IG9iai5jbG9zZXN0KCcuanN0cmVlJykpLmxlbmd0aCAmJiAob2JqID0gb2JqLmRhdGEoJ2pzdHJlZScpKSkge1xuXHRcdFx0dG1wID0gb2JqO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdCQoJy5qc3RyZWUnKS5lYWNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dmFyIGluc3QgPSAkKHRoaXMpLmRhdGEoJ2pzdHJlZScpO1xuXHRcdFx0XHRpZihpbnN0ICYmIGluc3QuX21vZGVsLmRhdGFbbmVlZGxlXSkge1xuXHRcdFx0XHRcdHRtcCA9IGluc3Q7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIHRtcDtcblx0fTtcblx0LyoqXG5cdCAqIENyZWF0ZSBhbiBpbnN0YW5jZSwgZ2V0IGFuIGluc3RhbmNlIG9yIGludm9rZSBhIGNvbW1hbmQgb24gYSBpbnN0YW5jZS5cblx0ICpcblx0ICogSWYgdGhlcmUgaXMgbm8gaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IG5vZGUgYSBuZXcgb25lIGlzIGNyZWF0ZWQgYW5kIGBhcmdgIGlzIHVzZWQgdG8gZXh0ZW5kIGAkLmpzdHJlZS5kZWZhdWx0c2AgZm9yIHRoaXMgbmV3IGluc3RhbmNlLiBUaGVyZSB3b3VsZCBiZSBubyByZXR1cm4gdmFsdWUgKGNoYWluaW5nIGlzIG5vdCBicm9rZW4pLlxuXHQgKlxuXHQgKiBJZiB0aGVyZSBpcyBhbiBleGlzdGluZyBpbnN0YW5jZSBhbmQgYGFyZ2AgaXMgYSBzdHJpbmcgdGhlIGNvbW1hbmQgc3BlY2lmaWVkIGJ5IGBhcmdgIGlzIGV4ZWN1dGVkIG9uIHRoZSBpbnN0YW5jZSwgd2l0aCBhbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbi4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgYSB2YWx1ZSBpdCB3aWxsIGJlIHJldHVybmVkIChjaGFpbmluZyBjb3VsZCBicmVhayBkZXBlbmRpbmcgb24gZnVuY3Rpb24pLlxuXHQgKlxuXHQgKiBJZiB0aGVyZSBpcyBhbiBleGlzdGluZyBpbnN0YW5jZSBhbmQgYGFyZ2AgaXMgbm90IGEgc3RyaW5nIHRoZSBpbnN0YW5jZSBpdHNlbGYgaXMgcmV0dXJuZWQgKHNpbWlsYXIgdG8gYCQuanN0cmVlLnJlZmVyZW5jZWApLlxuXHQgKlxuXHQgKiBJbiBhbnkgb3RoZXIgY2FzZSAtIG5vdGhpbmcgaXMgcmV0dXJuZWQgYW5kIGNoYWluaW5nIGlzIG5vdCBicm9rZW4uXG5cdCAqXG5cdCAqIF9fRXhhbXBsZXNfX1xuXHQgKlxuXHQgKlx0JCgnI3RyZWUxJykuanN0cmVlKCk7IC8vIGNyZWF0ZXMgYW4gaW5zdGFuY2Vcblx0ICpcdCQoJyN0cmVlMicpLmpzdHJlZSh7IHBsdWdpbnMgOiBbXSB9KTsgLy8gY3JlYXRlIGFuIGluc3RhbmNlIHdpdGggc29tZSBvcHRpb25zXG5cdCAqXHQkKCcjdHJlZTEnKS5qc3RyZWUoJ29wZW5fbm9kZScsICcjYnJhbmNoXzEnKTsgLy8gY2FsbCBhIG1ldGhvZCBvbiBhbiBleGlzdGluZyBpbnN0YW5jZSwgcGFzc2luZyBhZGRpdGlvbmFsIGFyZ3VtZW50c1xuXHQgKlx0JCgnI3RyZWUyJykuanN0cmVlKCk7IC8vIGdldCBhbiBleGlzdGluZyBpbnN0YW5jZSAob3IgY3JlYXRlIGFuIGluc3RhbmNlKVxuXHQgKlx0JCgnI3RyZWUyJykuanN0cmVlKHRydWUpOyAvLyBnZXQgYW4gZXhpc3RpbmcgaW5zdGFuY2UgKHdpbGwgbm90IGNyZWF0ZSBuZXcgaW5zdGFuY2UpXG5cdCAqXHQkKCcjYnJhbmNoXzEnKS5qc3RyZWUoKS5zZWxlY3Rfbm9kZSgnI2JyYW5jaF8xJyk7IC8vIGdldCBhbiBpbnN0YW5jZSAodXNpbmcgYSBuZXN0ZWQgZWxlbWVudCBhbmQgY2FsbCBhIG1ldGhvZClcblx0ICpcblx0ICogQG5hbWUgJCgpLmpzdHJlZShbYXJnXSlcblx0ICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBhcmdcblx0ICogQHJldHVybiB7TWl4ZWR9XG5cdCAqL1xuXHQkLmZuLmpzdHJlZSA9IGZ1bmN0aW9uIChhcmcpIHtcblx0XHQvLyBjaGVjayBmb3Igc3RyaW5nIGFyZ3VtZW50XG5cdFx0dmFyIGlzX21ldGhvZFx0PSAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpLFxuXHRcdFx0YXJnc1x0XHQ9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG5cdFx0XHRyZXN1bHRcdFx0PSBudWxsO1xuXHRcdGlmKGFyZyA9PT0gdHJ1ZSAmJiAhdGhpcy5sZW5ndGgpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0dGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdC8vIGdldCB0aGUgaW5zdGFuY2UgKGlmIHRoZXJlIGlzIG9uZSkgYW5kIG1ldGhvZCAoaWYgaXQgZXhpc3RzKVxuXHRcdFx0dmFyIGluc3RhbmNlID0gJC5qc3RyZWUucmVmZXJlbmNlKHRoaXMpLFxuXHRcdFx0XHRtZXRob2QgPSBpc19tZXRob2QgJiYgaW5zdGFuY2UgPyBpbnN0YW5jZVthcmddIDogbnVsbDtcblx0XHRcdC8vIGlmIGNhbGxpbmcgYSBtZXRob2QsIGFuZCBtZXRob2QgaXMgYXZhaWxhYmxlIC0gZXhlY3V0ZSBvbiB0aGUgaW5zdGFuY2Vcblx0XHRcdHJlc3VsdCA9IGlzX21ldGhvZCAmJiBtZXRob2QgP1xuXHRcdFx0XHRtZXRob2QuYXBwbHkoaW5zdGFuY2UsIGFyZ3MpIDpcblx0XHRcdFx0bnVsbDtcblx0XHRcdC8vIGlmIHRoZXJlIGlzIG5vIGluc3RhbmNlIGFuZCBubyBtZXRob2QgaXMgYmVpbmcgY2FsbGVkIC0gY3JlYXRlIG9uZVxuXHRcdFx0aWYoIWluc3RhbmNlICYmICFpc19tZXRob2QgJiYgKGFyZyA9PT0gdW5kZWZpbmVkIHx8ICQuaXNQbGFpbk9iamVjdChhcmcpKSkge1xuXHRcdFx0XHQkLmpzdHJlZS5jcmVhdGUodGhpcywgYXJnKTtcblx0XHRcdH1cblx0XHRcdC8vIGlmIHRoZXJlIGlzIGFuIGluc3RhbmNlIGFuZCBubyBtZXRob2QgaXMgY2FsbGVkIC0gcmV0dXJuIHRoZSBpbnN0YW5jZVxuXHRcdFx0aWYoIChpbnN0YW5jZSAmJiAhaXNfbWV0aG9kKSB8fCBhcmcgPT09IHRydWUgKSB7XG5cdFx0XHRcdHJlc3VsdCA9IGluc3RhbmNlIHx8IGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0Ly8gaWYgdGhlcmUgd2FzIGEgbWV0aG9kIGNhbGwgd2hpY2ggcmV0dXJuZWQgYSByZXN1bHQgLSBicmVhayBhbmQgcmV0dXJuIHRoZSB2YWx1ZVxuXHRcdFx0aWYocmVzdWx0ICE9PSBudWxsICYmIHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHQvLyBpZiB0aGVyZSB3YXMgYSBtZXRob2QgY2FsbCB3aXRoIGEgdmFsaWQgcmV0dXJuIHZhbHVlIC0gcmV0dXJuIHRoYXQsIG90aGVyd2lzZSBjb250aW51ZSB0aGUgY2hhaW5cblx0XHRyZXR1cm4gcmVzdWx0ICE9PSBudWxsICYmIHJlc3VsdCAhPT0gdW5kZWZpbmVkID9cblx0XHRcdHJlc3VsdCA6IHRoaXM7XG5cdH07XG5cdC8qKlxuXHQgKiB1c2VkIHRvIGZpbmQgZWxlbWVudHMgY29udGFpbmluZyBhbiBpbnN0YW5jZVxuXHQgKlxuXHQgKiBfX0V4YW1wbGVzX19cblx0ICpcblx0ICpcdCQoJ2Rpdjpqc3RyZWUnKS5lYWNoKGZ1bmN0aW9uICgpIHtcblx0ICpcdFx0JCh0aGlzKS5qc3RyZWUoJ2Rlc3Ryb3knKTtcblx0ICpcdH0pO1xuXHQgKlxuXHQgKiBAbmFtZSAkKCc6anN0cmVlJylcblx0ICogQHJldHVybiB7alF1ZXJ5fVxuXHQgKi9cblx0JC5leHByLnBzZXVkb3MuanN0cmVlID0gJC5leHByLmNyZWF0ZVBzZXVkbyhmdW5jdGlvbihzZWFyY2gpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oYSkge1xuXHRcdFx0cmV0dXJuICQoYSkuaGFzQ2xhc3MoJ2pzdHJlZScpICYmXG5cdFx0XHRcdCQoYSkuZGF0YSgnanN0cmVlJykgIT09IHVuZGVmaW5lZDtcblx0XHR9O1xuXHR9KTtcblxuXHQvKipcblx0ICogc3RvcmVzIGFsbCBkZWZhdWx0cyBmb3IgdGhlIGNvcmVcblx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZVxuXHQgKi9cblx0JC5qc3RyZWUuZGVmYXVsdHMuY29yZSA9IHtcblx0XHQvKipcblx0XHQgKiBkYXRhIGNvbmZpZ3VyYXRpb25cblx0XHQgKlxuXHRcdCAqIElmIGxlZnQgYXMgYGZhbHNlYCB0aGUgSFRNTCBpbnNpZGUgdGhlIGpzdHJlZSBjb250YWluZXIgZWxlbWVudCBpcyB1c2VkIHRvIHBvcHVsYXRlIHRoZSB0cmVlICh0aGF0IHNob3VsZCBiZSBhbiB1bm9yZGVyZWQgbGlzdCB3aXRoIGxpc3QgaXRlbXMpLlxuXHRcdCAqXG5cdFx0ICogWW91IGNhbiBhbHNvIHBhc3MgaW4gYSBIVE1MIHN0cmluZyBvciBhIEpTT04gYXJyYXkgaGVyZS5cblx0XHQgKlxuXHRcdCAqIEl0IGlzIHBvc3NpYmxlIHRvIHBhc3MgaW4gYSBzdGFuZGFyZCBqUXVlcnktbGlrZSBBSkFYIGNvbmZpZyBhbmQganN0cmVlIHdpbGwgYXV0b21hdGljYWxseSBkZXRlcm1pbmUgaWYgdGhlIHJlc3BvbnNlIGlzIEpTT04gb3IgSFRNTCBhbmQgdXNlIHRoYXQgdG8gcG9wdWxhdGUgdGhlIHRyZWUuXG5cdFx0ICogSW4gYWRkaXRpb24gdG8gdGhlIHN0YW5kYXJkIGpRdWVyeSBhamF4IG9wdGlvbnMgaGVyZSB5b3UgY2FuIHN1cHBseSBmdW5jdGlvbnMgZm9yIGBkYXRhYCBhbmQgYHVybGAsIHRoZSBmdW5jdGlvbnMgd2lsbCBiZSBydW4gaW4gdGhlIGN1cnJlbnQgaW5zdGFuY2UncyBzY29wZSBhbmQgYSBwYXJhbSB3aWxsIGJlIHBhc3NlZCBpbmRpY2F0aW5nIHdoaWNoIG5vZGUgaXMgYmVpbmcgbG9hZGVkLCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRob3NlIGZ1bmN0aW9ucyB3aWxsIGJlIHVzZWQuXG5cdFx0ICpcblx0XHQgKiBUaGUgbGFzdCBvcHRpb24gaXMgdG8gc3BlY2lmeSBhIGZ1bmN0aW9uLCB0aGF0IGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgbm9kZSBiZWluZyBsb2FkZWQgYXMgYXJndW1lbnQgYW5kIGEgc2Vjb25kIHBhcmFtIHdoaWNoIGlzIGEgZnVuY3Rpb24gd2hpY2ggc2hvdWxkIGJlIGNhbGxlZCB3aXRoIHRoZSByZXN1bHQuXG5cdFx0ICpcblx0XHQgKiBfX0V4YW1wbGVzX19cblx0XHQgKlxuXHRcdCAqXHQvLyBBSkFYXG5cdFx0ICpcdCQoJyN0cmVlJykuanN0cmVlKHtcblx0XHQgKlx0XHQnY29yZScgOiB7XG5cdFx0ICpcdFx0XHQnZGF0YScgOiB7XG5cdFx0ICpcdFx0XHRcdCd1cmwnIDogJy9nZXQvY2hpbGRyZW4vJyxcblx0XHQgKlx0XHRcdFx0J2RhdGEnIDogZnVuY3Rpb24gKG5vZGUpIHtcblx0XHQgKlx0XHRcdFx0XHRyZXR1cm4geyAnaWQnIDogbm9kZS5pZCB9O1xuXHRcdCAqXHRcdFx0XHR9XG5cdFx0ICpcdFx0XHR9XG5cdFx0ICpcdFx0fSk7XG5cdFx0ICpcblx0XHQgKlx0Ly8gZGlyZWN0IGRhdGFcblx0XHQgKlx0JCgnI3RyZWUnKS5qc3RyZWUoe1xuXHRcdCAqXHRcdCdjb3JlJyA6IHtcblx0XHQgKlx0XHRcdCdkYXRhJyA6IFtcblx0XHQgKlx0XHRcdFx0J1NpbXBsZSByb290IG5vZGUnLFxuXHRcdCAqXHRcdFx0XHR7XG5cdFx0ICpcdFx0XHRcdFx0J2lkJyA6ICdub2RlXzInLFxuXHRcdCAqXHRcdFx0XHRcdCd0ZXh0JyA6ICdSb290IG5vZGUgd2l0aCBvcHRpb25zJyxcblx0XHQgKlx0XHRcdFx0XHQnc3RhdGUnIDogeyAnb3BlbmVkJyA6IHRydWUsICdzZWxlY3RlZCcgOiB0cnVlIH0sXG5cdFx0ICpcdFx0XHRcdFx0J2NoaWxkcmVuJyA6IFsgeyAndGV4dCcgOiAnQ2hpbGQgMScgfSwgJ0NoaWxkIDInXVxuXHRcdCAqXHRcdFx0XHR9XG5cdFx0ICpcdFx0XHRdXG5cdFx0ICpcdFx0fVxuXHRcdCAqXHR9KTtcblx0XHQgKlxuXHRcdCAqXHQvLyBmdW5jdGlvblxuXHRcdCAqXHQkKCcjdHJlZScpLmpzdHJlZSh7XG5cdFx0ICpcdFx0J2NvcmUnIDoge1xuXHRcdCAqXHRcdFx0J2RhdGEnIDogZnVuY3Rpb24gKG9iaiwgY2FsbGJhY2spIHtcblx0XHQgKlx0XHRcdFx0Y2FsbGJhY2suY2FsbCh0aGlzLCBbJ1Jvb3QgMScsICdSb290IDInXSk7XG5cdFx0ICpcdFx0XHR9XG5cdFx0ICpcdFx0fSk7XG5cdFx0ICpcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLmRhdGFcblx0XHQgKi9cblx0XHRkYXRhXHRcdFx0OiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBjb25maWd1cmUgdGhlIHZhcmlvdXMgc3RyaW5ncyB1c2VkIHRocm91Z2hvdXQgdGhlIHRyZWVcblx0XHQgKlxuXHRcdCAqIFlvdSBjYW4gdXNlIGFuIG9iamVjdCB3aGVyZSB0aGUga2V5IGlzIHRoZSBzdHJpbmcgeW91IG5lZWQgdG8gcmVwbGFjZSBhbmQgdGhlIHZhbHVlIGlzIHlvdXIgcmVwbGFjZW1lbnQuXG5cdFx0ICogQW5vdGhlciBvcHRpb24gaXMgdG8gc3BlY2lmeSBhIGZ1bmN0aW9uIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHdpdGggYW4gYXJndW1lbnQgb2YgdGhlIG5lZWRlZCBzdHJpbmcgYW5kIHNob3VsZCByZXR1cm4gdGhlIHJlcGxhY2VtZW50LlxuXHRcdCAqIElmIGxlZnQgYXMgYGZhbHNlYCBubyByZXBsYWNlbWVudCBpcyBtYWRlLlxuXHRcdCAqXG5cdFx0ICogX19FeGFtcGxlc19fXG5cdFx0ICpcblx0XHQgKlx0JCgnI3RyZWUnKS5qc3RyZWUoe1xuXHRcdCAqXHRcdCdjb3JlJyA6IHtcblx0XHQgKlx0XHRcdCdzdHJpbmdzJyA6IHtcblx0XHQgKlx0XHRcdFx0J0xvYWRpbmcgLi4uJyA6ICdQbGVhc2Ugd2FpdCAuLi4nXG5cdFx0ICpcdFx0XHR9XG5cdFx0ICpcdFx0fVxuXHRcdCAqXHR9KTtcblx0XHQgKlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUuc3RyaW5nc1xuXHRcdCAqL1xuXHRcdHN0cmluZ3NcdFx0XHQ6IGZhbHNlLFxuXHRcdC8qKlxuXHRcdCAqIGRldGVybWluZXMgd2hhdCBoYXBwZW5zIHdoZW4gYSB1c2VyIHRyaWVzIHRvIG1vZGlmeSB0aGUgc3RydWN0dXJlIG9mIHRoZSB0cmVlXG5cdFx0ICogSWYgbGVmdCBhcyBgZmFsc2VgIGFsbCBvcGVyYXRpb25zIGxpa2UgY3JlYXRlLCByZW5hbWUsIGRlbGV0ZSwgbW92ZSBvciBjb3B5IGFyZSBwcmV2ZW50ZWQuXG5cdFx0ICogWW91IGNhbiBzZXQgdGhpcyB0byBgdHJ1ZWAgdG8gYWxsb3cgYWxsIGludGVyYWN0aW9ucyBvciB1c2UgYSBmdW5jdGlvbiB0byBoYXZlIGJldHRlciBjb250cm9sLlxuXHRcdCAqXG5cdFx0ICogX19FeGFtcGxlc19fXG5cdFx0ICpcblx0XHQgKlx0JCgnI3RyZWUnKS5qc3RyZWUoe1xuXHRcdCAqXHRcdCdjb3JlJyA6IHtcblx0XHQgKlx0XHRcdCdjaGVja19jYWxsYmFjaycgOiBmdW5jdGlvbiAob3BlcmF0aW9uLCBub2RlLCBub2RlX3BhcmVudCwgbm9kZV9wb3NpdGlvbiwgbW9yZSkge1xuXHRcdCAqXHRcdFx0XHQvLyBvcGVyYXRpb24gY2FuIGJlICdjcmVhdGVfbm9kZScsICdyZW5hbWVfbm9kZScsICdkZWxldGVfbm9kZScsICdtb3ZlX25vZGUnLCAnY29weV9ub2RlJyBvciAnZWRpdCdcblx0XHQgKlx0XHRcdFx0Ly8gaW4gY2FzZSBvZiAncmVuYW1lX25vZGUnIG5vZGVfcG9zaXRpb24gaXMgZmlsbGVkIHdpdGggdGhlIG5ldyBub2RlIG5hbWVcblx0XHQgKlx0XHRcdFx0cmV0dXJuIG9wZXJhdGlvbiA9PT0gJ3JlbmFtZV9ub2RlJyA/IHRydWUgOiBmYWxzZTtcblx0XHQgKlx0XHRcdH1cblx0XHQgKlx0XHR9XG5cdFx0ICpcdH0pO1xuXHRcdCAqXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS5jaGVja19jYWxsYmFja1xuXHRcdCAqL1xuXHRcdGNoZWNrX2NhbGxiYWNrXHQ6IGZhbHNlLFxuXHRcdC8qKlxuXHRcdCAqIGEgY2FsbGJhY2sgY2FsbGVkIHdpdGggYSBzaW5nbGUgb2JqZWN0IHBhcmFtZXRlciBpbiB0aGUgaW5zdGFuY2UncyBzY29wZSB3aGVuIHNvbWV0aGluZyBnb2VzIHdyb25nIChvcGVyYXRpb24gcHJldmVudGVkLCBhamF4IGZhaWxlZCwgZXRjKVxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUuZXJyb3Jcblx0XHQgKi9cblx0XHRlcnJvclx0XHRcdDogJC5ub29wLFxuXHRcdC8qKlxuXHRcdCAqIHRoZSBvcGVuIC8gY2xvc2UgYW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyAtIHNldCB0aGlzIHRvIGBmYWxzZWAgdG8gZGlzYWJsZSB0aGUgYW5pbWF0aW9uIChkZWZhdWx0IGlzIGAyMDBgKVxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUuYW5pbWF0aW9uXG5cdFx0ICovXG5cdFx0YW5pbWF0aW9uXHRcdDogMjAwLFxuXHRcdC8qKlxuXHRcdCAqIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIG11bHRpcGxlIG5vZGVzIGNhbiBiZSBzZWxlY3RlZFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUubXVsdGlwbGVcblx0XHQgKi9cblx0XHRtdWx0aXBsZVx0XHQ6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogdGhlbWUgY29uZmlndXJhdGlvbiBvYmplY3Rcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLnRoZW1lc1xuXHRcdCAqL1xuXHRcdHRoZW1lc1x0XHRcdDoge1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0aGUgbmFtZSBvZiB0aGUgdGhlbWUgdG8gdXNlIChpZiBsZWZ0IGFzIGBmYWxzZWAgdGhlIGRlZmF1bHQgdGhlbWUgaXMgdXNlZClcblx0XHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUudGhlbWVzLm5hbWVcblx0XHRcdCAqL1xuXHRcdFx0bmFtZVx0XHRcdDogZmFsc2UsXG5cdFx0XHQvKipcblx0XHRcdCAqIHRoZSBVUkwgb2YgdGhlIHRoZW1lJ3MgQ1NTIGZpbGUsIGxlYXZlIHRoaXMgYXMgYGZhbHNlYCBpZiB5b3UgaGF2ZSBtYW51YWxseSBpbmNsdWRlZCB0aGUgdGhlbWUgQ1NTIChyZWNvbW1lbmRlZCkuIFlvdSBjYW4gc2V0IHRoaXMgdG8gYHRydWVgIHRvbyB3aGljaCB3aWxsIHRyeSB0byBhdXRvbG9hZCB0aGUgdGhlbWUuXG5cdFx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLnRoZW1lcy51cmxcblx0XHRcdCAqL1xuXHRcdFx0dXJsXHRcdFx0XHQ6IGZhbHNlLFxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0aGUgbG9jYXRpb24gb2YgYWxsIGpzdHJlZSB0aGVtZXMgLSBvbmx5IHVzZWQgaWYgYHVybGAgaXMgc2V0IHRvIGB0cnVlYFxuXHRcdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS50aGVtZXMuZGlyXG5cdFx0XHQgKi9cblx0XHRcdGRpclx0XHRcdFx0OiBmYWxzZSxcblx0XHRcdC8qKlxuXHRcdFx0ICogYSBib29sZWFuIGluZGljYXRpbmcgaWYgY29ubmVjdGluZyBkb3RzIGFyZSBzaG93blxuXHRcdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS50aGVtZXMuZG90c1xuXHRcdFx0ICovXG5cdFx0XHRkb3RzXHRcdFx0OiB0cnVlLFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBub2RlIGljb25zIGFyZSBzaG93blxuXHRcdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS50aGVtZXMuaWNvbnNcblx0XHRcdCAqL1xuXHRcdFx0aWNvbnNcdFx0XHQ6IHRydWUsXG5cdFx0XHQvKipcblx0XHRcdCAqIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIG5vZGUgZWxsaXBzaXMgc2hvdWxkIGJlIHNob3duIC0gdGhpcyBvbmx5IHdvcmtzIHdpdGggYSBmaXhlZCB3aXRoIG9uIHRoZSBjb250YWluZXJcblx0XHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUudGhlbWVzLmVsbGlwc2lzXG5cdFx0XHQgKi9cblx0XHRcdGVsbGlwc2lzXHRcdDogZmFsc2UsXG5cdFx0XHQvKipcblx0XHRcdCAqIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSB0cmVlIGJhY2tncm91bmQgaXMgc3RyaXBlZFxuXHRcdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS50aGVtZXMuc3RyaXBlc1xuXHRcdFx0ICovXG5cdFx0XHRzdHJpcGVzXHRcdFx0OiBmYWxzZSxcblx0XHRcdC8qKlxuXHRcdFx0ICogYSBzdHJpbmcgKG9yIGJvb2xlYW4gYGZhbHNlYCkgc3BlY2lmeWluZyB0aGUgdGhlbWUgdmFyaWFudCB0byB1c2UgKGlmIHRoZSB0aGVtZSBzdXBwb3J0cyB2YXJpYW50cylcblx0XHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUudGhlbWVzLnZhcmlhbnRcblx0XHRcdCAqL1xuXHRcdFx0dmFyaWFudFx0XHRcdDogZmFsc2UsXG5cdFx0XHQvKipcblx0XHRcdCAqIGEgYm9vbGVhbiBzcGVjaWZ5aW5nIGlmIGEgcmVwb25zaXZlIHZlcnNpb24gb2YgdGhlIHRoZW1lIHNob3VsZCBraWNrIGluIG9uIHNtYWxsZXIgc2NyZWVucyAoaWYgdGhlIHRoZW1lIHN1cHBvcnRzIGl0KS4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cblx0XHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUudGhlbWVzLnJlc3BvbnNpdmVcblx0XHRcdCAqL1xuXHRcdFx0cmVzcG9uc2l2ZVx0XHQ6IGZhbHNlXG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBpZiBsZWZ0IGFzIGB0cnVlYCBhbGwgcGFyZW50cyBvZiBhbGwgc2VsZWN0ZWQgbm9kZXMgd2lsbCBiZSBvcGVuZWQgb25jZSB0aGUgdHJlZSBsb2FkcyAoc28gdGhhdCBhbGwgc2VsZWN0ZWQgbm9kZXMgYXJlIHZpc2libGUgdG8gdGhlIHVzZXIpXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY29yZS5leHBhbmRfc2VsZWN0ZWRfb25sb2FkXG5cdFx0ICovXG5cdFx0ZXhwYW5kX3NlbGVjdGVkX29ubG9hZCA6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogaWYgbGVmdCBhcyBgdHJ1ZWAgd2ViIHdvcmtlcnMgd2lsbCBiZSB1c2VkIHRvIHBhcnNlIGluY29taW5nIEpTT04gZGF0YSB3aGVyZSBwb3NzaWJsZSwgc28gdGhhdCB0aGUgVUkgd2lsbCBub3QgYmUgYmxvY2tlZCBieSBsYXJnZSByZXF1ZXN0cy4gV29ya2VycyBhcmUgaG93ZXZlciBhYm91dCAzMCUgc2xvd2VyLiBEZWZhdWx0cyB0byBgdHJ1ZWBcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLndvcmtlclxuXHRcdCAqL1xuXHRcdHdvcmtlciA6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogRm9yY2Ugbm9kZSB0ZXh0IHRvIHBsYWluIHRleHQgKGFuZCBlc2NhcGUgSFRNTCkuIERlZmF1bHRzIHRvIGBmYWxzZWBcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLmZvcmNlX3RleHRcblx0XHQgKi9cblx0XHRmb3JjZV90ZXh0IDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogU2hvdWxkIHRoZSBub2RlIGJlIHRvZ2dsZWQgaWYgdGhlIHRleHQgaXMgZG91YmxlIGNsaWNrZWQuIERlZmF1bHRzIHRvIGB0cnVlYFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUuZGJsY2xpY2tfdG9nZ2xlXG5cdFx0ICovXG5cdFx0ZGJsY2xpY2tfdG9nZ2xlIDogdHJ1ZSxcblx0XHQvKipcblx0XHQgKiBTaG91bGQgdGhlIGxvYWRlZCBub2RlcyBiZSBwYXJ0IG9mIHRoZSBzdGF0ZS4gRGVmYXVsdHMgdG8gYGZhbHNlYFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUubG9hZGVkX3N0YXRlXG5cdFx0ICovXG5cdFx0bG9hZGVkX3N0YXRlIDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogU2hvdWxkIHRoZSBsYXN0IGFjdGl2ZSBub2RlIGJlIGZvY3VzZWQgd2hlbiB0aGUgdHJlZSBjb250YWluZXIgaXMgYmx1cnJlZCBhbmQgdGhlIGZvY3VzZWQgYWdhaW4uIFRoaXMgaGVscHMgd29ya2luZyB3aXRoIHNjcmVlbiByZWFkZXJzLiBEZWZhdWx0cyB0byBgdHJ1ZWBcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLnJlc3RvcmVfZm9jdXNcblx0XHQgKi9cblx0XHRyZXN0b3JlX2ZvY3VzIDogdHJ1ZSxcblx0XHQvKipcblx0XHQgKiBGb3JjZSB0byBjb21wdXRlIGFuZCBzZXQgXCJhcmlhLXNldHNpemVcIiBhbmQgXCJhcmlhLXBvc2luc2V0XCIgZXhwbGljaXRseSBmb3IgZWFjaCB0cmVlaXRlbS4gXG5cdFx0ICogU29tZSBicm93c2VycyBtYXkgY29tcHV0ZSBpbmNvcnJlY3QgZWxlbWVudHMgcG9zaXRpb24gYW5kIHByb2R1Y2Ugd3JvbmcgYW5ub3VuY2VtZW50cyBmb3Igc2NyZWVuIHJlYWRlcnMuIERlZmF1bHRzIHRvIGBmYWxzZWBcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLmNvbXB1dGVfZWxlbWVudHNfcG9zaXRpb25zXG5cdFx0ICovXG5cdFx0Y29tcHV0ZV9lbGVtZW50c19wb3NpdGlvbnMgOiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBEZWZhdWx0IGtleWJvYXJkIHNob3J0Y3V0cyAoYW4gb2JqZWN0IHdoZXJlIGVhY2gga2V5IGlzIHRoZSBidXR0b24gbmFtZSBvciBjb21ibyAtIGxpa2UgJ2VudGVyJywgJ2N0cmwtc3BhY2UnLCAncCcsIGV0YyBhbmQgdGhlIHZhbHVlIGlzIHRoZSBmdW5jdGlvbiB0byBleGVjdXRlIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlKVxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvcmUua2V5Ym9hcmRcblx0XHQgKi9cblx0XHRrZXlib2FyZCA6IHtcblx0XHRcdCdjdHJsLXNwYWNlJzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gYXJpYSBkZWZpbmVzIHNwYWNlIG9ubHkgd2l0aCBDdHJsXG5cdFx0XHRcdGUudHlwZSA9IFwiY2xpY2tcIjtcblx0XHRcdFx0JChlLmN1cnJlbnRUYXJnZXQpLnRyaWdnZXIoZSk7XG5cdFx0XHR9LFxuXHRcdFx0J2VudGVyJzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gZW50ZXJcblx0XHRcdFx0ZS50eXBlID0gXCJjbGlja1wiO1xuXHRcdFx0XHQkKGUuY3VycmVudFRhcmdldCkudHJpZ2dlcihlKTtcblx0XHRcdH0sXG5cdFx0XHQnbGVmdCc6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdC8vIGxlZnRcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZih0aGlzLmlzX29wZW4oZS5jdXJyZW50VGFyZ2V0KSkge1xuXHRcdFx0XHRcdHRoaXMuY2xvc2Vfbm9kZShlLmN1cnJlbnRUYXJnZXQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdHZhciBvID0gdGhpcy5nZXRfcGFyZW50KGUuY3VycmVudFRhcmdldCk7XG5cdFx0XHRcdFx0aWYobyAmJiBvLmlkICE9PSAkLmpzdHJlZS5yb290KSB7IHRoaXMuZ2V0X25vZGUobywgdHJ1ZSkuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykudHJpZ2dlcignZm9jdXMnKTsgfVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0J3VwJzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gdXBcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR2YXIgbyA9IHRoaXMuZ2V0X3ByZXZfZG9tKGUuY3VycmVudFRhcmdldCk7XG5cdFx0XHRcdGlmKG8gJiYgby5sZW5ndGgpIHsgby5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS50cmlnZ2VyKCdmb2N1cycpOyB9XG5cdFx0XHR9LFxuXHRcdFx0J3JpZ2h0JzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gcmlnaHRcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZih0aGlzLmlzX2Nsb3NlZChlLmN1cnJlbnRUYXJnZXQpKSB7XG5cdFx0XHRcdFx0dGhpcy5vcGVuX25vZGUoZS5jdXJyZW50VGFyZ2V0LCBmdW5jdGlvbiAobykgeyB0aGlzLmdldF9ub2RlKG8sIHRydWUpLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLnRyaWdnZXIoJ2ZvY3VzJyk7IH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2UgaWYgKHRoaXMuaXNfb3BlbihlLmN1cnJlbnRUYXJnZXQpKSB7XG5cdFx0XHRcdFx0dmFyIG8gPSB0aGlzLmdldF9ub2RlKGUuY3VycmVudFRhcmdldCwgdHJ1ZSkuY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKVswXTtcblx0XHRcdFx0XHRpZihvKSB7ICQodGhpcy5fZmlyc3RDaGlsZChvKSkuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykudHJpZ2dlcignZm9jdXMnKTsgfVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0J2Rvd24nOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHQvLyBkb3duXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0dmFyIG8gPSB0aGlzLmdldF9uZXh0X2RvbShlLmN1cnJlbnRUYXJnZXQpO1xuXHRcdFx0XHRpZihvICYmIG8ubGVuZ3RoKSB7IG8uY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykudHJpZ2dlcignZm9jdXMnKTsgfVxuXHRcdFx0fSxcblx0XHRcdCcqJzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gYXJpYSBkZWZpbmVzICogb24gbnVtcGFkIGFzIG9wZW5fYWxsIC0gbm90IHZlcnkgY29tbW9uXG5cdFx0XHRcdHRoaXMub3Blbl9hbGwoKTtcblx0XHRcdH0sXG5cdFx0XHQnaG9tZSc6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdC8vIGhvbWVcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR2YXIgbyA9IHRoaXMuX2ZpcnN0Q2hpbGQodGhpcy5nZXRfY29udGFpbmVyX3VsKClbMF0pO1xuXHRcdFx0XHRpZihvKSB7ICQobykuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykuZmlsdGVyKCc6dmlzaWJsZScpLnRyaWdnZXIoJ2ZvY3VzJyk7IH1cblx0XHRcdH0sXG5cdFx0XHQnZW5kJzogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0Ly8gZW5kXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0dGhpcy5lbGVtZW50LmZpbmQoJy5qc3RyZWUtYW5jaG9yJykuZmlsdGVyKCc6dmlzaWJsZScpLmxhc3QoKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0fSxcblx0XHRcdCdmMic6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdC8vIGYyIC0gc2FmZSB0byBpbmNsdWRlIC0gaWYgY2hlY2tfY2FsbGJhY2sgaXMgZmFsc2UgaXQgd2lsbCBmYWlsXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0dGhpcy5lZGl0KGUuY3VycmVudFRhcmdldCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXHQkLmpzdHJlZS5jb3JlLnByb3RvdHlwZSA9IHtcblx0XHQvKipcblx0XHQgKiB1c2VkIHRvIGRlY29yYXRlIGFuIGluc3RhbmNlIHdpdGggYSBwbHVnaW4uIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIHBsdWdpbihkZWNvIFssIG9wdHNdKVxuXHRcdCAqIEBwYXJhbSAge1N0cmluZ30gZGVjbyB0aGUgcGx1Z2luIHRvIGRlY29yYXRlIHdpdGhcblx0XHQgKiBAcGFyYW0gIHtPYmplY3R9IG9wdHMgb3B0aW9ucyBmb3IgdGhlIHBsdWdpblxuXHRcdCAqIEByZXR1cm4ge2pzVHJlZX1cblx0XHQgKi9cblx0XHRwbHVnaW4gOiBmdW5jdGlvbiAoZGVjbywgb3B0cykge1xuXHRcdFx0dmFyIENoaWxkID0gJC5qc3RyZWUucGx1Z2luc1tkZWNvXTtcblx0XHRcdGlmKENoaWxkKSB7XG5cdFx0XHRcdHRoaXMuX2RhdGFbZGVjb10gPSB7fTtcblx0XHRcdFx0Q2hpbGQucHJvdG90eXBlID0gdGhpcztcblx0XHRcdFx0cmV0dXJuIG5ldyBDaGlsZChvcHRzLCB0aGlzKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogaW5pdGlhbGl6ZSB0aGUgaW5zdGFuY2UuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIGluaXQoZWwsIG9wdG9ucylcblx0XHQgKiBAcGFyYW0ge0RPTUVsZW1lbnR8alF1ZXJ5fFN0cmluZ30gZWwgdGhlIGVsZW1lbnQgd2UgYXJlIHRyYW5zZm9ybWluZ1xuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIG9wdGlvbnMgZm9yIHRoaXMgaW5zdGFuY2Vcblx0XHQgKiBAdHJpZ2dlciBpbml0LmpzdHJlZSwgbG9hZGluZy5qc3RyZWUsIGxvYWRlZC5qc3RyZWUsIHJlYWR5LmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRpbml0IDogZnVuY3Rpb24gKGVsLCBvcHRpb25zKSB7XG5cdFx0XHR0aGlzLl9tb2RlbCA9IHtcblx0XHRcdFx0ZGF0YSA6IHt9LFxuXHRcdFx0XHRjaGFuZ2VkIDogW10sXG5cdFx0XHRcdGZvcmNlX2Z1bGxfcmVkcmF3IDogZmFsc2UsXG5cdFx0XHRcdHJlZHJhd190aW1lb3V0IDogZmFsc2UsXG5cdFx0XHRcdGRlZmF1bHRfc3RhdGUgOiB7XG5cdFx0XHRcdFx0bG9hZGVkIDogdHJ1ZSxcblx0XHRcdFx0XHRvcGVuZWQgOiBmYWxzZSxcblx0XHRcdFx0XHRzZWxlY3RlZCA6IGZhbHNlLFxuXHRcdFx0XHRcdGRpc2FibGVkIDogZmFsc2Vcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdHRoaXMuX21vZGVsLmRhdGFbJC5qc3RyZWUucm9vdF0gPSB7XG5cdFx0XHRcdGlkIDogJC5qc3RyZWUucm9vdCxcblx0XHRcdFx0cGFyZW50IDogbnVsbCxcblx0XHRcdFx0cGFyZW50cyA6IFtdLFxuXHRcdFx0XHRjaGlsZHJlbiA6IFtdLFxuXHRcdFx0XHRjaGlsZHJlbl9kIDogW10sXG5cdFx0XHRcdHN0YXRlIDogeyBsb2FkZWQgOiBmYWxzZSB9XG5cdFx0XHR9O1xuXG5cdFx0XHR0aGlzLmVsZW1lbnQgPSAkKGVsKS5hZGRDbGFzcygnanN0cmVlIGpzdHJlZS0nICsgdGhpcy5faWQpO1xuXHRcdFx0dGhpcy5zZXR0aW5ncyA9IG9wdGlvbnM7XG5cblx0XHRcdHRoaXMuX2RhdGEuY29yZS5yZWFkeSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxvYWRlZCA9IGZhbHNlO1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnJ0bCA9ICh0aGlzLmVsZW1lbnQuY3NzKFwiZGlyZWN0aW9uXCIpID09PSBcInJ0bFwiKTtcblx0XHRcdHRoaXMuZWxlbWVudFt0aGlzLl9kYXRhLmNvcmUucnRsID8gJ2FkZENsYXNzJyA6ICdyZW1vdmVDbGFzcyddKFwianN0cmVlLXJ0bFwiKTtcblx0XHRcdHRoaXMuZWxlbWVudC5hdHRyKCdyb2xlJywndHJlZScpO1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jb3JlLm11bHRpcGxlKSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudC5hdHRyKCdhcmlhLW11bHRpc2VsZWN0YWJsZScsIHRydWUpO1xuXHRcdFx0fVxuXHRcdFx0aWYoIXRoaXMuZWxlbWVudC5hdHRyKCd0YWJpbmRleCcpKSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudC5hdHRyKCd0YWJpbmRleCcsJzAnKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5iaW5kKCk7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCBhZnRlciBhbGwgZXZlbnRzIGFyZSBib3VuZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBpbml0LmpzdHJlZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoXCJpbml0XCIpO1xuXG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUub3JpZ2luYWxfY29udGFpbmVyX2h0bWwgPSB0aGlzLmVsZW1lbnQuZmluZChcIiA+IHVsID4gbGlcIikuY2xvbmUodHJ1ZSk7XG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUub3JpZ2luYWxfY29udGFpbmVyX2h0bWxcblx0XHRcdFx0LmZpbmQoXCJsaVwiKS5hZGRCYWNrKClcblx0XHRcdFx0LmNvbnRlbnRzKCkuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLm5vZGVUeXBlID09PSAzICYmICghdGhpcy5ub2RlVmFsdWUgfHwgL15cXHMrJC8udGVzdCh0aGlzLm5vZGVWYWx1ZSkpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQucmVtb3ZlKCk7XG5cdFx0XHR0aGlzLmVsZW1lbnQuaHRtbChcIjxcIitcInVsIGNsYXNzPSdqc3RyZWUtY29udGFpbmVyLXVsIGpzdHJlZS1jaGlsZHJlbicgcm9sZT0nZ3JvdXAnPjxcIitcImxpIGlkPSdqXCIrdGhpcy5faWQrXCJfbG9hZGluZycgY2xhc3M9J2pzdHJlZS1pbml0aWFsLW5vZGUganN0cmVlLWxvYWRpbmcganN0cmVlLWxlYWYganN0cmVlLWxhc3QnIHJvbGU9J25vbmUnPjxpIGNsYXNzPSdqc3RyZWUtaWNvbiBqc3RyZWUtb2NsJz48L2k+PFwiK1wiYSBjbGFzcz0nanN0cmVlLWFuY2hvcicgcm9sZT0ndHJlZWl0ZW0nIGhyZWY9JyMnPjxpIGNsYXNzPSdqc3RyZWUtaWNvbiBqc3RyZWUtdGhlbWVpY29uLWhpZGRlbic+PC9pPlwiICsgdGhpcy5nZXRfc3RyaW5nKFwiTG9hZGluZyAuLi5cIikgKyBcIjwvYT48L2xpPjwvdWw+XCIpO1xuXHRcdFx0dGhpcy5lbGVtZW50LmF0dHIoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcsJ2onICsgdGhpcy5faWQgKyAnX2xvYWRpbmcnKTtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS5saV9oZWlnaHQgPSB0aGlzLmdldF9jb250YWluZXJfdWwoKS5jaGlsZHJlbihcImxpXCIpLmZpcnN0KCkub3V0ZXJIZWlnaHQoKSB8fCAyNDtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS5ub2RlID0gdGhpcy5fY3JlYXRlX3Byb3RvdHlwZV9ub2RlKCk7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCBhZnRlciB0aGUgbG9hZGluZyB0ZXh0IGlzIHNob3duIGFuZCBiZWZvcmUgbG9hZGluZyBzdGFydHNcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgbG9hZGluZy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKFwibG9hZGluZ1wiKTtcblx0XHRcdHRoaXMubG9hZF9ub2RlKCQuanN0cmVlLnJvb3QpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZGVzdHJveSBhbiBpbnN0YW5jZVxuXHRcdCAqIEBuYW1lIGRlc3Ryb3koKVxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IGtlZXBfaHRtbCBpZiBub3Qgc2V0IHRvIGB0cnVlYCB0aGUgY29udGFpbmVyIHdpbGwgYmUgZW1wdGllZCwgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IERPTSBlbGVtZW50cyB3aWxsIGJlIGtlcHQgaW50YWN0XG5cdFx0ICovXG5cdFx0ZGVzdHJveSA6IGZ1bmN0aW9uIChrZWVwX2h0bWwpIHtcblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIGJlZm9yZSB0aGUgdHJlZSBpcyBkZXN0cm95ZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgZGVzdHJveS5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKFwiZGVzdHJveVwiKTtcblx0XHRcdGlmKHRoaXMuX3dyaykge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHRoaXMuX3dyayk7XG5cdFx0XHRcdFx0dGhpcy5fd3JrID0gbnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0XHRjYXRjaCAoaWdub3JlKSB7IH1cblx0XHRcdH1cblx0XHRcdGlmKCFrZWVwX2h0bWwpIHsgdGhpcy5lbGVtZW50LmVtcHR5KCk7IH1cblx0XHRcdHRoaXMudGVhcmRvd24oKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIENyZWF0ZSBhIHByb3RvdHlwZSBub2RlXG5cdFx0ICogQG5hbWUgX2NyZWF0ZV9wcm90b3R5cGVfbm9kZSgpXG5cdFx0ICogQHJldHVybiB7RE9NRWxlbWVudH1cblx0XHQgKi9cblx0XHRfY3JlYXRlX3Byb3RvdHlwZV9ub2RlIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIF9ub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnTEknKSwgX3RlbXAxLCBfdGVtcDI7XG5cdFx0XHRfbm9kZS5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnbm9uZScpO1xuXHRcdFx0X3RlbXAxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnSScpO1xuXHRcdFx0X3RlbXAxLmNsYXNzTmFtZSA9ICdqc3RyZWUtaWNvbiBqc3RyZWUtb2NsJztcblx0XHRcdF90ZW1wMS5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAncHJlc2VudGF0aW9uJyk7XG5cdFx0XHRfbm9kZS5hcHBlbmRDaGlsZChfdGVtcDEpO1xuXHRcdFx0X3RlbXAxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnQScpO1xuXHRcdFx0X3RlbXAxLmNsYXNzTmFtZSA9ICdqc3RyZWUtYW5jaG9yJztcblx0XHRcdF90ZW1wMS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCcjJyk7XG5cdFx0XHRfdGVtcDEuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsJy0xJyk7XG5cdFx0XHRfdGVtcDEuc2V0QXR0cmlidXRlKCdyb2xlJywgJ3RyZWVpdGVtJyk7XG5cdFx0XHRfdGVtcDIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdJJyk7XG5cdFx0XHRfdGVtcDIuY2xhc3NOYW1lID0gJ2pzdHJlZS1pY29uIGpzdHJlZS10aGVtZWljb24nO1xuXHRcdFx0X3RlbXAyLnNldEF0dHJpYnV0ZSgncm9sZScsICdwcmVzZW50YXRpb24nKTtcblx0XHRcdF90ZW1wMS5hcHBlbmRDaGlsZChfdGVtcDIpO1xuXHRcdFx0X25vZGUuYXBwZW5kQ2hpbGQoX3RlbXAxKTtcblx0XHRcdF90ZW1wMSA9IF90ZW1wMiA9IG51bGw7XG5cblx0XHRcdHJldHVybiBfbm9kZTtcblx0XHR9LFxuXHRcdF9rYmV2ZW50X3RvX2Z1bmMgOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0dmFyIGtleXMgPSB7XG5cdFx0XHRcdDg6IFwiQmFja3NwYWNlXCIsIDk6IFwiVGFiXCIsIDEzOiBcIkVudGVyXCIsIDE5OiBcIlBhdXNlXCIsIDI3OiBcIkVzY1wiLFxuXHRcdFx0XHQzMjogXCJTcGFjZVwiLCAzMzogXCJQYWdlVXBcIiwgMzQ6IFwiUGFnZURvd25cIiwgMzU6IFwiRW5kXCIsIDM2OiBcIkhvbWVcIixcblx0XHRcdFx0Mzc6IFwiTGVmdFwiLCAzODogXCJVcFwiLCAzOTogXCJSaWdodFwiLCA0MDogXCJEb3duXCIsIDQ0OiBcIlByaW50XCIsIDQ1OiBcIkluc2VydFwiLFxuXHRcdFx0XHQ0NjogXCJEZWxldGVcIiwgOTY6IFwiTnVtcGFkMFwiLCA5NzogXCJOdW1wYWQxXCIsIDk4OiBcIk51bXBhZDJcIiwgOTkgOiBcIk51bXBhZDNcIixcblx0XHRcdFx0MTAwOiBcIk51bXBhZDRcIiwgMTAxOiBcIk51bXBhZDVcIiwgMTAyOiBcIk51bXBhZDZcIiwgMTAzOiBcIk51bXBhZDdcIixcblx0XHRcdFx0MTA0OiBcIk51bXBhZDhcIiwgMTA1OiBcIk51bXBhZDlcIiwgJy0xMyc6IFwiTnVtcGFkRW50ZXJcIiwgMTEyOiBcIkYxXCIsXG5cdFx0XHRcdDExMzogXCJGMlwiLCAxMTQ6IFwiRjNcIiwgMTE1OiBcIkY0XCIsIDExNjogXCJGNVwiLCAxMTc6IFwiRjZcIiwgMTE4OiBcIkY3XCIsXG5cdFx0XHRcdDExOTogXCJGOFwiLCAxMjA6IFwiRjlcIiwgMTIxOiBcIkYxMFwiLCAxMjI6IFwiRjExXCIsIDEyMzogXCJGMTJcIiwgMTQ0OiBcIk51bWxvY2tcIixcblx0XHRcdFx0MTQ1OiBcIlNjcm9sbGxvY2tcIiwgMTY6ICdTaGlmdCcsIDE3OiAnQ3RybCcsIDE4OiAnQWx0Jyxcblx0XHRcdFx0NDg6ICcwJywgIDQ5OiAnMScsICA1MDogJzInLCAgNTE6ICczJywgIDUyOiAnNCcsIDUzOiAgJzUnLFxuXHRcdFx0XHQ1NDogJzYnLCAgNTU6ICc3JywgIDU2OiAnOCcsICA1NzogJzknLCAgNTk6ICc7JywgIDYxOiAnPScsIDY1OiAgJ2EnLFxuXHRcdFx0XHQ2NjogJ2InLCAgNjc6ICdjJywgIDY4OiAnZCcsICA2OTogJ2UnLCAgNzA6ICdmJywgIDcxOiAnZycsIDcyOiAgJ2gnLFxuXHRcdFx0XHQ3MzogJ2knLCAgNzQ6ICdqJywgIDc1OiAnaycsICA3NjogJ2wnLCAgNzc6ICdtJywgIDc4OiAnbicsIDc5OiAgJ28nLFxuXHRcdFx0XHQ4MDogJ3AnLCAgODE6ICdxJywgIDgyOiAncicsICA4MzogJ3MnLCAgODQ6ICd0JywgIDg1OiAndScsIDg2OiAgJ3YnLFxuXHRcdFx0XHQ4NzogJ3cnLCAgODg6ICd4JywgIDg5OiAneScsICA5MDogJ3onLCAxMDc6ICcrJywgMTA5OiAnLScsIDExMDogJy4nLFxuXHRcdFx0XHQxODY6ICc7JywgMTg3OiAnPScsIDE4ODogJywnLCAxODk6ICctJywgMTkwOiAnLicsIDE5MTogJy8nLCAxOTI6ICdgJyxcblx0XHRcdFx0MjE5OiAnWycsIDIyMDogJ1xcXFwnLDIyMTogJ10nLCAyMjI6IFwiJ1wiLCAxMTE6ICcvJywgMTA2OiAnKicsIDE3MzogJy0nXG5cdFx0XHR9O1xuXHRcdFx0dmFyIHBhcnRzID0gW107XG5cdFx0XHRpZiAoZS5jdHJsS2V5KSB7IHBhcnRzLnB1c2goJ2N0cmwnKTsgfVxuXHRcdFx0aWYgKGUuYWx0S2V5KSB7IHBhcnRzLnB1c2goJ2FsdCcpOyB9XG4gICAgICAgICAgICBpZiAoZS5zaGlmdEtleSkgeyBwYXJ0cy5wdXNoKCdzaGlmdCcpOyB9XG5cdFx0XHRwYXJ0cy5wdXNoKGtleXNbZS53aGljaF0gPyBrZXlzW2Uud2hpY2hdLnRvTG93ZXJDYXNlKCkgOiBlLndoaWNoKTtcbiAgICAgICAgICAgIHBhcnRzID0gcGFydHMuc29ydCgpLmpvaW4oJy0nKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgaWYgKHBhcnRzID09PSAnc2hpZnQtc2hpZnQnIHx8IHBhcnRzID09PSAnY3RybC1jdHJsJyB8fCBwYXJ0cyA9PT0gJ2FsdC1hbHQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cblx0XHRcdHZhciBrYiA9IHRoaXMuc2V0dGluZ3MuY29yZS5rZXlib2FyZCwgaSwgdG1wO1xuXHRcdFx0Zm9yIChpIGluIGtiKSB7XG5cdFx0XHRcdGlmIChrYi5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdHRtcCA9IGk7XG5cdFx0XHRcdFx0aWYgKHRtcCAhPT0gJy0nICYmIHRtcCAhPT0gJysnKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSB0bXAucmVwbGFjZSgnLS0nLCAnLU1JTlVTJykucmVwbGFjZSgnKy0nLCAnLU1JTlVTJykucmVwbGFjZSgnKysnLCAnLVBMVVMnKS5yZXBsYWNlKCctKycsICctUExVUycpO1xuXHRcdFx0XHRcdFx0dG1wID0gdG1wLnNwbGl0KC8tfFxcKy8pLnNvcnQoKS5qb2luKCctJykucmVwbGFjZSgnTUlOVVMnLCAnLScpLnJlcGxhY2UoJ1BMVVMnLCAnKycpLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0bXAgPT09IHBhcnRzKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4ga2JbaV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHBhcnQgb2YgdGhlIGRlc3Ryb3lpbmcgb2YgYW4gaW5zdGFuY2UuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIHRlYXJkb3duKClcblx0XHQgKi9cblx0XHR0ZWFyZG93biA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMudW5iaW5kKCk7XG5cdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0LnJlbW92ZUNsYXNzKCdqc3RyZWUnKVxuXHRcdFx0XHQucmVtb3ZlRGF0YSgnanN0cmVlJylcblx0XHRcdFx0LmZpbmQoXCJbY2xhc3NePSdqc3RyZWUnXVwiKVxuXHRcdFx0XHRcdC5hZGRCYWNrKClcblx0XHRcdFx0XHQuYXR0cihcImNsYXNzXCIsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuY2xhc3NOYW1lLnJlcGxhY2UoL2pzdHJlZVteIF0qfCQvaWcsJycpOyB9KTtcblx0XHRcdHRoaXMuZWxlbWVudCA9IG51bGw7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBiaW5kIGFsbCBldmVudHMuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIGJpbmQoKVxuXHRcdCAqL1xuXHRcdGJpbmQgOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgd29yZCA9ICcnLFxuXHRcdFx0XHR0b3V0ID0gbnVsbCxcblx0XHRcdFx0d2FzX2NsaWNrID0gMDtcblx0XHRcdHRoaXMuZWxlbWVudFxuXHRcdFx0XHQub24oXCJkYmxjbGljay5qc3RyZWVcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGlmKGUudGFyZ2V0LnRhZ05hbWUgJiYgZS50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRcdFx0XHRcdGlmKGRvY3VtZW50LnNlbGVjdGlvbiAmJiBkb2N1bWVudC5zZWxlY3Rpb24uZW1wdHkpIHtcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuc2VsZWN0aW9uLmVtcHR5KCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0aWYod2luZG93LmdldFNlbGVjdGlvbikge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBzZWwgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cdFx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRcdHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcblx0XHRcdFx0XHRcdFx0XHRcdHNlbC5jb2xsYXBzZSgpO1xuXHRcdFx0XHRcdFx0XHRcdH0gY2F0Y2ggKGlnbm9yZSkgeyB9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0XHQub24oXCJtb3VzZWRvd24uanN0cmVlXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZihlLnRhcmdldCA9PT0gdGhpcy5lbGVtZW50WzBdKSB7XG5cdFx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTsgLy8gcHJldmVudCBsb3NpbmcgZm9jdXMgd2hlbiBjbGlja2luZyBzY3JvbGwgYXJyb3dzIChGRiwgQ2hyb21lKVxuXHRcdFx0XHRcdFx0XHR3YXNfY2xpY2sgPSArKG5ldyBEYXRlKCkpOyAvLyBpZSBkb2VzIG5vdCBhbGxvdyB0byBwcmV2ZW50IGxvc2luZyBmb2N1c1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0Lm9uKFwibW91c2Vkb3duLmpzdHJlZVwiLCBcIi5qc3RyZWUtb2NsXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7IC8vIHByZXZlbnQgYW55IG5vZGUgaW5zaWRlIGZyb20gbG9zaW5nIGZvY3VzIHdoZW4gY2xpY2tpbmcgdGhlIG9wZW4vY2xvc2UgaWNvblxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdC5vbihcImNsaWNrLmpzdHJlZVwiLCBcIi5qc3RyZWUtb2NsXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRvZ2dsZV9ub2RlKGUudGFyZ2V0KTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbihcImRibGNsaWNrLmpzdHJlZVwiLCBcIi5qc3RyZWUtYW5jaG9yXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZihlLnRhcmdldC50YWdOYW1lICYmIGUudGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0XHRcdFx0XHRpZih0aGlzLnNldHRpbmdzLmNvcmUuZGJsY2xpY2tfdG9nZ2xlKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMudG9nZ2xlX25vZGUoZS50YXJnZXQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0Lm9uKFwiY2xpY2suanN0cmVlXCIsIFwiLmpzdHJlZS1hbmNob3JcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdGlmKGUuY3VycmVudFRhcmdldCAhPT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkgeyAkKGUuY3VycmVudFRhcmdldCkudHJpZ2dlcignZm9jdXMnKTsgfVxuXHRcdFx0XHRcdFx0dGhpcy5hY3RpdmF0ZV9ub2RlKGUuY3VycmVudFRhcmdldCwgZSk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oJ2tleWRvd24uanN0cmVlJywgJy5qc3RyZWUtYW5jaG9yJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGlmKGUudGFyZ2V0LnRhZ05hbWUgJiYgZS50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRcdFx0XHRcdGlmKHRoaXMuX2RhdGEuY29yZS5ydGwpIHtcblx0XHRcdFx0XHRcdFx0aWYoZS53aGljaCA9PT0gMzcpIHsgZS53aGljaCA9IDM5OyB9XG5cdFx0XHRcdFx0XHRcdGVsc2UgaWYoZS53aGljaCA9PT0gMzkpIHsgZS53aGljaCA9IDM3OyB9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR2YXIgZiA9IHRoaXMuX2tiZXZlbnRfdG9fZnVuYyhlKTtcblx0XHRcdFx0XHRcdGlmIChmKSB7XG5cdFx0XHRcdFx0XHRcdHZhciByID0gZi5jYWxsKHRoaXMsIGUpO1xuXHRcdFx0XHRcdFx0XHRpZiAociA9PT0gZmFsc2UgfHwgciA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJsb2FkX25vZGUuanN0cmVlXCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHRpZihkYXRhLnN0YXR1cykge1xuXHRcdFx0XHRcdFx0XHRpZihkYXRhLm5vZGUuaWQgPT09ICQuanN0cmVlLnJvb3QgJiYgIXRoaXMuX2RhdGEuY29yZS5sb2FkZWQpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubG9hZGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRpZih0aGlzLl9maXJzdENoaWxkKHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpWzBdKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LmF0dHIoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcsdGhpcy5fZmlyc3RDaGlsZCh0aGlzLmdldF9jb250YWluZXJfdWwoKVswXSkuaWQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHRcdFx0XHQgKiB0cmlnZ2VyZWQgYWZ0ZXIgdGhlIHJvb3Qgbm9kZSBpcyBsb2FkZWQgZm9yIHRoZSBmaXJzdCB0aW1lXG5cdFx0XHRcdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0XHRcdFx0ICogQG5hbWUgbG9hZGVkLmpzdHJlZVxuXHRcdFx0XHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMudHJpZ2dlcihcImxvYWRlZFwiKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZighdGhpcy5fZGF0YS5jb3JlLnJlYWR5KSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKHRoaXMuZWxlbWVudCAmJiAhdGhpcy5nZXRfY29udGFpbmVyX3VsKCkuZmluZCgnLmpzdHJlZS1sb2FkaW5nJykubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5yZWFkeSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZih0aGlzLnNldHRpbmdzLmNvcmUuZXhwYW5kX3NlbGVjdGVkX29ubG9hZCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dmFyIHRtcCA9IFtdLCBpLCBqO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0bXAuY29uY2F0KHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldXS5wYXJlbnRzKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRtcCA9ICQudmFrYXRhLmFycmF5X3VuaXF1ZSh0bXApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gdG1wLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLm9wZW5fbm9kZSh0bXBbaV0sIGZhbHNlLCAwKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy50cmlnZ2VyKCdjaGFuZ2VkJywgeyAnYWN0aW9uJyA6ICdyZWFkeScsICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQgfSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0LyoqXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCAqIHRyaWdnZXJlZCBhZnRlciBhbGwgbm9kZXMgYXJlIGZpbmlzaGVkIGxvYWRpbmdcblx0XHRcdFx0XHRcdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0XHRcdFx0XHRcdCAqIEBuYW1lIHJlYWR5LmpzdHJlZVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy50cmlnZ2VyKFwicmVhZHlcIik7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpLCAwKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0Ly8gcXVpY2sgc2VhcmNoaW5nIHdoZW4gdGhlIHRyZWUgaXMgZm9jdXNlZFxuXHRcdFx0XHQub24oJ2tleXByZXNzLmpzdHJlZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZihlLnRhcmdldC50YWdOYW1lICYmIGUudGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0XHRcdFx0XHRpZih0b3V0KSB7IGNsZWFyVGltZW91dCh0b3V0KTsgfVxuXHRcdFx0XHRcdFx0dG91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHR3b3JkID0gJyc7XG5cdFx0XHRcdFx0XHR9LCA1MDApO1xuXG5cdFx0XHRcdFx0XHR2YXIgY2hyID0gU3RyaW5nLmZyb21DaGFyQ29kZShlLndoaWNoKS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0XHRjb2wgPSB0aGlzLmVsZW1lbnQuZmluZCgnLmpzdHJlZS1hbmNob3InKS5maWx0ZXIoJzp2aXNpYmxlJyksXG5cdFx0XHRcdFx0XHRcdGluZCA9IGNvbC5pbmRleChkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB8fCAwLFxuXHRcdFx0XHRcdFx0XHRlbmQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdHdvcmQgKz0gY2hyO1xuXG5cdFx0XHRcdFx0XHQvLyBtYXRjaCBmb3Igd2hvbGUgd29yZCBmcm9tIGN1cnJlbnQgbm9kZSBkb3duIChpbmNsdWRpbmcgdGhlIGN1cnJlbnQgbm9kZSlcblx0XHRcdFx0XHRcdGlmKHdvcmQubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdFx0XHRjb2wuc2xpY2UoaW5kKS5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoJCh2KS50ZXh0KCkudG9Mb3dlckNhc2UoKS5pbmRleE9mKHdvcmQpID09PSAwKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQkKHYpLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRlbmQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdFx0XHRcdFx0aWYoZW5kKSB7IHJldHVybjsgfVxuXG5cdFx0XHRcdFx0XHRcdC8vIG1hdGNoIGZvciB3aG9sZSB3b3JkIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgdHJlZVxuXHRcdFx0XHRcdFx0XHRjb2wuc2xpY2UoMCwgaW5kKS5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoJCh2KS50ZXh0KCkudG9Mb3dlckNhc2UoKS5pbmRleE9mKHdvcmQpID09PSAwKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQkKHYpLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRlbmQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdFx0XHRcdFx0aWYoZW5kKSB7IHJldHVybjsgfVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gbGlzdCBub2RlcyB0aGF0IHN0YXJ0IHdpdGggdGhhdCBsZXR0ZXIgKG9ubHkgaWYgd29yZCBjb25zaXN0cyBvZiBhIHNpbmdsZSBjaGFyKVxuXHRcdFx0XHRcdFx0aWYobmV3IFJlZ0V4cCgnXicgKyBjaHIucmVwbGFjZSgvWy1cXC9cXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykgKyAnKyQnKS50ZXN0KHdvcmQpKSB7XG5cdFx0XHRcdFx0XHRcdC8vIHNlYXJjaCBmb3IgdGhlIG5leHQgbm9kZSBzdGFydGluZyB3aXRoIHRoYXQgbGV0dGVyXG5cdFx0XHRcdFx0XHRcdGNvbC5zbGljZShpbmQgKyAxKS5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoJCh2KS50ZXh0KCkudG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09IGNocikge1xuXHRcdFx0XHRcdFx0XHRcdFx0JCh2KS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZW5kID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHRcdFx0XHRcdGlmKGVuZCkgeyByZXR1cm47IH1cblxuXHRcdFx0XHRcdFx0XHQvLyBzZWFyY2ggZnJvbSB0aGUgYmVnaW5uaW5nXG5cdFx0XHRcdFx0XHRcdGNvbC5zbGljZSgwLCBpbmQgKyAxKS5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoJCh2KS50ZXh0KCkudG9Mb3dlckNhc2UoKS5jaGFyQXQoMCkgPT09IGNocikge1xuXHRcdFx0XHRcdFx0XHRcdFx0JCh2KS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZW5kID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHRcdFx0XHRcdGlmKGVuZCkgeyByZXR1cm47IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC8vIFRIRU1FIFJFTEFURURcblx0XHRcdFx0Lm9uKFwiaW5pdC5qc3RyZWVcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0dmFyIHMgPSB0aGlzLnNldHRpbmdzLmNvcmUudGhlbWVzO1xuXHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5kb3RzXHRcdFx0PSBzLmRvdHM7XG5cdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUudGhlbWVzLnN0cmlwZXNcdFx0PSBzLnN0cmlwZXM7XG5cdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmljb25zXHRcdD0gcy5pY29ucztcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS50aGVtZXMuZWxsaXBzaXNcdFx0PSBzLmVsbGlwc2lzO1xuXHRcdFx0XHRcdFx0dGhpcy5zZXRfdGhlbWUocy5uYW1lIHx8IFwiZGVmYXVsdFwiLCBzLnVybCk7XG5cdFx0XHRcdFx0XHR0aGlzLnNldF90aGVtZV92YXJpYW50KHMudmFyaWFudCk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJsb2FkaW5nLmpzdHJlZVwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHR0aGlzWyB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmRvdHMgPyBcInNob3dfZG90c1wiIDogXCJoaWRlX2RvdHNcIiBdKCk7XG5cdFx0XHRcdFx0XHR0aGlzWyB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmljb25zID8gXCJzaG93X2ljb25zXCIgOiBcImhpZGVfaWNvbnNcIiBdKCk7XG5cdFx0XHRcdFx0XHR0aGlzWyB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLnN0cmlwZXMgPyBcInNob3dfc3RyaXBlc1wiIDogXCJoaWRlX3N0cmlwZXNcIiBdKCk7XG5cdFx0XHRcdFx0XHR0aGlzWyB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmVsbGlwc2lzID8gXCJzaG93X2VsbGlwc2lzXCIgOiBcImhpZGVfZWxsaXBzaXNcIiBdKCk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oJ2JsdXIuanN0cmVlJywgJy5qc3RyZWUtYW5jaG9yJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5mb2N1c2VkID0gbnVsbDtcblx0XHRcdFx0XHRcdCQoZS5jdXJyZW50VGFyZ2V0KS5maWx0ZXIoJy5qc3RyZWUtaG92ZXJlZCcpLnRyaWdnZXIoJ21vdXNlbGVhdmUnKTtcblx0XHRcdFx0XHRcdHRoaXMuZWxlbWVudC5hdHRyKCd0YWJpbmRleCcsICcwJyk7XG5cdFx0XHRcdFx0XHQkKGUuY3VycmVudFRhcmdldCkuYXR0cigndGFiaW5kZXgnLCAnLTEnKTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbignZm9jdXMuanN0cmVlJywgJy5qc3RyZWUtYW5jaG9yJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdHZhciB0bXAgPSB0aGlzLmdldF9ub2RlKGUuY3VycmVudFRhcmdldCk7XG5cdFx0XHRcdFx0XHRpZih0bXAgJiYgdG1wLmlkKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5mb2N1c2VkID0gdG1wLmlkO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LmZpbmQoJy5qc3RyZWUtaG92ZXJlZCcpLm5vdChlLmN1cnJlbnRUYXJnZXQpLnRyaWdnZXIoJ21vdXNlbGVhdmUnKTtcblx0XHRcdFx0XHRcdCQoZS5jdXJyZW50VGFyZ2V0KS50cmlnZ2VyKCdtb3VzZWVudGVyJyk7XG5cdFx0XHRcdFx0XHR0aGlzLmVsZW1lbnQuYXR0cigndGFiaW5kZXgnLCAnLTEnKTtcblx0XHRcdFx0XHRcdCQoZS5jdXJyZW50VGFyZ2V0KS5hdHRyKCd0YWJpbmRleCcsICcwJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oJ2ZvY3VzLmpzdHJlZScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdGlmKCsobmV3IERhdGUoKSkgLSB3YXNfY2xpY2sgPiA1MDAgJiYgIXRoaXMuX2RhdGEuY29yZS5mb2N1c2VkICYmIHRoaXMuc2V0dGluZ3MuY29yZS5yZXN0b3JlX2ZvY3VzKSB7XG5cdFx0XHRcdFx0XHRcdHdhc19jbGljayA9IDA7XG5cdFx0XHRcdFx0XHRcdHZhciBhY3QgPSB0aGlzLmdldF9ub2RlKHRoaXMuZWxlbWVudC5hdHRyKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnKSwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdGlmKGFjdCkge1xuXHRcdFx0XHRcdFx0XHRcdGFjdC5maW5kKCc+IC5qc3RyZWUtYW5jaG9yJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0Lm9uKCdtb3VzZWVudGVyLmpzdHJlZScsICcuanN0cmVlLWFuY2hvcicsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmhvdmVyX25vZGUoZS5jdXJyZW50VGFyZ2V0KTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbignbW91c2VsZWF2ZS5qc3RyZWUnLCAnLmpzdHJlZS1hbmNob3InLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0dGhpcy5kZWhvdmVyX25vZGUoZS5jdXJyZW50VGFyZ2V0KTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcGFydCBvZiB0aGUgZGVzdHJveWluZyBvZiBhbiBpbnN0YW5jZS4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgdW5iaW5kKClcblx0XHQgKi9cblx0XHR1bmJpbmQgOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHR0aGlzLmVsZW1lbnQub2ZmKCcuanN0cmVlJyk7XG5cdFx0XHQkKGRvY3VtZW50KS5vZmYoJy5qc3RyZWUtJyArIHRoaXMuX2lkKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHRyaWdnZXIgYW4gZXZlbnQuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIHRyaWdnZXIoZXYgWywgZGF0YV0pXG5cdFx0ICogQHBhcmFtICB7U3RyaW5nfSBldiB0aGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gdHJpZ2dlclxuXHRcdCAqIEBwYXJhbSAge09iamVjdH0gZGF0YSBhZGRpdGlvbmFsIGRhdGEgdG8gcGFzcyB3aXRoIHRoZSBldmVudFxuXHRcdCAqL1xuXHRcdHRyaWdnZXIgOiBmdW5jdGlvbiAoZXYsIGRhdGEpIHtcblx0XHRcdGlmKCFkYXRhKSB7XG5cdFx0XHRcdGRhdGEgPSB7fTtcblx0XHRcdH1cblx0XHRcdGRhdGEuaW5zdGFuY2UgPSB0aGlzO1xuXHRcdFx0dGhpcy5lbGVtZW50LnRyaWdnZXJIYW5kbGVyKGV2LnJlcGxhY2UoJy5qc3RyZWUnLCcnKSArICcuanN0cmVlJywgZGF0YSk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiByZXR1cm5zIHRoZSBqUXVlcnkgZXh0ZW5kZWQgaW5zdGFuY2UgY29udGFpbmVyXG5cdFx0ICogQG5hbWUgZ2V0X2NvbnRhaW5lcigpXG5cdFx0ICogQHJldHVybiB7alF1ZXJ5fVxuXHRcdCAqL1xuXHRcdGdldF9jb250YWluZXIgOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lbGVtZW50O1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcmV0dXJucyB0aGUgalF1ZXJ5IGV4dGVuZGVkIG1haW4gVUwgbm9kZSBpbnNpZGUgdGhlIGluc3RhbmNlIGNvbnRhaW5lci4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgZ2V0X2NvbnRhaW5lcl91bCgpXG5cdFx0ICogQHJldHVybiB7alF1ZXJ5fVxuXHRcdCAqL1xuXHRcdGdldF9jb250YWluZXJfdWwgOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lbGVtZW50LmNoaWxkcmVuKFwiLmpzdHJlZS1jaGlsZHJlblwiKS5maXJzdCgpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyBzdHJpbmcgcmVwbGFjZW1lbnRzIChsb2NhbGl6YXRpb24pLiBVc2VkIGludGVybmFsbHkuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBnZXRfc3RyaW5nKGtleSlcblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IGtleVxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ31cblx0XHQgKi9cblx0XHRnZXRfc3RyaW5nIDogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0dmFyIGEgPSB0aGlzLnNldHRpbmdzLmNvcmUuc3RyaW5ncztcblx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKGEpKSB7IHJldHVybiBhLmNhbGwodGhpcywga2V5KTsgfVxuXHRcdFx0aWYoYSAmJiBhW2tleV0pIHsgcmV0dXJuIGFba2V5XTsgfVxuXHRcdFx0cmV0dXJuIGtleTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldHMgdGhlIGZpcnN0IGNoaWxkIG9mIGEgRE9NIG5vZGUuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9maXJzdENoaWxkKGRvbSlcblx0XHQgKiBAcGFyYW0gIHtET01FbGVtZW50fSBkb21cblx0XHQgKiBAcmV0dXJuIHtET01FbGVtZW50fVxuXHRcdCAqL1xuXHRcdF9maXJzdENoaWxkIDogZnVuY3Rpb24gKGRvbSkge1xuXHRcdFx0ZG9tID0gZG9tID8gZG9tLmZpcnN0Q2hpbGQgOiBudWxsO1xuXHRcdFx0d2hpbGUoZG9tICE9PSBudWxsICYmIGRvbS5ub2RlVHlwZSAhPT0gMSkge1xuXHRcdFx0XHRkb20gPSBkb20ubmV4dFNpYmxpbmc7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZG9tO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyB0aGUgbmV4dCBzaWJsaW5nIG9mIGEgRE9NIG5vZGUuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9uZXh0U2libGluZyhkb20pXG5cdFx0ICogQHBhcmFtICB7RE9NRWxlbWVudH0gZG9tXG5cdFx0ICogQHJldHVybiB7RE9NRWxlbWVudH1cblx0XHQgKi9cblx0XHRfbmV4dFNpYmxpbmcgOiBmdW5jdGlvbiAoZG9tKSB7XG5cdFx0XHRkb20gPSBkb20gPyBkb20ubmV4dFNpYmxpbmcgOiBudWxsO1xuXHRcdFx0d2hpbGUoZG9tICE9PSBudWxsICYmIGRvbS5ub2RlVHlwZSAhPT0gMSkge1xuXHRcdFx0XHRkb20gPSBkb20ubmV4dFNpYmxpbmc7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZG9tO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyB0aGUgcHJldmlvdXMgc2libGluZyBvZiBhIERPTSBub2RlLiBVc2VkIGludGVybmFsbHkuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBfcHJldmlvdXNTaWJsaW5nKGRvbSlcblx0XHQgKiBAcGFyYW0gIHtET01FbGVtZW50fSBkb21cblx0XHQgKiBAcmV0dXJuIHtET01FbGVtZW50fVxuXHRcdCAqL1xuXHRcdF9wcmV2aW91c1NpYmxpbmcgOiBmdW5jdGlvbiAoZG9tKSB7XG5cdFx0XHRkb20gPSBkb20gPyBkb20ucHJldmlvdXNTaWJsaW5nIDogbnVsbDtcblx0XHRcdHdoaWxlKGRvbSAhPT0gbnVsbCAmJiBkb20ubm9kZVR5cGUgIT09IDEpIHtcblx0XHRcdFx0ZG9tID0gZG9tLnByZXZpb3VzU2libGluZztcblx0XHRcdH1cblx0XHRcdHJldHVybiBkb207XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBnZXQgdGhlIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBub2RlIChvciB0aGUgYWN0dWFsIGpRdWVyeSBleHRlbmRlZCBET00gbm9kZSkgYnkgdXNpbmcgYW55IGlucHV0IChjaGlsZCBET00gZWxlbWVudCwgSUQgc3RyaW5nLCBzZWxlY3RvciwgZXRjKVxuXHRcdCAqIEBuYW1lIGdldF9ub2RlKG9iaiBbLCBhc19kb21dKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmpcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBhc19kb21cblx0XHQgKiBAcmV0dXJuIHtPYmplY3R8alF1ZXJ5fVxuXHRcdCAqL1xuXHRcdGdldF9ub2RlIDogZnVuY3Rpb24gKG9iaiwgYXNfZG9tKSB7XG5cdFx0XHRpZihvYmogJiYgb2JqLmlkKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5pZDtcblx0XHRcdH1cblx0XHRcdGlmIChvYmogaW5zdGFuY2VvZiAkICYmIG9iai5sZW5ndGggJiYgb2JqWzBdLmlkKSB7XG5cdFx0XHRcdG9iaiA9IG9ialswXS5pZDtcblx0XHRcdH1cblx0XHRcdHZhciBkb207XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW29ial0pIHtcblx0XHRcdFx0XHRvYmogPSB0aGlzLl9tb2RlbC5kYXRhW29ial07XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSBpZih0eXBlb2Ygb2JqID09PSBcInN0cmluZ1wiICYmIHRoaXMuX21vZGVsLmRhdGFbb2JqLnJlcGxhY2UoL14jLywgJycpXSkge1xuXHRcdFx0XHRcdG9iaiA9IHRoaXMuX21vZGVsLmRhdGFbb2JqLnJlcGxhY2UoL14jLywgJycpXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIGlmKHR5cGVvZiBvYmogPT09IFwic3RyaW5nXCIgJiYgKGRvbSA9ICQoJyMnICsgb2JqLnJlcGxhY2UoJC5qc3RyZWUuaWRyZWdleCwnXFxcXCQmJyksIHRoaXMuZWxlbWVudCkpLmxlbmd0aCAmJiB0aGlzLl9tb2RlbC5kYXRhW2RvbS5jbG9zZXN0KCcuanN0cmVlLW5vZGUnKS5hdHRyKCdpZCcpXSkge1xuXHRcdFx0XHRcdG9iaiA9IHRoaXMuX21vZGVsLmRhdGFbZG9tLmNsb3Nlc3QoJy5qc3RyZWUtbm9kZScpLmF0dHIoJ2lkJyldO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2UgaWYoKGRvbSA9IHRoaXMuZWxlbWVudC5maW5kKG9iaikpLmxlbmd0aCAmJiB0aGlzLl9tb2RlbC5kYXRhW2RvbS5jbG9zZXN0KCcuanN0cmVlLW5vZGUnKS5hdHRyKCdpZCcpXSkge1xuXHRcdFx0XHRcdG9iaiA9IHRoaXMuX21vZGVsLmRhdGFbZG9tLmNsb3Nlc3QoJy5qc3RyZWUtbm9kZScpLmF0dHIoJ2lkJyldO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2UgaWYoKGRvbSA9IHRoaXMuZWxlbWVudC5maW5kKG9iaikpLmxlbmd0aCAmJiBkb20uaGFzQ2xhc3MoJ2pzdHJlZScpKSB7XG5cdFx0XHRcdFx0b2JqID0gdGhpcy5fbW9kZWwuZGF0YVskLmpzdHJlZS5yb290XTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZihhc19kb20pIHtcblx0XHRcdFx0XHRvYmogPSBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QgPyB0aGlzLmVsZW1lbnQgOiAkKCcjJyArIG9iai5pZC5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpLCB0aGlzLmVsZW1lbnQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBvYmo7XG5cdFx0XHR9IGNhdGNoIChleCkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCB0aGUgcGF0aCB0byBhIG5vZGUsIGVpdGhlciBjb25zaXN0aW5nIG9mIG5vZGUgdGV4dHMsIG9yIG9mIG5vZGUgSURzLCBvcHRpb25hbGx5IGdsdWVkIHRvZ2V0aGVyIChvdGhlcndpc2UgYW4gYXJyYXkpXG5cdFx0ICogQG5hbWUgZ2V0X3BhdGgob2JqIFssIGdsdWUsIGlkc10pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZVxuXHRcdCAqIEBwYXJhbSAge1N0cmluZ30gZ2x1ZSBpZiB5b3Ugd2FudCB0aGUgcGF0aCBhcyBhIHN0cmluZyAtIHBhc3MgdGhlIGdsdWUgaGVyZSAoZm9yIGV4YW1wbGUgJy8nKSwgaWYgYSBmYWxzeSB2YWx1ZSBpcyBzdXBwbGllZCBoZXJlLCBhbiBhcnJheSBpcyByZXR1cm5lZFxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IGlkcyBpZiBzZXQgdG8gdHJ1ZSBidWlsZCB0aGUgcGF0aCB1c2luZyBJRCwgb3RoZXJ3aXNlIG5vZGUgdGV4dCBpcyB1c2VkXG5cdFx0ICogQHJldHVybiB7bWl4ZWR9XG5cdFx0ICovXG5cdFx0Z2V0X3BhdGggOiBmdW5jdGlvbiAob2JqLCBnbHVlLCBpZHMpIHtcblx0XHRcdG9iaiA9IG9iai5wYXJlbnRzID8gb2JqIDogdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QgfHwgIW9iai5wYXJlbnRzKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHZhciBpLCBqLCBwID0gW107XG5cdFx0XHRwLnB1c2goaWRzID8gb2JqLmlkIDogb2JqLnRleHQpO1xuXHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdHAucHVzaChpZHMgPyBvYmoucGFyZW50c1tpXSA6IHRoaXMuZ2V0X3RleHQob2JqLnBhcmVudHNbaV0pKTtcblx0XHRcdH1cblx0XHRcdHAgPSBwLnJldmVyc2UoKS5zbGljZSgxKTtcblx0XHRcdHJldHVybiBnbHVlID8gcC5qb2luKGdsdWUpIDogcDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCB0aGUgbmV4dCB2aXNpYmxlIG5vZGUgdGhhdCBpcyBiZWxvdyB0aGUgYG9iamAgbm9kZS4gSWYgYHN0cmljdGAgaXMgc2V0IHRvIGB0cnVlYCBvbmx5IHNpYmxpbmcgbm9kZXMgYXJlIHJldHVybmVkLlxuXHRcdCAqIEBuYW1lIGdldF9uZXh0X2RvbShvYmogWywgc3RyaWN0XSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gc3RyaWN0XG5cdFx0ICogQHJldHVybiB7alF1ZXJ5fVxuXHRcdCAqL1xuXHRcdGdldF9uZXh0X2RvbSA6IGZ1bmN0aW9uIChvYmosIHN0cmljdCkge1xuXHRcdFx0dmFyIHRtcDtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdGlmKG9ialswXSA9PT0gdGhpcy5lbGVtZW50WzBdKSB7XG5cdFx0XHRcdHRtcCA9IHRoaXMuX2ZpcnN0Q2hpbGQodGhpcy5nZXRfY29udGFpbmVyX3VsKClbMF0pO1xuXHRcdFx0XHR3aGlsZSAodG1wICYmIHRtcC5vZmZzZXRIZWlnaHQgPT09IDApIHtcblx0XHRcdFx0XHR0bXAgPSB0aGlzLl9uZXh0U2libGluZyh0bXApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0bXAgPyAkKHRtcCkgOiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKCFvYmogfHwgIW9iai5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0aWYoc3RyaWN0KSB7XG5cdFx0XHRcdHRtcCA9IG9ialswXTtcblx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdHRtcCA9IHRoaXMuX25leHRTaWJsaW5nKHRtcCk7XG5cdFx0XHRcdH0gd2hpbGUgKHRtcCAmJiB0bXAub2Zmc2V0SGVpZ2h0ID09PSAwKTtcblx0XHRcdFx0cmV0dXJuIHRtcCA/ICQodG1wKSA6IGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0aWYob2JqLmhhc0NsYXNzKFwianN0cmVlLW9wZW5cIikpIHtcblx0XHRcdFx0dG1wID0gdGhpcy5fZmlyc3RDaGlsZChvYmouY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKVswXSk7XG5cdFx0XHRcdHdoaWxlICh0bXAgJiYgdG1wLm9mZnNldEhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRcdHRtcCA9IHRoaXMuX25leHRTaWJsaW5nKHRtcCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYodG1wICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0cmV0dXJuICQodG1wKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dG1wID0gb2JqWzBdO1xuXHRcdFx0ZG8ge1xuXHRcdFx0XHR0bXAgPSB0aGlzLl9uZXh0U2libGluZyh0bXApO1xuXHRcdFx0fSB3aGlsZSAodG1wICYmIHRtcC5vZmZzZXRIZWlnaHQgPT09IDApO1xuXHRcdFx0aWYodG1wICE9PSBudWxsKSB7XG5cdFx0XHRcdHJldHVybiAkKHRtcCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gb2JqLnBhcmVudHNVbnRpbChcIi5qc3RyZWVcIixcIi5qc3RyZWUtbm9kZVwiKS5uZXh0QWxsKFwiLmpzdHJlZS1ub2RlOnZpc2libGVcIikuZmlyc3QoKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCB0aGUgcHJldmlvdXMgdmlzaWJsZSBub2RlIHRoYXQgaXMgYWJvdmUgdGhlIGBvYmpgIG5vZGUuIElmIGBzdHJpY3RgIGlzIHNldCB0byBgdHJ1ZWAgb25seSBzaWJsaW5nIG5vZGVzIGFyZSByZXR1cm5lZC5cblx0XHQgKiBAbmFtZSBnZXRfcHJldl9kb20ob2JqIFssIHN0cmljdF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IHN0cmljdFxuXHRcdCAqIEByZXR1cm4ge2pRdWVyeX1cblx0XHQgKi9cblx0XHRnZXRfcHJldl9kb20gOiBmdW5jdGlvbiAob2JqLCBzdHJpY3QpIHtcblx0XHRcdHZhciB0bXA7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSk7XG5cdFx0XHRpZihvYmpbMF0gPT09IHRoaXMuZWxlbWVudFswXSkge1xuXHRcdFx0XHR0bXAgPSB0aGlzLmdldF9jb250YWluZXJfdWwoKVswXS5sYXN0Q2hpbGQ7XG5cdFx0XHRcdHdoaWxlICh0bXAgJiYgdG1wLm9mZnNldEhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRcdHRtcCA9IHRoaXMuX3ByZXZpb3VzU2libGluZyh0bXApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0bXAgPyAkKHRtcCkgOiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKCFvYmogfHwgIW9iai5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0aWYoc3RyaWN0KSB7XG5cdFx0XHRcdHRtcCA9IG9ialswXTtcblx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdHRtcCA9IHRoaXMuX3ByZXZpb3VzU2libGluZyh0bXApO1xuXHRcdFx0XHR9IHdoaWxlICh0bXAgJiYgdG1wLm9mZnNldEhlaWdodCA9PT0gMCk7XG5cdFx0XHRcdHJldHVybiB0bXAgPyAkKHRtcCkgOiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHRtcCA9IG9ialswXTtcblx0XHRcdGRvIHtcblx0XHRcdFx0dG1wID0gdGhpcy5fcHJldmlvdXNTaWJsaW5nKHRtcCk7XG5cdFx0XHR9IHdoaWxlICh0bXAgJiYgdG1wLm9mZnNldEhlaWdodCA9PT0gMCk7XG5cdFx0XHRpZih0bXAgIT09IG51bGwpIHtcblx0XHRcdFx0b2JqID0gJCh0bXApO1xuXHRcdFx0XHR3aGlsZShvYmouaGFzQ2xhc3MoXCJqc3RyZWUtb3BlblwiKSkge1xuXHRcdFx0XHRcdG9iaiA9IG9iai5jaGlsZHJlbihcIi5qc3RyZWUtY2hpbGRyZW5cIikuZmlyc3QoKS5jaGlsZHJlbihcIi5qc3RyZWUtbm9kZTp2aXNpYmxlOmxhc3RcIik7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG9iajtcblx0XHRcdH1cblx0XHRcdHRtcCA9IG9ialswXS5wYXJlbnROb2RlLnBhcmVudE5vZGU7XG5cdFx0XHRyZXR1cm4gdG1wICYmIHRtcC5jbGFzc05hbWUgJiYgdG1wLmNsYXNzTmFtZS5pbmRleE9mKCdqc3RyZWUtbm9kZScpICE9PSAtMSA/ICQodG1wKSA6IGZhbHNlO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0IHRoZSBwYXJlbnQgSUQgb2YgYSBub2RlXG5cdFx0ICogQG5hbWUgZ2V0X3BhcmVudChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ31cblx0XHQgKi9cblx0XHRnZXRfcGFyZW50IDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9iai5wYXJlbnQ7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBnZXQgYSBqUXVlcnkgY29sbGVjdGlvbiBvZiBhbGwgdGhlIGNoaWxkcmVuIG9mIGEgbm9kZSAobm9kZSBtdXN0IGJlIHJlbmRlcmVkKSwgcmV0dXJucyBmYWxzZSBvbiBlcnJvclxuXHRcdCAqIEBuYW1lIGdldF9jaGlsZHJlbl9kb20ob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmpcblx0XHQgKiBAcmV0dXJuIHtqUXVlcnl9XG5cdFx0ICovXG5cdFx0Z2V0X2NoaWxkcmVuX2RvbSA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdGlmKG9ialswXSA9PT0gdGhpcy5lbGVtZW50WzBdKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmdldF9jb250YWluZXJfdWwoKS5jaGlsZHJlbihcIi5qc3RyZWUtbm9kZVwiKTtcblx0XHRcdH1cblx0XHRcdGlmKCFvYmogfHwgIW9iai5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9iai5jaGlsZHJlbihcIi5qc3RyZWUtY2hpbGRyZW5cIikuY2hpbGRyZW4oXCIuanN0cmVlLW5vZGVcIik7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBjaGVja3MgaWYgYSBub2RlIGhhcyBjaGlsZHJlblxuXHRcdCAqIEBuYW1lIGlzX3BhcmVudChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0aXNfcGFyZW50IDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuIG9iaiAmJiAob2JqLnN0YXRlLmxvYWRlZCA9PT0gZmFsc2UgfHwgb2JqLmNoaWxkcmVuLmxlbmd0aCA+IDApO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY2hlY2tzIGlmIGEgbm9kZSBpcyBsb2FkZWQgKGl0cyBjaGlsZHJlbiBhcmUgYXZhaWxhYmxlKVxuXHRcdCAqIEBuYW1lIGlzX2xvYWRlZChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0aXNfbG9hZGVkIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuIG9iaiAmJiBvYmouc3RhdGUubG9hZGVkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY2hlY2sgaWYgYSBub2RlIGlzIGN1cnJlbnRseSBsb2FkaW5nIChmZXRjaGluZyBjaGlsZHJlbilcblx0XHQgKiBAbmFtZSBpc19sb2FkaW5nKG9iailcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICogQHJldHVybiB7Qm9vbGVhbn1cblx0XHQgKi9cblx0XHRpc19sb2FkaW5nIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuIG9iaiAmJiBvYmouc3RhdGUgJiYgb2JqLnN0YXRlLmxvYWRpbmc7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBjaGVjayBpZiBhIG5vZGUgaXMgb3BlbmVkXG5cdFx0ICogQG5hbWUgaXNfb3BlbihvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0aXNfb3BlbiA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdHJldHVybiBvYmogJiYgb2JqLnN0YXRlLm9wZW5lZDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNoZWNrIGlmIGEgbm9kZSBpcyBpbiBhIGNsb3NlZCBzdGF0ZVxuXHRcdCAqIEBuYW1lIGlzX2Nsb3NlZChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0aXNfY2xvc2VkIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuIG9iaiAmJiB0aGlzLmlzX3BhcmVudChvYmopICYmICFvYmouc3RhdGUub3BlbmVkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY2hlY2sgaWYgYSBub2RlIGhhcyBubyBjaGlsZHJlblxuXHRcdCAqIEBuYW1lIGlzX2xlYWYob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmpcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqL1xuXHRcdGlzX2xlYWYgOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRyZXR1cm4gIXRoaXMuaXNfcGFyZW50KG9iaik7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBsb2FkcyBhIG5vZGUgKGZldGNoZXMgaXRzIGNoaWxkcmVuIHVzaW5nIHRoZSBgY29yZS5kYXRhYCBzZXR0aW5nKS4gTXVsdGlwbGUgbm9kZXMgY2FuIGJlIHBhc3NlZCB0byBieSB1c2luZyBhbiBhcnJheS5cblx0XHQgKiBAbmFtZSBsb2FkX25vZGUob2JqIFssIGNhbGxiYWNrXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICogQHBhcmFtICB7ZnVuY3Rpb259IGNhbGxiYWNrIGEgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgb25jZSBsb2FkaW5nIGlzIGNvbXBsZXRlLCB0aGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgaW4gdGhlIGluc3RhbmNlJ3Mgc2NvcGUgYW5kIHJlY2VpdmVzIHR3byBhcmd1bWVudHMgLSB0aGUgbm9kZSBhbmQgYSBib29sZWFuIHN0YXR1c1xuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICogQHRyaWdnZXIgbG9hZF9ub2RlLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGxvYWRfbm9kZSA6IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG5cdFx0XHR2YXIgZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpLCBrLCBsLCBpLCBqLCBjO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHR0aGlzLl9sb2FkX25vZGVzKG9iai5zbGljZSgpLCBjYWxsYmFjayk7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaikge1xuXHRcdFx0XHRpZihjYWxsYmFjaykgeyBjYWxsYmFjay5jYWxsKHRoaXMsIG9iaiwgZmFsc2UpOyB9XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdC8vIGlmKG9iai5zdGF0ZS5sb2FkaW5nKSB7IH0gLy8gdGhlIG5vZGUgaXMgYWxyZWFkeSBsb2FkaW5nIC0ganVzdCB3YWl0IGZvciBpdCB0byBsb2FkIGFuZCBpbnZva2UgY2FsbGJhY2s/IGJ1dCBpZiBjYWxsZWQgaW1wbGljaXRseSBpdCBzaG91bGQgYmUgbG9hZGVkIGFnYWluP1xuXHRcdFx0aWYob2JqLnN0YXRlLmxvYWRlZCkge1xuXHRcdFx0XHRvYmouc3RhdGUubG9hZGVkID0gZmFsc2U7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5wYXJlbnRzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdHRoaXMuX21vZGVsLmRhdGFbb2JqLnBhcmVudHNbaV1dLmNoaWxkcmVuX2QgPSAkLnZha2F0YS5hcnJheV9maWx0ZXIodGhpcy5fbW9kZWwuZGF0YVtvYmoucGFyZW50c1tpXV0uY2hpbGRyZW5fZCwgZnVuY3Rpb24gKHYpIHtcblx0XHRcdFx0XHRcdHJldHVybiAkLmluQXJyYXkodiwgb2JqLmNoaWxkcmVuX2QpID09PSAtMTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRmb3IoayA9IDAsIGwgPSBvYmouY2hpbGRyZW5fZC5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW29iai5jaGlsZHJlbl9kW2tdXS5zdGF0ZS5zZWxlY3RlZCkge1xuXHRcdFx0XHRcdFx0YyA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRlbGV0ZSB0aGlzLl9tb2RlbC5kYXRhW29iai5jaGlsZHJlbl9kW2tdXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoYykge1xuXHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZCA9ICQudmFrYXRhLmFycmF5X2ZpbHRlcih0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsIGZ1bmN0aW9uICh2KSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gJC5pbkFycmF5KHYsIG9iai5jaGlsZHJlbl9kKSA9PT0gLTE7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0b2JqLmNoaWxkcmVuID0gW107XG5cdFx0XHRcdG9iai5jaGlsZHJlbl9kID0gW107XG5cdFx0XHRcdGlmKGMpIHtcblx0XHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2NoYW5nZWQnLCB7ICdhY3Rpb24nIDogJ2xvYWRfbm9kZScsICdub2RlJyA6IG9iaiwgJ3NlbGVjdGVkJyA6IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZCB9KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0b2JqLnN0YXRlLmZhaWxlZCA9IGZhbHNlO1xuXHRcdFx0b2JqLnN0YXRlLmxvYWRpbmcgPSB0cnVlO1xuXHRcdFx0aWYgKG9iai5pZCAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRkb20uY2hpbGRyZW4oXCIuanN0cmVlLWFuY2hvclwiKS5hdHRyKCdhcmlhLWJ1c3knLCB0cnVlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRvbS5hdHRyKCdhcmlhLWJ1c3knLCB0cnVlKTtcblx0XHRcdH1cblx0XHRcdGRvbS5hZGRDbGFzcyhcImpzdHJlZS1sb2FkaW5nXCIpO1xuXHRcdFx0dGhpcy5fbG9hZF9ub2RlKG9iaiwgZnVuY3Rpb24gKHN0YXR1cykge1xuXHRcdFx0XHRvYmogPSB0aGlzLl9tb2RlbC5kYXRhW29iai5pZF07XG5cdFx0XHRcdG9iai5zdGF0ZS5sb2FkaW5nID0gZmFsc2U7XG5cdFx0XHRcdG9iai5zdGF0ZS5sb2FkZWQgPSBzdGF0dXM7XG5cdFx0XHRcdG9iai5zdGF0ZS5mYWlsZWQgPSAhb2JqLnN0YXRlLmxvYWRlZDtcblx0XHRcdFx0dmFyIGRvbSA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKSwgaSA9IDAsIGogPSAwLCBtID0gdGhpcy5fbW9kZWwuZGF0YSwgaGFzX2NoaWxkcmVuID0gZmFsc2U7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRpZihtW29iai5jaGlsZHJlbltpXV0gJiYgIW1bb2JqLmNoaWxkcmVuW2ldXS5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0XHRcdGhhc19jaGlsZHJlbiA9IHRydWU7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYob2JqLnN0YXRlLmxvYWRlZCAmJiBkb20gJiYgZG9tLmxlbmd0aCkge1xuXHRcdFx0XHRcdGRvbS5yZW1vdmVDbGFzcygnanN0cmVlLWNsb3NlZCBqc3RyZWUtb3BlbiBqc3RyZWUtbGVhZicpO1xuXHRcdFx0XHRcdGlmICghaGFzX2NoaWxkcmVuKSB7XG5cdFx0XHRcdFx0XHRkb20uYWRkQ2xhc3MoJ2pzdHJlZS1sZWFmJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKG9iai5pZCAhPT0gJyMnKSB7XG5cdFx0XHRcdFx0XHRcdGRvbS5hZGRDbGFzcyhvYmouc3RhdGUub3BlbmVkID8gJ2pzdHJlZS1vcGVuJyA6ICdqc3RyZWUtY2xvc2VkJyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChvYmouaWQgIT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRkb20uY2hpbGRyZW4oXCIuanN0cmVlLWFuY2hvclwiKS5hdHRyKCdhcmlhLWJ1c3knLCBmYWxzZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZG9tLmF0dHIoJ2FyaWEtYnVzeScsIGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkb20ucmVtb3ZlQ2xhc3MoXCJqc3RyZWUtbG9hZGluZ1wiKTtcblx0XHRcdFx0LyoqXG5cdFx0XHRcdCAqIHRyaWdnZXJlZCBhZnRlciBhIG5vZGUgaXMgbG9hZGVkXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBsb2FkX25vZGUuanN0cmVlXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIHRoZSBub2RlIHRoYXQgd2FzIGxvYWRpbmdcblx0XHRcdFx0ICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgd2FzIHRoZSBub2RlIGxvYWRlZCBzdWNjZXNzZnVsbHlcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcignbG9hZF9ub2RlJywgeyBcIm5vZGVcIiA6IG9iaiwgXCJzdGF0dXNcIiA6IHN0YXR1cyB9KTtcblx0XHRcdFx0aWYoY2FsbGJhY2spIHtcblx0XHRcdFx0XHRjYWxsYmFjay5jYWxsKHRoaXMsIG9iaiwgc3RhdHVzKTtcblx0XHRcdFx0fVxuXHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogbG9hZCBhbiBhcnJheSBvZiBub2RlcyAod2lsbCBhbHNvIGxvYWQgdW5hdmFpbGFibGUgbm9kZXMgYXMgc29vbiBhcyB0aGV5IGFwcGVhciBpbiB0aGUgc3RydWN0dXJlKS4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgX2xvYWRfbm9kZXMobm9kZXMgWywgY2FsbGJhY2tdKVxuXHRcdCAqIEBwYXJhbSAge2FycmF5fSBub2Rlc1xuXHRcdCAqIEBwYXJhbSAge2Z1bmN0aW9ufSBjYWxsYmFjayBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIG9uY2UgbG9hZGluZyBpcyBjb21wbGV0ZSwgdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlIGFuZCByZWNlaXZlcyBvbmUgYXJndW1lbnQgLSB0aGUgYXJyYXkgcGFzc2VkIHRvIF9sb2FkX25vZGVzXG5cdFx0ICovXG5cdFx0X2xvYWRfbm9kZXMgOiBmdW5jdGlvbiAobm9kZXMsIGNhbGxiYWNrLCBpc19jYWxsYmFjaywgZm9yY2VfcmVsb2FkKSB7XG5cdFx0XHR2YXIgciA9IHRydWUsXG5cdFx0XHRcdGMgPSBmdW5jdGlvbiAoKSB7IHRoaXMuX2xvYWRfbm9kZXMobm9kZXMsIGNhbGxiYWNrLCB0cnVlKTsgfSxcblx0XHRcdFx0bSA9IHRoaXMuX21vZGVsLmRhdGEsIGksIGosIHRtcCA9IFtdO1xuXHRcdFx0Zm9yKGkgPSAwLCBqID0gbm9kZXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKG1bbm9kZXNbaV1dICYmICggKCFtW25vZGVzW2ldXS5zdGF0ZS5sb2FkZWQgJiYgIW1bbm9kZXNbaV1dLnN0YXRlLmZhaWxlZCkgfHwgKCFpc19jYWxsYmFjayAmJiBmb3JjZV9yZWxvYWQpICkpIHtcblx0XHRcdFx0XHRpZighdGhpcy5pc19sb2FkaW5nKG5vZGVzW2ldKSkge1xuXHRcdFx0XHRcdFx0dGhpcy5sb2FkX25vZGUobm9kZXNbaV0sIGMpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKHIpIHtcblx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gbm9kZXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0aWYobVtub2Rlc1tpXV0gJiYgbVtub2Rlc1tpXV0uc3RhdGUubG9hZGVkKSB7XG5cdFx0XHRcdFx0XHR0bXAucHVzaChub2Rlc1tpXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKGNhbGxiYWNrICYmICFjYWxsYmFjay5kb25lKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCh0aGlzLCB0bXApO1xuXHRcdFx0XHRcdGNhbGxiYWNrLmRvbmUgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBsb2FkcyBhbGwgdW5sb2FkZWQgbm9kZXNcblx0XHQgKiBAbmFtZSBsb2FkX2FsbChbb2JqLCBjYWxsYmFja10pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlIHRvIGxvYWQgcmVjdXJzaXZlbHksIG9taXQgdG8gbG9hZCBhbGwgbm9kZXMgaW4gdGhlIHRyZWVcblx0XHQgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIG9uY2UgbG9hZGluZyBhbGwgdGhlIG5vZGVzIGlzIGNvbXBsZXRlLFxuXHRcdCAqIEB0cmlnZ2VyIGxvYWRfYWxsLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGxvYWRfYWxsIDogZnVuY3Rpb24gKG9iaiwgY2FsbGJhY2spIHtcblx0XHRcdGlmKCFvYmopIHsgb2JqID0gJC5qc3RyZWUucm9vdDsgfVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHZhciB0b19sb2FkID0gW10sXG5cdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRjID0gbVtvYmouaWRdLmNoaWxkcmVuX2QsXG5cdFx0XHRcdGksIGo7XG5cdFx0XHRpZihvYmouc3RhdGUgJiYgIW9iai5zdGF0ZS5sb2FkZWQpIHtcblx0XHRcdFx0dG9fbG9hZC5wdXNoKG9iai5pZCk7XG5cdFx0XHR9XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBjLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRpZihtW2NbaV1dICYmIG1bY1tpXV0uc3RhdGUgJiYgIW1bY1tpXV0uc3RhdGUubG9hZGVkKSB7XG5cdFx0XHRcdFx0dG9fbG9hZC5wdXNoKGNbaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZih0b19sb2FkLmxlbmd0aCkge1xuXHRcdFx0XHR0aGlzLl9sb2FkX25vZGVzKHRvX2xvYWQsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR0aGlzLmxvYWRfYWxsKG9iaiwgY2FsbGJhY2spO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIGFmdGVyIGEgbG9hZF9hbGwgY2FsbCBjb21wbGV0ZXNcblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIGxvYWRfYWxsLmpzdHJlZVxuXHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgcmVjdXJzaXZlbHkgbG9hZGVkIG5vZGVcblx0XHRcdFx0ICovXG5cdFx0XHRcdGlmKGNhbGxiYWNrKSB7IGNhbGxiYWNrLmNhbGwodGhpcywgb2JqKTsgfVxuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2xvYWRfYWxsJywgeyBcIm5vZGVcIiA6IG9iaiB9KTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGhhbmRsZXMgdGhlIGFjdHVhbCBsb2FkaW5nIG9mIGEgbm9kZS4gVXNlZCBvbmx5IGludGVybmFsbHkuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBfbG9hZF9ub2RlKG9iaiBbLCBjYWxsYmFja10pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEBwYXJhbSAge2Z1bmN0aW9ufSBjYWxsYmFjayBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIG9uY2UgbG9hZGluZyBpcyBjb21wbGV0ZSwgdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlIGFuZCByZWNlaXZlcyBvbmUgYXJndW1lbnQgLSBhIGJvb2xlYW4gc3RhdHVzXG5cdFx0ICogQHJldHVybiB7Qm9vbGVhbn1cblx0XHQgKi9cblx0XHRfbG9hZF9ub2RlIDogZnVuY3Rpb24gKG9iaiwgY2FsbGJhY2spIHtcblx0XHRcdHZhciBzID0gdGhpcy5zZXR0aW5ncy5jb3JlLmRhdGEsIHQ7XG5cdFx0XHR2YXIgbm90VGV4dE9yQ29tbWVudE5vZGUgPSBmdW5jdGlvbiBub3RUZXh0T3JDb21tZW50Tm9kZSAoKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLm5vZGVUeXBlICE9PSAzICYmIHRoaXMubm9kZVR5cGUgIT09IDg7XG5cdFx0XHR9O1xuXHRcdFx0Ly8gdXNlIG9yaWdpbmFsIEhUTUxcblx0XHRcdGlmKCFzKSB7XG5cdFx0XHRcdGlmKG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9hcHBlbmRfaHRtbF9kYXRhKG9iaiwgdGhpcy5fZGF0YS5jb3JlLm9yaWdpbmFsX2NvbnRhaW5lcl9odG1sLmNsb25lKHRydWUpLCBmdW5jdGlvbiAoc3RhdHVzKSB7XG5cdFx0XHRcdFx0XHRjYWxsYmFjay5jYWxsKHRoaXMsIHN0YXR1cyk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIHJldHVybiBjYWxsYmFjay5jYWxsKHRoaXMsIG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCA/IHRoaXMuX2FwcGVuZF9odG1sX2RhdGEob2JqLCB0aGlzLl9kYXRhLmNvcmUub3JpZ2luYWxfY29udGFpbmVyX2h0bWwuY2xvbmUodHJ1ZSkpIDogZmFsc2UpO1xuXHRcdFx0fVxuXHRcdFx0aWYoJC52YWthdGEuaXNfZnVuY3Rpb24ocykpIHtcblx0XHRcdFx0cmV0dXJuIHMuY2FsbCh0aGlzLCBvYmosIGZ1bmN0aW9uIChkKSB7XG5cdFx0XHRcdFx0aWYoZCA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXNbdHlwZW9mIGQgPT09ICdzdHJpbmcnID8gJ19hcHBlbmRfaHRtbF9kYXRhJyA6ICdfYXBwZW5kX2pzb25fZGF0YSddKG9iaiwgdHlwZW9mIGQgPT09ICdzdHJpbmcnID8gJCgkLnBhcnNlSFRNTChkKSkuZmlsdGVyKG5vdFRleHRPckNvbW1lbnROb2RlKSA6IGQsIGZ1bmN0aW9uIChzdGF0dXMpIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCh0aGlzLCBzdGF0dXMpO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdC8vIHJldHVybiBkID09PSBmYWxzZSA/IGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpIDogY2FsbGJhY2suY2FsbCh0aGlzLCB0aGlzW3R5cGVvZiBkID09PSAnc3RyaW5nJyA/ICdfYXBwZW5kX2h0bWxfZGF0YScgOiAnX2FwcGVuZF9qc29uX2RhdGEnXShvYmosIHR5cGVvZiBkID09PSAnc3RyaW5nJyA/ICQoZCkgOiBkKSk7XG5cdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHR9XG5cdFx0XHRpZih0eXBlb2YgcyA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0aWYocy51cmwpIHtcblx0XHRcdFx0XHRzID0gJC5leHRlbmQodHJ1ZSwge30sIHMpO1xuXHRcdFx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKHMudXJsKSkge1xuXHRcdFx0XHRcdFx0cy51cmwgPSBzLnVybC5jYWxsKHRoaXMsIG9iaik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKHMuZGF0YSkpIHtcblx0XHRcdFx0XHRcdHMuZGF0YSA9IHMuZGF0YS5jYWxsKHRoaXMsIG9iaik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiAkLmFqYXgocylcblx0XHRcdFx0XHRcdC5kb25lKGZ1bmN0aW9uIChkLHQseCkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciB0eXBlID0geC5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJyk7XG5cdFx0XHRcdFx0XHRcdFx0aWYoKHR5cGUgJiYgdHlwZS5pbmRleE9mKCdqc29uJykgIT09IC0xKSB8fCB0eXBlb2YgZCA9PT0gXCJvYmplY3RcIikge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRoaXMuX2FwcGVuZF9qc29uX2RhdGEob2JqLCBkLCBmdW5jdGlvbiAoc3RhdHVzKSB7IGNhbGxiYWNrLmNhbGwodGhpcywgc3RhdHVzKTsgfSk7XG5cdFx0XHRcdFx0XHRcdFx0XHQvL3JldHVybiBjYWxsYmFjay5jYWxsKHRoaXMsIHRoaXMuX2FwcGVuZF9qc29uX2RhdGEob2JqLCBkKSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlmKCh0eXBlICYmIHR5cGUuaW5kZXhPZignaHRtbCcpICE9PSAtMSkgfHwgdHlwZW9mIGQgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiB0aGlzLl9hcHBlbmRfaHRtbF9kYXRhKG9iaiwgJCgkLnBhcnNlSFRNTChkKSkuZmlsdGVyKG5vdFRleHRPckNvbW1lbnROb2RlKSwgZnVuY3Rpb24gKHN0YXR1cykgeyBjYWxsYmFjay5jYWxsKHRoaXMsIHN0YXR1cyk7IH0pO1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gcmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgdGhpcy5fYXBwZW5kX2h0bWxfZGF0YShvYmosICQoZCkpKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IgPSB7ICdlcnJvcicgOiAnYWpheCcsICdwbHVnaW4nIDogJ2NvcmUnLCAnaWQnIDogJ2NvcmVfMDQnLCAncmVhc29uJyA6ICdDb3VsZCBub3QgbG9hZCBub2RlJywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoeyAnaWQnIDogb2JqLmlkLCAneGhyJyA6IHggfSkgfTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNldHRpbmdzLmNvcmUuZXJyb3IuY2FsbCh0aGlzLCB0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvcik7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpO1xuXHRcdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdFx0XHQuZmFpbChmdW5jdGlvbiAoZikge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2FqYXgnLCAncGx1Z2luJyA6ICdjb3JlJywgJ2lkJyA6ICdjb3JlXzA0JywgJ3JlYXNvbicgOiAnQ291bGQgbm90IGxvYWQgbm9kZScsICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2lkJyA6IG9iai5pZCwgJ3hocicgOiBmIH0pIH07XG5cdFx0XHRcdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCh0aGlzLCBmYWxzZSk7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5jb3JlLmVycm9yLmNhbGwodGhpcywgdGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IpO1xuXHRcdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICgkLnZha2F0YS5pc19hcnJheShzKSkge1xuXHRcdFx0XHRcdHQgPSAkLmV4dGVuZCh0cnVlLCBbXSwgcyk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoJC5pc1BsYWluT2JqZWN0KHMpKSB7XG5cdFx0XHRcdFx0dCA9ICQuZXh0ZW5kKHRydWUsIHt9LCBzKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0ID0gcztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZihvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5fYXBwZW5kX2pzb25fZGF0YShvYmosIHQsIGZ1bmN0aW9uIChzdGF0dXMpIHtcblx0XHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwodGhpcywgc3RhdHVzKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvciA9IHsgJ2Vycm9yJyA6ICdub2RhdGEnLCAncGx1Z2luJyA6ICdjb3JlJywgJ2lkJyA6ICdjb3JlXzA1JywgJ3JlYXNvbicgOiAnQ291bGQgbm90IGxvYWQgbm9kZScsICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2lkJyA6IG9iai5pZCB9KSB9O1xuXHRcdFx0XHRcdHRoaXMuc2V0dGluZ3MuY29yZS5lcnJvci5jYWxsKHRoaXMsIHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yKTtcblx0XHRcdFx0XHRyZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzLCBmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly9yZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzLCAob2JqLmlkID09PSAkLmpzdHJlZS5yb290ID8gdGhpcy5fYXBwZW5kX2pzb25fZGF0YShvYmosIHQpIDogZmFsc2UpICk7XG5cdFx0XHR9XG5cdFx0XHRpZih0eXBlb2YgcyA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0aWYob2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuX2FwcGVuZF9odG1sX2RhdGEob2JqLCAkKCQucGFyc2VIVE1MKHMpKS5maWx0ZXIobm90VGV4dE9yQ29tbWVudE5vZGUpLCBmdW5jdGlvbiAoc3RhdHVzKSB7XG5cdFx0XHRcdFx0XHRjYWxsYmFjay5jYWxsKHRoaXMsIHN0YXR1cyk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IgPSB7ICdlcnJvcicgOiAnbm9kYXRhJywgJ3BsdWdpbicgOiAnY29yZScsICdpZCcgOiAnY29yZV8wNicsICdyZWFzb24nIDogJ0NvdWxkIG5vdCBsb2FkIG5vZGUnLCAnZGF0YScgOiBKU09OLnN0cmluZ2lmeSh7ICdpZCcgOiBvYmouaWQgfSkgfTtcblx0XHRcdFx0XHR0aGlzLnNldHRpbmdzLmNvcmUuZXJyb3IuY2FsbCh0aGlzLCB0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvcik7XG5cdFx0XHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vcmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgKG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCA/IHRoaXMuX2FwcGVuZF9odG1sX2RhdGEob2JqLCAkKHMpKSA6IGZhbHNlKSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpcywgZmFsc2UpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogYWRkcyBhIG5vZGUgdG8gdGhlIGxpc3Qgb2Ygbm9kZXMgdG8gcmVkcmF3LiBVc2VkIG9ubHkgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9ub2RlX2NoYW5nZWQob2JqIFssIGNhbGxiYWNrXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICovXG5cdFx0X25vZGVfY2hhbmdlZCA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcbiAgICAgIGlmIChvYmogJiYgJC5pbkFycmF5KG9iai5pZCwgdGhpcy5fbW9kZWwuY2hhbmdlZCkgPT09IC0xKSB7XG5cdFx0XHRcdHRoaXMuX21vZGVsLmNoYW5nZWQucHVzaChvYmouaWQpO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogYXBwZW5kcyBIVE1MIGNvbnRlbnQgdG8gdGhlIHRyZWUuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9hcHBlbmRfaHRtbF9kYXRhKG9iaiwgZGF0YSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqIHRoZSBub2RlIHRvIGFwcGVuZCB0b1xuXHRcdCAqIEBwYXJhbSAge1N0cmluZ30gZGF0YSB0aGUgSFRNTCBzdHJpbmcgdG8gcGFyc2UgYW5kIGFwcGVuZFxuXHRcdCAqIEB0cmlnZ2VyIG1vZGVsLmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRfYXBwZW5kX2h0bWxfZGF0YSA6IGZ1bmN0aW9uIChkb20sIGRhdGEsIGNiKSB7XG5cdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKGRvbSk7XG5cdFx0XHRkb20uY2hpbGRyZW4gPSBbXTtcblx0XHRcdGRvbS5jaGlsZHJlbl9kID0gW107XG5cdFx0XHR2YXIgZGF0ID0gZGF0YS5pcygndWwnKSA/IGRhdGEuY2hpbGRyZW4oKSA6IGRhdGEsXG5cdFx0XHRcdHBhciA9IGRvbS5pZCxcblx0XHRcdFx0Y2hkID0gW10sXG5cdFx0XHRcdGRwYyA9IFtdLFxuXHRcdFx0XHRtID0gdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0cCA9IG1bcGFyXSxcblx0XHRcdFx0cyA9IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5sZW5ndGgsXG5cdFx0XHRcdHRtcCwgaSwgajtcblx0XHRcdGRhdC5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdHRtcCA9IHRoaXMuX3BhcnNlX21vZGVsX2Zyb21faHRtbCgkKHYpLCBwYXIsIHAucGFyZW50cy5jb25jYXQoKSk7XG5cdFx0XHRcdGlmKHRtcCkge1xuXHRcdFx0XHRcdGNoZC5wdXNoKHRtcCk7XG5cdFx0XHRcdFx0ZHBjLnB1c2godG1wKTtcblx0XHRcdFx0XHRpZihtW3RtcF0uY2hpbGRyZW5fZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGRwYyA9IGRwYy5jb25jYXQobVt0bXBdLmNoaWxkcmVuX2QpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdHAuY2hpbGRyZW4gPSBjaGQ7XG5cdFx0XHRwLmNoaWxkcmVuX2QgPSBkcGM7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBwLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdG1bcC5wYXJlbnRzW2ldXS5jaGlsZHJlbl9kID0gbVtwLnBhcmVudHNbaV1dLmNoaWxkcmVuX2QuY29uY2F0KGRwYyk7XG5cdFx0XHR9XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIG5ldyBkYXRhIGlzIGluc2VydGVkIHRvIHRoZSB0cmVlIG1vZGVsXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIG1vZGVsLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZXMgYW4gYXJyYXkgb2Ygbm9kZSBJRHNcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXJlbnQgdGhlIHBhcmVudCBJRCBvZiB0aGUgbm9kZXNcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdtb2RlbCcsIHsgXCJub2Rlc1wiIDogZHBjLCAncGFyZW50JyA6IHBhciB9KTtcblx0XHRcdGlmKHBhciAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHR0aGlzLl9ub2RlX2NoYW5nZWQocGFyKTtcblx0XHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHR0aGlzLmdldF9jb250YWluZXJfdWwoKS5jaGlsZHJlbignLmpzdHJlZS1pbml0aWFsLW5vZGUnKS5yZW1vdmUoKTtcblx0XHRcdFx0dGhpcy5yZWRyYXcodHJ1ZSk7XG5cdFx0XHR9XG5cdFx0XHRpZih0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQubGVuZ3RoICE9PSBzKSB7XG5cdFx0XHRcdHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHsgJ2FjdGlvbicgOiAnbW9kZWwnLCAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkIH0pO1xuXHRcdFx0fVxuXHRcdFx0Y2IuY2FsbCh0aGlzLCB0cnVlKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGFwcGVuZHMgSlNPTiBjb250ZW50IHRvIHRoZSB0cmVlLiBVc2VkIGludGVybmFsbHkuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBfYXBwZW5kX2pzb25fZGF0YShvYmosIGRhdGEpXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBhcHBlbmQgdG9cblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGEgdGhlIEpTT04gb2JqZWN0IHRvIHBhcnNlIGFuZCBhcHBlbmRcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBmb3JjZV9wcm9jZXNzaW5nIGludGVybmFsIHBhcmFtIC0gZG8gbm90IHNldFxuXHRcdCAqIEB0cmlnZ2VyIG1vZGVsLmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRfYXBwZW5kX2pzb25fZGF0YSA6IGZ1bmN0aW9uIChkb20sIGRhdGEsIGNiLCBmb3JjZV9wcm9jZXNzaW5nKSB7XG5cdFx0XHRpZih0aGlzLmVsZW1lbnQgPT09IG51bGwpIHsgcmV0dXJuOyB9XG5cdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKGRvbSk7XG5cdFx0XHRkb20uY2hpbGRyZW4gPSBbXTtcblx0XHRcdGRvbS5jaGlsZHJlbl9kID0gW107XG5cdFx0XHQvLyAqJSRAISEhXG5cdFx0XHRpZihkYXRhLmQpIHtcblx0XHRcdFx0ZGF0YSA9IGRhdGEuZDtcblx0XHRcdFx0aWYodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdFx0XHRkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoISQudmFrYXRhLmlzX2FycmF5KGRhdGEpKSB7IGRhdGEgPSBbZGF0YV07IH1cblx0XHRcdHZhciB3ID0gbnVsbCxcblx0XHRcdFx0YXJncyA9IHtcblx0XHRcdFx0XHQnZGYnXHQ6IHRoaXMuX21vZGVsLmRlZmF1bHRfc3RhdGUsXG5cdFx0XHRcdFx0J2RhdCdcdDogZGF0YSxcblx0XHRcdFx0XHQncGFyJ1x0OiBkb20uaWQsXG5cdFx0XHRcdFx0J20nXHRcdDogdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0XHQndF9pZCdcdDogdGhpcy5faWQsXG5cdFx0XHRcdFx0J3RfY250J1x0OiB0aGlzLl9jbnQsXG5cdFx0XHRcdFx0J3NlbCdcdDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGluc3QgPSB0aGlzLFxuXHRcdFx0XHRmdW5jID0gZnVuY3Rpb24gKGRhdGEsIHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdGlmKGRhdGEuZGF0YSkgeyBkYXRhID0gZGF0YS5kYXRhOyB9XG5cdFx0XHRcdFx0dmFyIGRhdCA9IGRhdGEuZGF0LFxuXHRcdFx0XHRcdFx0cGFyID0gZGF0YS5wYXIsXG5cdFx0XHRcdFx0XHRjaGQgPSBbXSxcblx0XHRcdFx0XHRcdGRwYyA9IFtdLFxuXHRcdFx0XHRcdFx0YWRkID0gW10sXG5cdFx0XHRcdFx0XHRkZiA9IGRhdGEuZGYsXG5cdFx0XHRcdFx0XHR0X2lkID0gZGF0YS50X2lkLFxuXHRcdFx0XHRcdFx0dF9jbnQgPSBkYXRhLnRfY250LFxuXHRcdFx0XHRcdFx0bSA9IGRhdGEubSxcblx0XHRcdFx0XHRcdHAgPSBtW3Bhcl0sXG5cdFx0XHRcdFx0XHRzZWwgPSBkYXRhLnNlbCxcblx0XHRcdFx0XHRcdHRtcCwgaSwgaiwgcnNsdCxcblx0XHRcdFx0XHRcdHBhcnNlX2ZsYXQgPSBmdW5jdGlvbiAoZCwgcCwgcHMpIHtcblx0XHRcdFx0XHRcdFx0aWYoIXBzKSB7IHBzID0gW107IH1cblx0XHRcdFx0XHRcdFx0ZWxzZSB7IHBzID0gcHMuY29uY2F0KCk7IH1cblx0XHRcdFx0XHRcdFx0aWYocCkgeyBwcy51bnNoaWZ0KHApOyB9XG5cdFx0XHRcdFx0XHRcdHZhciB0aWQgPSBkLmlkLnRvU3RyaW5nKCksXG5cdFx0XHRcdFx0XHRcdFx0aSwgaiwgYywgZSxcblx0XHRcdFx0XHRcdFx0XHR0bXAgPSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZFx0XHRcdDogdGlkLFxuXHRcdFx0XHRcdFx0XHRcdFx0dGV4dFx0XHQ6IGQudGV4dCB8fCAnJyxcblx0XHRcdFx0XHRcdFx0XHRcdGljb25cdFx0OiBkLmljb24gIT09IHVuZGVmaW5lZCA/IGQuaWNvbiA6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0XHRwYXJlbnRcdFx0OiBwLFxuXHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50c1x0XHQ6IHBzLFxuXHRcdFx0XHRcdFx0XHRcdFx0Y2hpbGRyZW5cdDogZC5jaGlsZHJlbiB8fCBbXSxcblx0XHRcdFx0XHRcdFx0XHRcdGNoaWxkcmVuX2RcdDogZC5jaGlsZHJlbl9kIHx8IFtdLFxuXHRcdFx0XHRcdFx0XHRcdFx0ZGF0YVx0XHQ6IGQuZGF0YSxcblx0XHRcdFx0XHRcdFx0XHRcdHN0YXRlXHRcdDogeyB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0bGlfYXR0clx0XHQ6IHsgaWQgOiBmYWxzZSB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0YV9hdHRyXHRcdDogeyBocmVmIDogJyMnIH0sXG5cdFx0XHRcdFx0XHRcdFx0XHRvcmlnaW5hbFx0OiBmYWxzZVxuXHRcdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRcdGZvcihpIGluIGRmKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoZGYuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5zdGF0ZVtpXSA9IGRmW2ldO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihkICYmIGQuZGF0YSAmJiBkLmRhdGEuanN0cmVlICYmIGQuZGF0YS5qc3RyZWUuaWNvbikge1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5pY29uID0gZC5kYXRhLmpzdHJlZS5pY29uO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKHRtcC5pY29uID09PSB1bmRlZmluZWQgfHwgdG1wLmljb24gPT09IG51bGwgfHwgdG1wLmljb24gPT09IFwiXCIpIHtcblx0XHRcdFx0XHRcdFx0XHR0bXAuaWNvbiA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYoZCAmJiBkLmRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHR0bXAuZGF0YSA9IGQuZGF0YTtcblx0XHRcdFx0XHRcdFx0XHRpZihkLmRhdGEuanN0cmVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmb3IoaSBpbiBkLmRhdGEuanN0cmVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKGQuZGF0YS5qc3RyZWUuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAuc3RhdGVbaV0gPSBkLmRhdGEuanN0cmVlW2ldO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgdHlwZW9mIGQuc3RhdGUgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yIChpIGluIGQuc3RhdGUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKGQuc3RhdGUuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLnN0YXRlW2ldID0gZC5zdGF0ZVtpXTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYoZCAmJiB0eXBlb2YgZC5saV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRcdFx0XHRcdGZvciAoaSBpbiBkLmxpX2F0dHIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKGQubGlfYXR0ci5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAubGlfYXR0cltpXSA9IGQubGlfYXR0cltpXTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYoIXRtcC5saV9hdHRyLmlkKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLmxpX2F0dHIuaWQgPSB0aWQ7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYoZCAmJiB0eXBlb2YgZC5hX2F0dHIgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yIChpIGluIGQuYV9hdHRyKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZihkLmFfYXR0ci5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAuYV9hdHRyW2ldID0gZC5hX2F0dHJbaV07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgZC5jaGlsZHJlbiAmJiBkLmNoaWxkcmVuID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLnN0YXRlLmxvYWRlZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbiA9IFtdO1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbl9kID0gW107XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0bVt0bXAuaWRdID0gdG1wO1xuXHRcdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSB0bXAuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0YyA9IHBhcnNlX2ZsYXQobVt0bXAuY2hpbGRyZW5baV1dLCB0bXAuaWQsIHBzKTtcblx0XHRcdFx0XHRcdFx0XHRlID0gbVtjXTtcblx0XHRcdFx0XHRcdFx0XHR0bXAuY2hpbGRyZW5fZC5wdXNoKGMpO1xuXHRcdFx0XHRcdFx0XHRcdGlmKGUuY2hpbGRyZW5fZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbl9kID0gdG1wLmNoaWxkcmVuX2QuY29uY2F0KGUuY2hpbGRyZW5fZCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBkLmRhdGE7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBkLmNoaWxkcmVuO1xuXHRcdFx0XHRcdFx0XHRtW3RtcC5pZF0ub3JpZ2luYWwgPSBkO1xuXHRcdFx0XHRcdFx0XHRpZih0bXAuc3RhdGUuc2VsZWN0ZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRhZGQucHVzaCh0bXAuaWQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0bXAuaWQ7XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0cGFyc2VfbmVzdCA9IGZ1bmN0aW9uIChkLCBwLCBwcykge1xuXHRcdFx0XHRcdFx0XHRpZighcHMpIHsgcHMgPSBbXTsgfVxuXHRcdFx0XHRcdFx0XHRlbHNlIHsgcHMgPSBwcy5jb25jYXQoKTsgfVxuXHRcdFx0XHRcdFx0XHRpZihwKSB7IHBzLnVuc2hpZnQocCk7IH1cblx0XHRcdFx0XHRcdFx0dmFyIHRpZCA9IGZhbHNlLCBpLCBqLCBjLCBlLCB0bXA7XG5cdFx0XHRcdFx0XHRcdGRvIHtcblx0XHRcdFx0XHRcdFx0XHR0aWQgPSAnaicgKyB0X2lkICsgJ18nICsgKCsrdF9jbnQpO1xuXHRcdFx0XHRcdFx0XHR9IHdoaWxlKG1bdGlkXSk7XG5cblx0XHRcdFx0XHRcdFx0dG1wID0ge1xuXHRcdFx0XHRcdFx0XHRcdGlkXHRcdFx0OiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0XHR0ZXh0XHRcdDogdHlwZW9mIGQgPT09ICdzdHJpbmcnID8gZCA6ICcnLFxuXHRcdFx0XHRcdFx0XHRcdGljb25cdFx0OiB0eXBlb2YgZCA9PT0gJ29iamVjdCcgJiYgZC5pY29uICE9PSB1bmRlZmluZWQgPyBkLmljb24gOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHBhcmVudFx0XHQ6IHAsXG5cdFx0XHRcdFx0XHRcdFx0cGFyZW50c1x0XHQ6IHBzLFxuXHRcdFx0XHRcdFx0XHRcdGNoaWxkcmVuXHQ6IFtdLFxuXHRcdFx0XHRcdFx0XHRcdGNoaWxkcmVuX2RcdDogW10sXG5cdFx0XHRcdFx0XHRcdFx0ZGF0YVx0XHQ6IG51bGwsXG5cdFx0XHRcdFx0XHRcdFx0c3RhdGVcdFx0OiB7IH0sXG5cdFx0XHRcdFx0XHRcdFx0bGlfYXR0clx0XHQ6IHsgaWQgOiBmYWxzZSB9LFxuXHRcdFx0XHRcdFx0XHRcdGFfYXR0clx0XHQ6IHsgaHJlZiA6ICcjJyB9LFxuXHRcdFx0XHRcdFx0XHRcdG9yaWdpbmFsXHQ6IGZhbHNlXG5cdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRcdGZvcihpIGluIGRmKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoZGYuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5zdGF0ZVtpXSA9IGRmW2ldO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihkICYmIGQuaWQpIHsgdG1wLmlkID0gZC5pZC50b1N0cmluZygpOyB9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgZC50ZXh0KSB7IHRtcC50ZXh0ID0gZC50ZXh0OyB9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgZC5kYXRhICYmIGQuZGF0YS5qc3RyZWUgJiYgZC5kYXRhLmpzdHJlZS5pY29uKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLmljb24gPSBkLmRhdGEuanN0cmVlLmljb247XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYodG1wLmljb24gPT09IHVuZGVmaW5lZCB8fCB0bXAuaWNvbiA9PT0gbnVsbCB8fCB0bXAuaWNvbiA9PT0gXCJcIikge1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5pY29uID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihkICYmIGQuZGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5kYXRhID0gZC5kYXRhO1xuXHRcdFx0XHRcdFx0XHRcdGlmKGQuZGF0YS5qc3RyZWUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZvcihpIGluIGQuZGF0YS5qc3RyZWUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYoZC5kYXRhLmpzdHJlZS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRtcC5zdGF0ZVtpXSA9IGQuZGF0YS5qc3RyZWVbaV07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYoZCAmJiB0eXBlb2YgZC5zdGF0ZSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHRcdFx0XHRmb3IgKGkgaW4gZC5zdGF0ZSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYoZC5zdGF0ZS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAuc3RhdGVbaV0gPSBkLnN0YXRlW2ldO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihkICYmIHR5cGVvZiBkLmxpX2F0dHIgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yIChpIGluIGQubGlfYXR0cikge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYoZC5saV9hdHRyLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRtcC5saV9hdHRyW2ldID0gZC5saV9hdHRyW2ldO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZih0bXAubGlfYXR0ci5pZCAmJiAhdG1wLmlkKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLmlkID0gdG1wLmxpX2F0dHIuaWQudG9TdHJpbmcoKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZighdG1wLmlkKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLmlkID0gdGlkO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKCF0bXAubGlfYXR0ci5pZCkge1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5saV9hdHRyLmlkID0gdG1wLmlkO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgdHlwZW9mIGQuYV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRcdFx0XHRcdGZvciAoaSBpbiBkLmFfYXR0cikge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYoZC5hX2F0dHIuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLmFfYXR0cltpXSA9IGQuYV9hdHRyW2ldO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihkICYmIGQuY2hpbGRyZW4gJiYgZC5jaGlsZHJlbi5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBkLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0YyA9IHBhcnNlX25lc3QoZC5jaGlsZHJlbltpXSwgdG1wLmlkLCBwcyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRlID0gbVtjXTtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbi5wdXNoKGMpO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYoZS5jaGlsZHJlbl9kLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAuY2hpbGRyZW5fZCA9IHRtcC5jaGlsZHJlbl9kLmNvbmNhdChlLmNoaWxkcmVuX2QpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR0bXAuY2hpbGRyZW5fZCA9IHRtcC5jaGlsZHJlbl9kLmNvbmNhdCh0bXAuY2hpbGRyZW4pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgZC5jaGlsZHJlbiAmJiBkLmNoaWxkcmVuID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0dG1wLnN0YXRlLmxvYWRlZCA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbiA9IFtdO1xuXHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbl9kID0gW107XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZGVsZXRlIGQuZGF0YTtcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIGQuY2hpbGRyZW47XG5cdFx0XHRcdFx0XHRcdHRtcC5vcmlnaW5hbCA9IGQ7XG5cdFx0XHRcdFx0XHRcdG1bdG1wLmlkXSA9IHRtcDtcblx0XHRcdFx0XHRcdFx0aWYodG1wLnN0YXRlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRcdFx0YWRkLnB1c2godG1wLmlkKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdG1wLmlkO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGlmKGRhdC5sZW5ndGggJiYgZGF0WzBdLmlkICE9PSB1bmRlZmluZWQgJiYgZGF0WzBdLnBhcmVudCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHQvLyBGbGF0IEpTT04gc3VwcG9ydCAoZm9yIGVhc3kgaW1wb3J0IGZyb20gREIpOlxuXHRcdFx0XHRcdFx0Ly8gMSkgY29udmVydCB0byBvYmplY3QgKGZvcmVhY2gpXG5cdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBkYXQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdGlmKCFkYXRbaV0uY2hpbGRyZW4pIHtcblx0XHRcdFx0XHRcdFx0XHRkYXRbaV0uY2hpbGRyZW4gPSBbXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZighZGF0W2ldLnN0YXRlKSB7XG5cdFx0XHRcdFx0XHRcdFx0ZGF0W2ldLnN0YXRlID0ge307XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0bVtkYXRbaV0uaWQudG9TdHJpbmcoKV0gPSBkYXRbaV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHQvLyAyKSBwb3B1bGF0ZSBjaGlsZHJlbiAoZm9yZWFjaClcblx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IGRhdC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0aWYgKCFtW2RhdFtpXS5wYXJlbnQudG9TdHJpbmcoKV0pIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAodHlwZW9mIGluc3QgIT09IFwidW5kZWZpbmVkXCIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGluc3QuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ3BhcnNlJywgJ3BsdWdpbicgOiAnY29yZScsICdpZCcgOiAnY29yZV8wNycsICdyZWFzb24nIDogJ05vZGUgd2l0aCBpbnZhbGlkIHBhcmVudCcsICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2lkJyA6IGRhdFtpXS5pZC50b1N0cmluZygpLCAncGFyZW50JyA6IGRhdFtpXS5wYXJlbnQudG9TdHJpbmcoKSB9KSB9O1xuXHRcdFx0XHRcdFx0XHRcdFx0aW5zdC5zZXR0aW5ncy5jb3JlLmVycm9yLmNhbGwoaW5zdCwgaW5zdC5fZGF0YS5jb3JlLmxhc3RfZXJyb3IpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdG1bZGF0W2ldLnBhcmVudC50b1N0cmluZygpXS5jaGlsZHJlbi5wdXNoKGRhdFtpXS5pZC50b1N0cmluZygpKTtcblx0XHRcdFx0XHRcdFx0Ly8gcG9wdWxhdGUgcGFyZW50LmNoaWxkcmVuX2Rcblx0XHRcdFx0XHRcdFx0cC5jaGlsZHJlbl9kLnB1c2goZGF0W2ldLmlkLnRvU3RyaW5nKCkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gMykgbm9ybWFsaXplICYmIHBvcHVsYXRlIHBhcmVudHMgYW5kIGNoaWxkcmVuX2Qgd2l0aCByZWN1cnNpb25cblx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IHAuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdHRtcCA9IHBhcnNlX2ZsYXQobVtwLmNoaWxkcmVuW2ldXSwgcGFyLCBwLnBhcmVudHMuY29uY2F0KCkpO1xuXHRcdFx0XHRcdFx0XHRkcGMucHVzaCh0bXApO1xuXHRcdFx0XHRcdFx0XHRpZihtW3RtcF0uY2hpbGRyZW5fZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRkcGMgPSBkcGMuY29uY2F0KG1bdG1wXS5jaGlsZHJlbl9kKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gcC5wYXJlbnRzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRtW3AucGFyZW50c1tpXV0uY2hpbGRyZW5fZCA9IG1bcC5wYXJlbnRzW2ldXS5jaGlsZHJlbl9kLmNvbmNhdChkcGMpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gPykgdGhyZWVfc3RhdGUgc2VsZWN0aW9uIC0gcC5zdGF0ZS5zZWxlY3RlZCAmJiB0IC0gKGlmIHRocmVlX3N0YXRlIGZvcmVhY2goZGF0ID0+IGNoKSAtPiBmb3JlYWNoKHBhcmVudHMpIGlmKHBhcmVudC5zZWxlY3RlZCkgY2hpbGQuc2VsZWN0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0cnNsdCA9IHtcblx0XHRcdFx0XHRcdFx0J2NudCcgOiB0X2NudCxcblx0XHRcdFx0XHRcdFx0J21vZCcgOiBtLFxuXHRcdFx0XHRcdFx0XHQnc2VsJyA6IHNlbCxcblx0XHRcdFx0XHRcdFx0J3BhcicgOiBwYXIsXG5cdFx0XHRcdFx0XHRcdCdkcGMnIDogZHBjLFxuXHRcdFx0XHRcdFx0XHQnYWRkJyA6IGFkZFxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBkYXQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdHRtcCA9IHBhcnNlX25lc3QoZGF0W2ldLCBwYXIsIHAucGFyZW50cy5jb25jYXQoKSk7XG5cdFx0XHRcdFx0XHRcdGlmKHRtcCkge1xuXHRcdFx0XHRcdFx0XHRcdGNoZC5wdXNoKHRtcCk7XG5cdFx0XHRcdFx0XHRcdFx0ZHBjLnB1c2godG1wKTtcblx0XHRcdFx0XHRcdFx0XHRpZihtW3RtcF0uY2hpbGRyZW5fZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGRwYyA9IGRwYy5jb25jYXQobVt0bXBdLmNoaWxkcmVuX2QpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cC5jaGlsZHJlbiA9IGNoZDtcblx0XHRcdFx0XHRcdHAuY2hpbGRyZW5fZCA9IGRwYztcblx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IHAucGFyZW50cy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0bVtwLnBhcmVudHNbaV1dLmNoaWxkcmVuX2QgPSBtW3AucGFyZW50c1tpXV0uY2hpbGRyZW5fZC5jb25jYXQoZHBjKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJzbHQgPSB7XG5cdFx0XHRcdFx0XHRcdCdjbnQnIDogdF9jbnQsXG5cdFx0XHRcdFx0XHRcdCdtb2QnIDogbSxcblx0XHRcdFx0XHRcdFx0J3NlbCcgOiBzZWwsXG5cdFx0XHRcdFx0XHRcdCdwYXInIDogcGFyLFxuXHRcdFx0XHRcdFx0XHQnZHBjJyA6IGRwYyxcblx0XHRcdFx0XHRcdFx0J2FkZCcgOiBhZGRcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHRwb3N0TWVzc2FnZShyc2x0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcnNsdDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHJzbHQgPSBmdW5jdGlvbiAocnNsdCwgd29ya2VyKSB7XG5cdFx0XHRcdFx0aWYodGhpcy5lbGVtZW50ID09PSBudWxsKSB7IHJldHVybjsgfVxuXHRcdFx0XHRcdHRoaXMuX2NudCA9IHJzbHQuY250O1xuXHRcdFx0XHRcdHZhciBpLCBtID0gdGhpcy5fbW9kZWwuZGF0YTtcblx0XHRcdFx0XHRmb3IgKGkgaW4gbSkge1xuXHRcdFx0XHRcdFx0aWYgKG0uaGFzT3duUHJvcGVydHkoaSkgJiYgbVtpXS5zdGF0ZSAmJiBtW2ldLnN0YXRlLmxvYWRpbmcgJiYgcnNsdC5tb2RbaV0pIHtcblx0XHRcdFx0XHRcdFx0cnNsdC5tb2RbaV0uc3RhdGUubG9hZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuX21vZGVsLmRhdGEgPSByc2x0Lm1vZDsgLy8gYnJlYWtzIHRoZSByZWZlcmVuY2UgaW4gbG9hZF9ub2RlIC0gY2FyZWZ1bFxuXG5cdFx0XHRcdFx0aWYod29ya2VyKSB7XG5cdFx0XHRcdFx0XHR2YXIgaiwgYSA9IHJzbHQuYWRkLCByID0gcnNsdC5zZWwsIHMgPSB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQuc2xpY2UoKTtcblx0XHRcdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhO1xuXHRcdFx0XHRcdFx0Ly8gaWYgc2VsZWN0aW9uIHdhcyBjaGFuZ2VkIHdoaWxlIGNhbGN1bGF0aW5nIGluIHdvcmtlclxuXHRcdFx0XHRcdFx0aWYoci5sZW5ndGggIT09IHMubGVuZ3RoIHx8ICQudmFrYXRhLmFycmF5X3VuaXF1ZShyLmNvbmNhdChzKSkubGVuZ3RoICE9PSByLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHQvLyBkZXNlbGVjdCBub2RlcyB0aGF0IGFyZSBubyBsb25nZXIgc2VsZWN0ZWRcblx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gci5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRpZigkLmluQXJyYXkocltpXSwgYSkgPT09IC0xICYmICQuaW5BcnJheShyW2ldLCBzKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdFx0XHRcdG1bcltpXV0uc3RhdGUuc2VsZWN0ZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0Ly8gc2VsZWN0IG5vZGVzIHRoYXQgd2VyZSBzZWxlY3RlZCBpbiB0aGUgbWVhbiB0aW1lXG5cdFx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYoJC5pbkFycmF5KHNbaV0sIHIpID09PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bVtzW2ldXS5zdGF0ZS5zZWxlY3RlZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKHJzbHQuYWRkLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdChyc2x0LmFkZCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGhpcy50cmlnZ2VyKCdtb2RlbCcsIHsgXCJub2Rlc1wiIDogcnNsdC5kcGMsICdwYXJlbnQnIDogcnNsdC5wYXIgfSk7XG5cblx0XHRcdFx0XHRpZihyc2x0LnBhciAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fbm9kZV9jaGFuZ2VkKHJzbHQucGFyKTtcblx0XHRcdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gdGhpcy5nZXRfY29udGFpbmVyX3VsKCkuY2hpbGRyZW4oJy5qc3RyZWUtaW5pdGlhbC1ub2RlJykucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHR0aGlzLnJlZHJhdyh0cnVlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYocnNsdC5hZGQubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2NoYW5nZWQnLCB7ICdhY3Rpb24nIDogJ21vZGVsJywgJ3NlbGVjdGVkJyA6IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZCB9KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBJZiBubyB3b3JrZXIsIHRyeSB0byBtaW1pYyB3b3JrZXIgYmVoYXZpb291ciwgYnkgaW52b2tpbmcgY2IgYXN5bmNocm9ub3VzbHlcblx0XHRcdFx0XHRpZiAoIXdvcmtlciAmJiBzZXRJbW1lZGlhdGUpIHtcblx0XHRcdFx0XHRcdHNldEltbWVkaWF0ZShmdW5jdGlvbigpe1xuXHRcdFx0XHRcdFx0XHRjYi5jYWxsKGluc3QsIHRydWUpO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2IuY2FsbChpbnN0LCB0cnVlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNvcmUud29ya2VyICYmIHdpbmRvdy5CbG9iICYmIHdpbmRvdy5VUkwgJiYgd2luZG93Lldvcmtlcikge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGlmKHRoaXMuX3dyayA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fd3JrID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoXG5cdFx0XHRcdFx0XHRcdG5ldyB3aW5kb3cuQmxvYihcblx0XHRcdFx0XHRcdFx0XHRbJ3NlbGYub25tZXNzYWdlID0gJyArIGZ1bmMudG9TdHJpbmcoKV0sXG5cdFx0XHRcdFx0XHRcdFx0e3R5cGU6XCJ0ZXh0L2phdmFzY3JpcHRcIn1cblx0XHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYoIXRoaXMuX2RhdGEuY29yZS53b3JraW5nIHx8IGZvcmNlX3Byb2Nlc3NpbmcpIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS53b3JraW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHcgPSBuZXcgd2luZG93Lldvcmtlcih0aGlzLl93cmspO1xuXHRcdFx0XHRcdFx0dy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0XHRyc2x0LmNhbGwodGhpcywgZS5kYXRhLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0dHJ5IHsgdy50ZXJtaW5hdGUoKTsgdyA9IG51bGw7IH0gY2F0Y2goaWdub3JlKSB7IH1cblx0XHRcdFx0XHRcdFx0aWYodGhpcy5fZGF0YS5jb3JlLndvcmtlcl9xdWV1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9hcHBlbmRfanNvbl9kYXRhLmFwcGx5KHRoaXMsIHRoaXMuX2RhdGEuY29yZS53b3JrZXJfcXVldWUuc2hpZnQoKSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLndvcmtpbmcgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpO1xuXHRcdFx0XHRcdFx0dy5vbmVycm9yID0gZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdFx0cnNsdC5jYWxsKHRoaXMsIGZ1bmMoYXJncyksIGZhbHNlKTtcblx0XHRcdFx0XHRcdFx0aWYodGhpcy5fZGF0YS5jb3JlLndvcmtlcl9xdWV1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9hcHBlbmRfanNvbl9kYXRhLmFwcGx5KHRoaXMsIHRoaXMuX2RhdGEuY29yZS53b3JrZXJfcXVldWUuc2hpZnQoKSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLndvcmtpbmcgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpO1xuXHRcdFx0XHRcdFx0aWYoIWFyZ3MucGFyKSB7XG5cdFx0XHRcdFx0XHRcdGlmKHRoaXMuX2RhdGEuY29yZS53b3JrZXJfcXVldWUubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5fYXBwZW5kX2pzb25fZGF0YS5hcHBseSh0aGlzLCB0aGlzLl9kYXRhLmNvcmUud29ya2VyX3F1ZXVlLnNoaWZ0KCkpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS53b3JraW5nID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHR3LnBvc3RNZXNzYWdlKGFyZ3MpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS53b3JrZXJfcXVldWUucHVzaChbZG9tLCBkYXRhLCBjYiwgdHJ1ZV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRjYXRjaChlKSB7XG5cdFx0XHRcdFx0cnNsdC5jYWxsKHRoaXMsIGZ1bmMoYXJncyksIGZhbHNlKTtcblx0XHRcdFx0XHRpZih0aGlzLl9kYXRhLmNvcmUud29ya2VyX3F1ZXVlLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fYXBwZW5kX2pzb25fZGF0YS5hcHBseSh0aGlzLCB0aGlzLl9kYXRhLmNvcmUud29ya2VyX3F1ZXVlLnNoaWZ0KCkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS53b3JraW5nID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0cnNsdC5jYWxsKHRoaXMsIGZ1bmMoYXJncyksIGZhbHNlKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHBhcnNlcyBhIG5vZGUgZnJvbSBhIGpRdWVyeSBvYmplY3QgYW5kIGFwcGVuZHMgdGhlbSB0byB0aGUgaW4gbWVtb3J5IHRyZWUgbW9kZWwuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9wYXJzZV9tb2RlbF9mcm9tX2h0bWwoZCBbLCBwLCBwc10pXG5cdFx0ICogQHBhcmFtICB7alF1ZXJ5fSBkIHRoZSBqUXVlcnkgb2JqZWN0IHRvIHBhcnNlXG5cdFx0ICogQHBhcmFtICB7U3RyaW5nfSBwIHRoZSBwYXJlbnQgSURcblx0XHQgKiBAcGFyYW0gIHtBcnJheX0gcHMgbGlzdCBvZiBhbGwgcGFyZW50c1xuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gdGhlIElEIG9mIHRoZSBvYmplY3QgYWRkZWQgdG8gdGhlIG1vZGVsXG5cdFx0ICovXG5cdFx0X3BhcnNlX21vZGVsX2Zyb21faHRtbCA6IGZ1bmN0aW9uIChkLCBwLCBwcykge1xuXHRcdFx0aWYoIXBzKSB7IHBzID0gW107IH1cblx0XHRcdGVsc2UgeyBwcyA9IFtdLmNvbmNhdChwcyk7IH1cblx0XHRcdGlmKHApIHsgcHMudW5zaGlmdChwKTsgfVxuXHRcdFx0dmFyIGMsIGUsIG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRkYXRhID0ge1xuXHRcdFx0XHRcdGlkXHRcdFx0OiBmYWxzZSxcblx0XHRcdFx0XHR0ZXh0XHRcdDogZmFsc2UsXG5cdFx0XHRcdFx0aWNvblx0XHQ6IHRydWUsXG5cdFx0XHRcdFx0cGFyZW50XHRcdDogcCxcblx0XHRcdFx0XHRwYXJlbnRzXHRcdDogcHMsXG5cdFx0XHRcdFx0Y2hpbGRyZW5cdDogW10sXG5cdFx0XHRcdFx0Y2hpbGRyZW5fZFx0OiBbXSxcblx0XHRcdFx0XHRkYXRhXHRcdDogbnVsbCxcblx0XHRcdFx0XHRzdGF0ZVx0XHQ6IHsgfSxcblx0XHRcdFx0XHRsaV9hdHRyXHRcdDogeyBpZCA6IGZhbHNlIH0sXG5cdFx0XHRcdFx0YV9hdHRyXHRcdDogeyBocmVmIDogJyMnIH0sXG5cdFx0XHRcdFx0b3JpZ2luYWxcdDogZmFsc2Vcblx0XHRcdFx0fSwgaSwgdG1wLCB0aWQ7XG5cdFx0XHRmb3IoaSBpbiB0aGlzLl9tb2RlbC5kZWZhdWx0X3N0YXRlKSB7XG5cdFx0XHRcdGlmKHRoaXMuX21vZGVsLmRlZmF1bHRfc3RhdGUuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRkYXRhLnN0YXRlW2ldID0gdGhpcy5fbW9kZWwuZGVmYXVsdF9zdGF0ZVtpXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dG1wID0gJC52YWthdGEuYXR0cmlidXRlcyhkLCB0cnVlKTtcblx0XHRcdCQuZWFjaCh0bXAsIGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdHYgPSAkLnZha2F0YS50cmltKHYpO1xuXHRcdFx0XHRpZighdi5sZW5ndGgpIHsgcmV0dXJuIHRydWU7IH1cblx0XHRcdFx0ZGF0YS5saV9hdHRyW2ldID0gdjtcblx0XHRcdFx0aWYoaSA9PT0gJ2lkJykge1xuXHRcdFx0XHRcdGRhdGEuaWQgPSB2LnRvU3RyaW5nKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0dG1wID0gZC5jaGlsZHJlbignYScpLmZpcnN0KCk7XG5cdFx0XHRpZih0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdHRtcCA9ICQudmFrYXRhLmF0dHJpYnV0ZXModG1wLCB0cnVlKTtcblx0XHRcdFx0JC5lYWNoKHRtcCwgZnVuY3Rpb24gKGksIHYpIHtcblx0XHRcdFx0XHR2ID0gJC52YWthdGEudHJpbSh2KTtcblx0XHRcdFx0XHRpZih2Lmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0ZGF0YS5hX2F0dHJbaV0gPSB2O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHR0bXAgPSBkLmNoaWxkcmVuKFwiYVwiKS5maXJzdCgpLmxlbmd0aCA/IGQuY2hpbGRyZW4oXCJhXCIpLmZpcnN0KCkuY2xvbmUoKSA6IGQuY2xvbmUoKTtcblx0XHRcdHRtcC5jaGlsZHJlbihcImlucywgaSwgdWxcIikucmVtb3ZlKCk7XG5cdFx0XHR0bXAgPSB0bXAuaHRtbCgpO1xuXHRcdFx0dG1wID0gJCgnPGRpdj48L2Rpdj4nKS5odG1sKHRtcCk7XG5cdFx0XHRkYXRhLnRleHQgPSB0aGlzLnNldHRpbmdzLmNvcmUuZm9yY2VfdGV4dCA/IHRtcC50ZXh0KCkgOiB0bXAuaHRtbCgpO1xuXHRcdFx0dG1wID0gZC5kYXRhKCk7XG5cdFx0XHRkYXRhLmRhdGEgPSB0bXAgPyAkLmV4dGVuZCh0cnVlLCB7fSwgdG1wKSA6IG51bGw7XG5cdFx0XHRkYXRhLnN0YXRlLm9wZW5lZCA9IGQuaGFzQ2xhc3MoJ2pzdHJlZS1vcGVuJyk7XG5cdFx0XHRkYXRhLnN0YXRlLnNlbGVjdGVkID0gZC5jaGlsZHJlbignYScpLmhhc0NsYXNzKCdqc3RyZWUtY2xpY2tlZCcpO1xuXHRcdFx0ZGF0YS5zdGF0ZS5kaXNhYmxlZCA9IGQuY2hpbGRyZW4oJ2EnKS5oYXNDbGFzcygnanN0cmVlLWRpc2FibGVkJyk7XG5cdFx0XHRpZihkYXRhLmRhdGEgJiYgZGF0YS5kYXRhLmpzdHJlZSkge1xuXHRcdFx0XHRmb3IoaSBpbiBkYXRhLmRhdGEuanN0cmVlKSB7XG5cdFx0XHRcdFx0aWYoZGF0YS5kYXRhLmpzdHJlZS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0ZGF0YS5zdGF0ZVtpXSA9IGRhdGEuZGF0YS5qc3RyZWVbaV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0bXAgPSBkLmNoaWxkcmVuKFwiYVwiKS5jaGlsZHJlbihcIi5qc3RyZWUtdGhlbWVpY29uXCIpO1xuXHRcdFx0aWYodG1wLmxlbmd0aCkge1xuXHRcdFx0XHRkYXRhLmljb24gPSB0bXAuaGFzQ2xhc3MoJ2pzdHJlZS10aGVtZWljb24taGlkZGVuJykgPyBmYWxzZSA6IHRtcC5hdHRyKCdyZWwnKTtcblx0XHRcdH1cblx0XHRcdGlmKGRhdGEuc3RhdGUuaWNvbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGRhdGEuaWNvbiA9IGRhdGEuc3RhdGUuaWNvbjtcblx0XHRcdH1cblx0XHRcdGlmKGRhdGEuaWNvbiA9PT0gdW5kZWZpbmVkIHx8IGRhdGEuaWNvbiA9PT0gbnVsbCB8fCBkYXRhLmljb24gPT09IFwiXCIpIHtcblx0XHRcdFx0ZGF0YS5pY29uID0gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdHRtcCA9IGQuY2hpbGRyZW4oXCJ1bFwiKS5jaGlsZHJlbihcImxpXCIpO1xuXHRcdFx0ZG8ge1xuXHRcdFx0XHR0aWQgPSAnaicgKyB0aGlzLl9pZCArICdfJyArICgrK3RoaXMuX2NudCk7XG5cdFx0XHR9IHdoaWxlKG1bdGlkXSk7XG5cdFx0XHRkYXRhLmlkID0gZGF0YS5saV9hdHRyLmlkID8gZGF0YS5saV9hdHRyLmlkLnRvU3RyaW5nKCkgOiB0aWQ7XG5cdFx0XHRpZih0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdHRtcC5lYWNoKGZ1bmN0aW9uIChpLCB2KSB7XG5cdFx0XHRcdFx0YyA9IHRoaXMuX3BhcnNlX21vZGVsX2Zyb21faHRtbCgkKHYpLCBkYXRhLmlkLCBwcyk7XG5cdFx0XHRcdFx0ZSA9IHRoaXMuX21vZGVsLmRhdGFbY107XG5cdFx0XHRcdFx0ZGF0YS5jaGlsZHJlbi5wdXNoKGMpO1xuXHRcdFx0XHRcdGlmKGUuY2hpbGRyZW5fZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGRhdGEuY2hpbGRyZW5fZCA9IGRhdGEuY2hpbGRyZW5fZC5jb25jYXQoZS5jaGlsZHJlbl9kKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHRcdGRhdGEuY2hpbGRyZW5fZCA9IGRhdGEuY2hpbGRyZW5fZC5jb25jYXQoZGF0YS5jaGlsZHJlbik7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0aWYoZC5oYXNDbGFzcygnanN0cmVlLWNsb3NlZCcpKSB7XG5cdFx0XHRcdFx0ZGF0YS5zdGF0ZS5sb2FkZWQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoZGF0YS5saV9hdHRyWydjbGFzcyddKSB7XG5cdFx0XHRcdGRhdGEubGlfYXR0clsnY2xhc3MnXSA9IGRhdGEubGlfYXR0clsnY2xhc3MnXS5yZXBsYWNlKCdqc3RyZWUtY2xvc2VkJywnJykucmVwbGFjZSgnanN0cmVlLW9wZW4nLCcnKTtcblx0XHRcdH1cblx0XHRcdGlmKGRhdGEuYV9hdHRyWydjbGFzcyddKSB7XG5cdFx0XHRcdGRhdGEuYV9hdHRyWydjbGFzcyddID0gZGF0YS5hX2F0dHJbJ2NsYXNzJ10ucmVwbGFjZSgnanN0cmVlLWNsaWNrZWQnLCcnKS5yZXBsYWNlKCdqc3RyZWUtZGlzYWJsZWQnLCcnKTtcblx0XHRcdH1cblx0XHRcdG1bZGF0YS5pZF0gPSBkYXRhO1xuXHRcdFx0aWYoZGF0YS5zdGF0ZS5zZWxlY3RlZCkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQucHVzaChkYXRhLmlkKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBkYXRhLmlkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcGFyc2VzIGEgbm9kZSBmcm9tIGEgSlNPTiBvYmplY3QgKHVzZWQgd2hlbiBkZWFsaW5nIHdpdGggZmxhdCBkYXRhLCB3aGljaCBoYXMgbm8gbmVzdGluZyBvZiBjaGlsZHJlbiwgYnV0IGhhcyBpZCBhbmQgcGFyZW50IHByb3BlcnRpZXMpIGFuZCBhcHBlbmRzIGl0IHRvIHRoZSBpbiBtZW1vcnkgdHJlZSBtb2RlbC4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgX3BhcnNlX21vZGVsX2Zyb21fZmxhdF9qc29uKGQgWywgcCwgcHNdKVxuXHRcdCAqIEBwYXJhbSAge09iamVjdH0gZCB0aGUgSlNPTiBvYmplY3QgdG8gcGFyc2Vcblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IHAgdGhlIHBhcmVudCBJRFxuXHRcdCAqIEBwYXJhbSAge0FycmF5fSBwcyBsaXN0IG9mIGFsbCBwYXJlbnRzXG5cdFx0ICogQHJldHVybiB7U3RyaW5nfSB0aGUgSUQgb2YgdGhlIG9iamVjdCBhZGRlZCB0byB0aGUgbW9kZWxcblx0XHQgKi9cblx0XHRfcGFyc2VfbW9kZWxfZnJvbV9mbGF0X2pzb24gOiBmdW5jdGlvbiAoZCwgcCwgcHMpIHtcblx0XHRcdGlmKCFwcykgeyBwcyA9IFtdOyB9XG5cdFx0XHRlbHNlIHsgcHMgPSBwcy5jb25jYXQoKTsgfVxuXHRcdFx0aWYocCkgeyBwcy51bnNoaWZ0KHApOyB9XG5cdFx0XHR2YXIgdGlkID0gZC5pZC50b1N0cmluZygpLFxuXHRcdFx0XHRtID0gdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0ZGYgPSB0aGlzLl9tb2RlbC5kZWZhdWx0X3N0YXRlLFxuXHRcdFx0XHRpLCBqLCBjLCBlLFxuXHRcdFx0XHR0bXAgPSB7XG5cdFx0XHRcdFx0aWRcdFx0XHQ6IHRpZCxcblx0XHRcdFx0XHR0ZXh0XHRcdDogZC50ZXh0IHx8ICcnLFxuXHRcdFx0XHRcdGljb25cdFx0OiBkLmljb24gIT09IHVuZGVmaW5lZCA/IGQuaWNvbiA6IHRydWUsXG5cdFx0XHRcdFx0cGFyZW50XHRcdDogcCxcblx0XHRcdFx0XHRwYXJlbnRzXHRcdDogcHMsXG5cdFx0XHRcdFx0Y2hpbGRyZW5cdDogZC5jaGlsZHJlbiB8fCBbXSxcblx0XHRcdFx0XHRjaGlsZHJlbl9kXHQ6IGQuY2hpbGRyZW5fZCB8fCBbXSxcblx0XHRcdFx0XHRkYXRhXHRcdDogZC5kYXRhLFxuXHRcdFx0XHRcdHN0YXRlXHRcdDogeyB9LFxuXHRcdFx0XHRcdGxpX2F0dHJcdFx0OiB7IGlkIDogZmFsc2UgfSxcblx0XHRcdFx0XHRhX2F0dHJcdFx0OiB7IGhyZWYgOiAnIycgfSxcblx0XHRcdFx0XHRvcmlnaW5hbFx0OiBmYWxzZVxuXHRcdFx0XHR9O1xuXHRcdFx0Zm9yKGkgaW4gZGYpIHtcblx0XHRcdFx0aWYoZGYuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHR0bXAuc3RhdGVbaV0gPSBkZltpXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoZCAmJiBkLmRhdGEgJiYgZC5kYXRhLmpzdHJlZSAmJiBkLmRhdGEuanN0cmVlLmljb24pIHtcblx0XHRcdFx0dG1wLmljb24gPSBkLmRhdGEuanN0cmVlLmljb247XG5cdFx0XHR9XG5cdFx0XHRpZih0bXAuaWNvbiA9PT0gdW5kZWZpbmVkIHx8IHRtcC5pY29uID09PSBudWxsIHx8IHRtcC5pY29uID09PSBcIlwiKSB7XG5cdFx0XHRcdHRtcC5pY29uID0gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGlmKGQgJiYgZC5kYXRhKSB7XG5cdFx0XHRcdHRtcC5kYXRhID0gZC5kYXRhO1xuXHRcdFx0XHRpZihkLmRhdGEuanN0cmVlKSB7XG5cdFx0XHRcdFx0Zm9yKGkgaW4gZC5kYXRhLmpzdHJlZSkge1xuXHRcdFx0XHRcdFx0aWYoZC5kYXRhLmpzdHJlZS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHR0bXAuc3RhdGVbaV0gPSBkLmRhdGEuanN0cmVlW2ldO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoZCAmJiB0eXBlb2YgZC5zdGF0ZSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Zm9yIChpIGluIGQuc3RhdGUpIHtcblx0XHRcdFx0XHRpZihkLnN0YXRlLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0XHR0bXAuc3RhdGVbaV0gPSBkLnN0YXRlW2ldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoZCAmJiB0eXBlb2YgZC5saV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRmb3IgKGkgaW4gZC5saV9hdHRyKSB7XG5cdFx0XHRcdFx0aWYoZC5saV9hdHRyLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0XHR0bXAubGlfYXR0cltpXSA9IGQubGlfYXR0cltpXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKCF0bXAubGlfYXR0ci5pZCkge1xuXHRcdFx0XHR0bXAubGlfYXR0ci5pZCA9IHRpZDtcblx0XHRcdH1cblx0XHRcdGlmKGQgJiYgdHlwZW9mIGQuYV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRmb3IgKGkgaW4gZC5hX2F0dHIpIHtcblx0XHRcdFx0XHRpZihkLmFfYXR0ci5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0dG1wLmFfYXR0cltpXSA9IGQuYV9hdHRyW2ldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoZCAmJiBkLmNoaWxkcmVuICYmIGQuY2hpbGRyZW4gPT09IHRydWUpIHtcblx0XHRcdFx0dG1wLnN0YXRlLmxvYWRlZCA9IGZhbHNlO1xuXHRcdFx0XHR0bXAuY2hpbGRyZW4gPSBbXTtcblx0XHRcdFx0dG1wLmNoaWxkcmVuX2QgPSBbXTtcblx0XHRcdH1cblx0XHRcdG1bdG1wLmlkXSA9IHRtcDtcblx0XHRcdGZvcihpID0gMCwgaiA9IHRtcC5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0YyA9IHRoaXMuX3BhcnNlX21vZGVsX2Zyb21fZmxhdF9qc29uKG1bdG1wLmNoaWxkcmVuW2ldXSwgdG1wLmlkLCBwcyk7XG5cdFx0XHRcdGUgPSBtW2NdO1xuXHRcdFx0XHR0bXAuY2hpbGRyZW5fZC5wdXNoKGMpO1xuXHRcdFx0XHRpZihlLmNoaWxkcmVuX2QubGVuZ3RoKSB7XG5cdFx0XHRcdFx0dG1wLmNoaWxkcmVuX2QgPSB0bXAuY2hpbGRyZW5fZC5jb25jYXQoZS5jaGlsZHJlbl9kKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZGVsZXRlIGQuZGF0YTtcblx0XHRcdGRlbGV0ZSBkLmNoaWxkcmVuO1xuXHRcdFx0bVt0bXAuaWRdLm9yaWdpbmFsID0gZDtcblx0XHRcdGlmKHRtcC5zdGF0ZS5zZWxlY3RlZCkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQucHVzaCh0bXAuaWQpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRtcC5pZDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHBhcnNlcyBhIG5vZGUgZnJvbSBhIEpTT04gb2JqZWN0IGFuZCBhcHBlbmRzIGl0IHRvIHRoZSBpbiBtZW1vcnkgdHJlZSBtb2RlbC4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgX3BhcnNlX21vZGVsX2Zyb21fanNvbihkIFssIHAsIHBzXSlcblx0XHQgKiBAcGFyYW0gIHtPYmplY3R9IGQgdGhlIEpTT04gb2JqZWN0IHRvIHBhcnNlXG5cdFx0ICogQHBhcmFtICB7U3RyaW5nfSBwIHRoZSBwYXJlbnQgSURcblx0XHQgKiBAcGFyYW0gIHtBcnJheX0gcHMgbGlzdCBvZiBhbGwgcGFyZW50c1xuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gdGhlIElEIG9mIHRoZSBvYmplY3QgYWRkZWQgdG8gdGhlIG1vZGVsXG5cdFx0ICovXG5cdFx0X3BhcnNlX21vZGVsX2Zyb21fanNvbiA6IGZ1bmN0aW9uIChkLCBwLCBwcykge1xuXHRcdFx0aWYoIXBzKSB7IHBzID0gW107IH1cblx0XHRcdGVsc2UgeyBwcyA9IHBzLmNvbmNhdCgpOyB9XG5cdFx0XHRpZihwKSB7IHBzLnVuc2hpZnQocCk7IH1cblx0XHRcdHZhciB0aWQgPSBmYWxzZSwgaSwgaiwgYywgZSwgbSA9IHRoaXMuX21vZGVsLmRhdGEsIGRmID0gdGhpcy5fbW9kZWwuZGVmYXVsdF9zdGF0ZSwgdG1wO1xuXHRcdFx0ZG8ge1xuXHRcdFx0XHR0aWQgPSAnaicgKyB0aGlzLl9pZCArICdfJyArICgrK3RoaXMuX2NudCk7XG5cdFx0XHR9IHdoaWxlKG1bdGlkXSk7XG5cblx0XHRcdHRtcCA9IHtcblx0XHRcdFx0aWRcdFx0XHQ6IGZhbHNlLFxuXHRcdFx0XHR0ZXh0XHRcdDogdHlwZW9mIGQgPT09ICdzdHJpbmcnID8gZCA6ICcnLFxuXHRcdFx0XHRpY29uXHRcdDogdHlwZW9mIGQgPT09ICdvYmplY3QnICYmIGQuaWNvbiAhPT0gdW5kZWZpbmVkID8gZC5pY29uIDogdHJ1ZSxcblx0XHRcdFx0cGFyZW50XHRcdDogcCxcblx0XHRcdFx0cGFyZW50c1x0XHQ6IHBzLFxuXHRcdFx0XHRjaGlsZHJlblx0OiBbXSxcblx0XHRcdFx0Y2hpbGRyZW5fZFx0OiBbXSxcblx0XHRcdFx0ZGF0YVx0XHQ6IG51bGwsXG5cdFx0XHRcdHN0YXRlXHRcdDogeyB9LFxuXHRcdFx0XHRsaV9hdHRyXHRcdDogeyBpZCA6IGZhbHNlIH0sXG5cdFx0XHRcdGFfYXR0clx0XHQ6IHsgaHJlZiA6ICcjJyB9LFxuXHRcdFx0XHRvcmlnaW5hbFx0OiBmYWxzZVxuXHRcdFx0fTtcblx0XHRcdGZvcihpIGluIGRmKSB7XG5cdFx0XHRcdGlmKGRmLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0dG1wLnN0YXRlW2ldID0gZGZbaV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKGQgJiYgZC5pZCkgeyB0bXAuaWQgPSBkLmlkLnRvU3RyaW5nKCk7IH1cblx0XHRcdGlmKGQgJiYgZC50ZXh0KSB7IHRtcC50ZXh0ID0gZC50ZXh0OyB9XG5cdFx0XHRpZihkICYmIGQuZGF0YSAmJiBkLmRhdGEuanN0cmVlICYmIGQuZGF0YS5qc3RyZWUuaWNvbikge1xuXHRcdFx0XHR0bXAuaWNvbiA9IGQuZGF0YS5qc3RyZWUuaWNvbjtcblx0XHRcdH1cblx0XHRcdGlmKHRtcC5pY29uID09PSB1bmRlZmluZWQgfHwgdG1wLmljb24gPT09IG51bGwgfHwgdG1wLmljb24gPT09IFwiXCIpIHtcblx0XHRcdFx0dG1wLmljb24gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0aWYoZCAmJiBkLmRhdGEpIHtcblx0XHRcdFx0dG1wLmRhdGEgPSBkLmRhdGE7XG5cdFx0XHRcdGlmKGQuZGF0YS5qc3RyZWUpIHtcblx0XHRcdFx0XHRmb3IoaSBpbiBkLmRhdGEuanN0cmVlKSB7XG5cdFx0XHRcdFx0XHRpZihkLmRhdGEuanN0cmVlLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0XHRcdHRtcC5zdGF0ZVtpXSA9IGQuZGF0YS5qc3RyZWVbaV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZihkICYmIHR5cGVvZiBkLnN0YXRlID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRmb3IgKGkgaW4gZC5zdGF0ZSkge1xuXHRcdFx0XHRcdGlmKGQuc3RhdGUuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdHRtcC5zdGF0ZVtpXSA9IGQuc3RhdGVbaV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZihkICYmIHR5cGVvZiBkLmxpX2F0dHIgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdGZvciAoaSBpbiBkLmxpX2F0dHIpIHtcblx0XHRcdFx0XHRpZihkLmxpX2F0dHIuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdHRtcC5saV9hdHRyW2ldID0gZC5saV9hdHRyW2ldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYodG1wLmxpX2F0dHIuaWQgJiYgIXRtcC5pZCkge1xuXHRcdFx0XHR0bXAuaWQgPSB0bXAubGlfYXR0ci5pZC50b1N0cmluZygpO1xuXHRcdFx0fVxuXHRcdFx0aWYoIXRtcC5pZCkge1xuXHRcdFx0XHR0bXAuaWQgPSB0aWQ7XG5cdFx0XHR9XG5cdFx0XHRpZighdG1wLmxpX2F0dHIuaWQpIHtcblx0XHRcdFx0dG1wLmxpX2F0dHIuaWQgPSB0bXAuaWQ7XG5cdFx0XHR9XG5cdFx0XHRpZihkICYmIHR5cGVvZiBkLmFfYXR0ciA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Zm9yIChpIGluIGQuYV9hdHRyKSB7XG5cdFx0XHRcdFx0aWYoZC5hX2F0dHIuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdHRtcC5hX2F0dHJbaV0gPSBkLmFfYXR0cltpXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKGQgJiYgZC5jaGlsZHJlbiAmJiBkLmNoaWxkcmVuLmxlbmd0aCkge1xuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBkLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdGMgPSB0aGlzLl9wYXJzZV9tb2RlbF9mcm9tX2pzb24oZC5jaGlsZHJlbltpXSwgdG1wLmlkLCBwcyk7XG5cdFx0XHRcdFx0ZSA9IG1bY107XG5cdFx0XHRcdFx0dG1wLmNoaWxkcmVuLnB1c2goYyk7XG5cdFx0XHRcdFx0aWYoZS5jaGlsZHJlbl9kLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dG1wLmNoaWxkcmVuX2QgPSB0bXAuY2hpbGRyZW5fZC5jb25jYXQoZS5jaGlsZHJlbl9kKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0dG1wLmNoaWxkcmVuX2QgPSB0bXAuY2hpbGRyZW4uY29uY2F0KHRtcC5jaGlsZHJlbl9kKTtcblx0XHRcdH1cblx0XHRcdGlmKGQgJiYgZC5jaGlsZHJlbiAmJiBkLmNoaWxkcmVuID09PSB0cnVlKSB7XG5cdFx0XHRcdHRtcC5zdGF0ZS5sb2FkZWQgPSBmYWxzZTtcblx0XHRcdFx0dG1wLmNoaWxkcmVuID0gW107XG5cdFx0XHRcdHRtcC5jaGlsZHJlbl9kID0gW107XG5cdFx0XHR9XG5cdFx0XHRkZWxldGUgZC5kYXRhO1xuXHRcdFx0ZGVsZXRlIGQuY2hpbGRyZW47XG5cdFx0XHR0bXAub3JpZ2luYWwgPSBkO1xuXHRcdFx0bVt0bXAuaWRdID0gdG1wO1xuXHRcdFx0aWYodG1wLnN0YXRlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5wdXNoKHRtcC5pZCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdG1wLmlkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcmVkcmF3cyBhbGwgbm9kZXMgdGhhdCBuZWVkIHRvIGJlIHJlZHJhd24uIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF9yZWRyYXcoKVxuXHRcdCAqIEB0cmlnZ2VyIHJlZHJhdy5qc3RyZWVcblx0XHQgKi9cblx0XHRfcmVkcmF3IDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIG5vZGVzID0gdGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcgPyB0aGlzLl9tb2RlbC5kYXRhWyQuanN0cmVlLnJvb3RdLmNoaWxkcmVuLmNvbmNhdChbXSkgOiB0aGlzLl9tb2RlbC5jaGFuZ2VkLmNvbmNhdChbXSksXG5cdFx0XHRcdGYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdVTCcpLCB0bXAsIGksIGosIGZlID0gdGhpcy5fZGF0YS5jb3JlLmZvY3VzZWQ7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBub2Rlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0dG1wID0gdGhpcy5yZWRyYXdfbm9kZShub2Rlc1tpXSwgdHJ1ZSwgdGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcpO1xuXHRcdFx0XHRpZih0bXAgJiYgdGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcpIHtcblx0XHRcdFx0XHRmLmFwcGVuZENoaWxkKHRtcCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuX21vZGVsLmZvcmNlX2Z1bGxfcmVkcmF3KSB7XG5cdFx0XHRcdGYuY2xhc3NOYW1lID0gdGhpcy5nZXRfY29udGFpbmVyX3VsKClbMF0uY2xhc3NOYW1lO1xuXHRcdFx0XHRmLnNldEF0dHJpYnV0ZSgncm9sZScsJ3ByZXNlbnRhdGlvbicpO1xuXHRcdFx0XHR0aGlzLmVsZW1lbnQuZW1wdHkoKS5hcHBlbmQoZik7XG5cdFx0XHRcdC8vdGhpcy5nZXRfY29udGFpbmVyX3VsKClbMF0uYXBwZW5kQ2hpbGQoZik7XG5cdFx0XHR9XG5cdFx0XHRpZihmZSAhPT0gbnVsbCAmJiB0aGlzLnNldHRpbmdzLmNvcmUucmVzdG9yZV9mb2N1cykge1xuXHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKGZlLCB0cnVlKTtcblx0XHRcdFx0aWYodG1wICYmIHRtcC5sZW5ndGggJiYgdG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpWzBdICE9PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG5cdFx0XHRcdFx0dG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmZvY3VzZWQgPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9tb2RlbC5mb3JjZV9mdWxsX3JlZHJhdyA9IGZhbHNlO1xuXHRcdFx0dGhpcy5fbW9kZWwuY2hhbmdlZCA9IFtdO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgYWZ0ZXIgbm9kZXMgYXJlIHJlZHJhd25cblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgcmVkcmF3LmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHthcnJheX0gbm9kZXMgdGhlIHJlZHJhd24gbm9kZXNcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdyZWRyYXcnLCB7IFwibm9kZXNcIiA6IG5vZGVzIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcmVkcmF3cyBhbGwgbm9kZXMgdGhhdCBuZWVkIHRvIGJlIHJlZHJhd24gb3Igb3B0aW9uYWxseSAtIHRoZSB3aG9sZSB0cmVlXG5cdFx0ICogQG5hbWUgcmVkcmF3KFtmdWxsXSlcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IGZ1bGwgaWYgc2V0IHRvIGB0cnVlYCBhbGwgbm9kZXMgYXJlIHJlZHJhd24uXG5cdFx0ICovXG5cdFx0cmVkcmF3IDogZnVuY3Rpb24gKGZ1bGwpIHtcblx0XHRcdGlmKGZ1bGwpIHtcblx0XHRcdFx0dGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0Ly9pZih0aGlzLl9tb2RlbC5yZWRyYXdfdGltZW91dCkge1xuXHRcdFx0Ly9cdGNsZWFyVGltZW91dCh0aGlzLl9tb2RlbC5yZWRyYXdfdGltZW91dCk7XG5cdFx0XHQvL31cblx0XHRcdC8vdGhpcy5fbW9kZWwucmVkcmF3X3RpbWVvdXQgPSBzZXRUaW1lb3V0KCQucHJveHkodGhpcy5fcmVkcmF3LCB0aGlzKSwwKTtcblx0XHRcdHRoaXMuX3JlZHJhdygpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcmVkcmF3cyBhIHNpbmdsZSBub2RlJ3MgY2hpbGRyZW4uIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIGRyYXdfY2hpbGRyZW4obm9kZSlcblx0XHQgKiBAcGFyYW0ge21peGVkfSBub2RlIHRoZSBub2RlIHdob3NlIGNoaWxkcmVuIHdpbGwgYmUgcmVkcmF3blxuXHRcdCAqL1xuXHRcdGRyYXdfY2hpbGRyZW4gOiBmdW5jdGlvbiAobm9kZSkge1xuXHRcdFx0dmFyIG9iaiA9IHRoaXMuZ2V0X25vZGUobm9kZSksXG5cdFx0XHRcdGkgPSBmYWxzZSxcblx0XHRcdFx0aiA9IGZhbHNlLFxuXHRcdFx0XHRrID0gZmFsc2UsXG5cdFx0XHRcdGQgPSBkb2N1bWVudDtcblx0XHRcdGlmKCFvYmopIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRpZihvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHsgcmV0dXJuIHRoaXMucmVkcmF3KHRydWUpOyB9XG5cdFx0XHRub2RlID0gdGhpcy5nZXRfbm9kZShub2RlLCB0cnVlKTtcblx0XHRcdGlmKCFub2RlIHx8ICFub2RlLmxlbmd0aCkgeyByZXR1cm4gZmFsc2U7IH0gLy8gVE9ETzogcXVpY2sgdG9nZ2xlXG5cblx0XHRcdG5vZGUuY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKS5yZW1vdmUoKTtcblx0XHRcdG5vZGUgPSBub2RlWzBdO1xuXHRcdFx0aWYob2JqLmNoaWxkcmVuLmxlbmd0aCAmJiBvYmouc3RhdGUubG9hZGVkKSB7XG5cdFx0XHRcdGsgPSBkLmNyZWF0ZUVsZW1lbnQoJ1VMJyk7XG5cdFx0XHRcdGsuc2V0QXR0cmlidXRlKCdyb2xlJywgJ2dyb3VwJyk7XG5cdFx0XHRcdGsuY2xhc3NOYW1lID0gJ2pzdHJlZS1jaGlsZHJlbic7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRrLmFwcGVuZENoaWxkKHRoaXMucmVkcmF3X25vZGUob2JqLmNoaWxkcmVuW2ldLCB0cnVlLCB0cnVlKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bm9kZS5hcHBlbmRDaGlsZChrKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHJlZHJhd3MgYSBzaW5nbGUgbm9kZS4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgcmVkcmF3X25vZGUobm9kZSwgZGVlcCwgaXNfY2FsbGJhY2ssIGZvcmNlX3JlbmRlcilcblx0XHQgKiBAcGFyYW0ge21peGVkfSBub2RlIHRoZSBub2RlIHRvIHJlZHJhd1xuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcCBzaG91bGQgY2hpbGQgbm9kZXMgYmUgcmVkcmF3biB0b29cblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IGlzX2NhbGxiYWNrIGlzIHRoaXMgYSByZWN1cnNpb24gY2FsbFxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2VfcmVuZGVyIHNob3VsZCBjaGlsZHJlbiBvZiBjbG9zZWQgcGFyZW50cyBiZSBkcmF3biBhbnl3YXlcblx0XHQgKi9cblx0XHRyZWRyYXdfbm9kZSA6IGZ1bmN0aW9uIChub2RlLCBkZWVwLCBpc19jYWxsYmFjaywgZm9yY2VfcmVuZGVyKSB7XG5cdFx0XHR2YXIgb2JqID0gdGhpcy5nZXRfbm9kZShub2RlKSxcblx0XHRcdFx0cGFyID0gZmFsc2UsXG5cdFx0XHRcdGluZCA9IGZhbHNlLFxuXHRcdFx0XHRvbGQgPSBmYWxzZSxcblx0XHRcdFx0aSA9IGZhbHNlLFxuXHRcdFx0XHRqID0gZmFsc2UsXG5cdFx0XHRcdGsgPSBmYWxzZSxcblx0XHRcdFx0YyA9ICcnLFxuXHRcdFx0XHRkID0gZG9jdW1lbnQsXG5cdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRmID0gZmFsc2UsXG5cdFx0XHRcdHMgPSBmYWxzZSxcblx0XHRcdFx0dG1wID0gbnVsbCxcblx0XHRcdFx0dCA9IDAsXG5cdFx0XHRcdGwgPSAwLFxuXHRcdFx0XHRoYXNfY2hpbGRyZW4gPSBmYWxzZSxcblx0XHRcdFx0bGFzdF9zaWJsaW5nID0gZmFsc2U7XG5cdFx0XHRpZighb2JqKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0aWYob2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7ICByZXR1cm4gdGhpcy5yZWRyYXcodHJ1ZSk7IH1cblx0XHRcdGRlZXAgPSBkZWVwIHx8IG9iai5jaGlsZHJlbi5sZW5ndGggPT09IDA7XG5cdFx0XHRub2RlID0gIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvYmouaWQpIDogdGhpcy5lbGVtZW50WzBdLnF1ZXJ5U2VsZWN0b3IoJyMnICsgKFwiMDEyMzQ1Njc4OVwiLmluZGV4T2Yob2JqLmlkWzBdKSAhPT0gLTEgPyAnXFxcXDMnICsgb2JqLmlkWzBdICsgJyAnICsgb2JqLmlkLnN1YnN0cigxKS5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpIDogb2JqLmlkLnJlcGxhY2UoJC5qc3RyZWUuaWRyZWdleCwnXFxcXCQmJykpICk7IC8vLCB0aGlzLmVsZW1lbnQpO1xuXHRcdFx0aWYoIW5vZGUpIHtcblx0XHRcdFx0ZGVlcCA9IHRydWU7XG5cdFx0XHRcdC8vbm9kZSA9IGQuY3JlYXRlRWxlbWVudCgnTEknKTtcblx0XHRcdFx0aWYoIWlzX2NhbGxiYWNrKSB7XG5cdFx0XHRcdFx0cGFyID0gb2JqLnBhcmVudCAhPT0gJC5qc3RyZWUucm9vdCA/ICQoJyMnICsgb2JqLnBhcmVudC5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpLCB0aGlzLmVsZW1lbnQpWzBdIDogbnVsbDtcblx0XHRcdFx0XHRpZihwYXIgIT09IG51bGwgJiYgKCFwYXIgfHwgIW1bb2JqLnBhcmVudF0uc3RhdGUub3BlbmVkKSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpbmQgPSAkLmluQXJyYXkob2JqLmlkLCBwYXIgPT09IG51bGwgPyBtWyQuanN0cmVlLnJvb3RdLmNoaWxkcmVuIDogbVtvYmoucGFyZW50XS5jaGlsZHJlbik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRub2RlID0gJChub2RlKTtcblx0XHRcdFx0aWYoIWlzX2NhbGxiYWNrKSB7XG5cdFx0XHRcdFx0cGFyID0gbm9kZS5wYXJlbnQoKS5wYXJlbnQoKVswXTtcblx0XHRcdFx0XHRpZihwYXIgPT09IHRoaXMuZWxlbWVudFswXSkge1xuXHRcdFx0XHRcdFx0cGFyID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aW5kID0gbm9kZS5pbmRleCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIG1bb2JqLmlkXS5kYXRhID0gbm9kZS5kYXRhKCk7IC8vIHVzZSBvbmx5IG5vZGUncyBkYXRhLCBubyBuZWVkIHRvIHRvdWNoIGpxdWVyeSBzdG9yYWdlXG5cdFx0XHRcdGlmKCFkZWVwICYmIG9iai5jaGlsZHJlbi5sZW5ndGggJiYgIW5vZGUuY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKS5sZW5ndGgpIHtcblx0XHRcdFx0XHRkZWVwID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZighZGVlcCkge1xuXHRcdFx0XHRcdG9sZCA9IG5vZGUuY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKVswXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRmID0gbm9kZS5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKVswXSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0XHRcdFx0bm9kZS5yZW1vdmUoKTtcblx0XHRcdFx0Ly9ub2RlID0gZC5jcmVhdGVFbGVtZW50KCdMSScpO1xuXHRcdFx0XHQvL25vZGUgPSBub2RlWzBdO1xuXHRcdFx0fVxuXHRcdFx0bm9kZSA9IHRoaXMuX2RhdGEuY29yZS5ub2RlLmNsb25lTm9kZSh0cnVlKTtcblx0XHRcdC8vIG5vZGUgaXMgRE9NLCBkZWVwIGlzIGJvb2xlYW5cblxuXHRcdFx0YyA9ICdqc3RyZWUtbm9kZSAnO1xuXHRcdFx0Zm9yKGkgaW4gb2JqLmxpX2F0dHIpIHtcblx0XHRcdFx0aWYob2JqLmxpX2F0dHIuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRpZihpID09PSAnaWQnKSB7IGNvbnRpbnVlOyB9XG5cdFx0XHRcdFx0aWYoaSAhPT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0bm9kZS5zZXRBdHRyaWJ1dGUoaSwgb2JqLmxpX2F0dHJbaV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdGMgKz0gb2JqLmxpX2F0dHJbaV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZighb2JqLmFfYXR0ci5pZCkge1xuXHRcdFx0XHRvYmouYV9hdHRyLmlkID0gb2JqLmlkICsgJ19hbmNob3InO1xuXHRcdFx0fVxuXHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLnNldEF0dHJpYnV0ZSgnYXJpYS1zZWxlY3RlZCcsICEhb2JqLnN0YXRlLnNlbGVjdGVkKTtcblx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGV2ZWwnLCBvYmoucGFyZW50cy5sZW5ndGgpO1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jb3JlLmNvbXB1dGVfZWxlbWVudHNfcG9zaXRpb25zKSB7XG5cdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2V0c2l6ZScsIG1bb2JqLnBhcmVudF0uY2hpbGRyZW4ubGVuZ3RoKTtcblx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLnNldEF0dHJpYnV0ZSgnYXJpYS1wb3NpbnNldCcsIG1bb2JqLnBhcmVudF0uY2hpbGRyZW4uaW5kZXhPZihvYmouaWQpICsgMSk7XG5cdFx0XHR9XG5cdFx0XHRpZihvYmouc3RhdGUuZGlzYWJsZWQpIHtcblx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLnNldEF0dHJpYnV0ZSgnYXJpYS1kaXNhYmxlZCcsIHRydWUpO1xuXHRcdFx0fVxuXG5cdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKCFtW29iai5jaGlsZHJlbltpXV0uc3RhdGUuaGlkZGVuKSB7XG5cdFx0XHRcdFx0aGFzX2NoaWxkcmVuID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYob2JqLnBhcmVudCAhPT0gbnVsbCAmJiBtW29iai5wYXJlbnRdICYmICFvYmouc3RhdGUuaGlkZGVuKSB7XG5cdFx0XHRcdGkgPSAkLmluQXJyYXkob2JqLmlkLCBtW29iai5wYXJlbnRdLmNoaWxkcmVuKTtcblx0XHRcdFx0bGFzdF9zaWJsaW5nID0gb2JqLmlkO1xuXHRcdFx0XHRpZihpICE9PSAtMSkge1xuXHRcdFx0XHRcdGkrKztcblx0XHRcdFx0XHRmb3IoaiA9IG1bb2JqLnBhcmVudF0uY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRpZighbVttW29iai5wYXJlbnRdLmNoaWxkcmVuW2ldXS5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0XHRcdFx0bGFzdF9zaWJsaW5nID0gbVtvYmoucGFyZW50XS5jaGlsZHJlbltpXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmKGxhc3Rfc2libGluZyAhPT0gb2JqLmlkKSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZihvYmouc3RhdGUuaGlkZGVuKSB7XG5cdFx0XHRcdGMgKz0gJyBqc3RyZWUtaGlkZGVuJztcblx0XHRcdH1cblx0XHRcdGlmIChvYmouc3RhdGUubG9hZGluZykge1xuXHRcdFx0XHRjICs9ICcganN0cmVlLWxvYWRpbmcnO1xuXHRcdFx0fVxuXHRcdFx0aWYob2JqLnN0YXRlLmxvYWRlZCAmJiAhaGFzX2NoaWxkcmVuKSB7XG5cdFx0XHRcdGMgKz0gJyBqc3RyZWUtbGVhZic7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0YyArPSBvYmouc3RhdGUub3BlbmVkICYmIG9iai5zdGF0ZS5sb2FkZWQgPyAnIGpzdHJlZS1vcGVuJyA6ICcganN0cmVlLWNsb3NlZCc7XG5cdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAob2JqLnN0YXRlLm9wZW5lZCAmJiBvYmouc3RhdGUubG9hZGVkKSApO1xuXHRcdFx0fVxuXHRcdFx0aWYobGFzdF9zaWJsaW5nID09PSBvYmouaWQpIHtcblx0XHRcdFx0YyArPSAnIGpzdHJlZS1sYXN0Jztcblx0XHRcdH1cblx0XHRcdG5vZGUuaWQgPSBvYmouaWQ7XG5cdFx0XHRub2RlLmNsYXNzTmFtZSA9IGM7XG5cdFx0XHRjID0gKCBvYmouc3RhdGUuc2VsZWN0ZWQgPyAnIGpzdHJlZS1jbGlja2VkJyA6ICcnKSArICggb2JqLnN0YXRlLmRpc2FibGVkID8gJyBqc3RyZWUtZGlzYWJsZWQnIDogJycpO1xuXHRcdFx0Zm9yKGogaW4gb2JqLmFfYXR0cikge1xuXHRcdFx0XHRpZihvYmouYV9hdHRyLmhhc093blByb3BlcnR5KGopKSB7XG5cdFx0XHRcdFx0aWYoaiA9PT0gJ2hyZWYnICYmIG9iai5hX2F0dHJbal0gPT09ICcjJykgeyBjb250aW51ZTsgfVxuXHRcdFx0XHRcdGlmKGogIT09ICdjbGFzcycpIHtcblx0XHRcdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5zZXRBdHRyaWJ1dGUoaiwgb2JqLmFfYXR0cltqXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0YyArPSAnICcgKyBvYmouYV9hdHRyW2pdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoYy5sZW5ndGgpIHtcblx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmNsYXNzTmFtZSA9ICdqc3RyZWUtYW5jaG9yICcgKyBjO1xuXHRcdFx0fVxuXHRcdFx0aWYoKG9iai5pY29uICYmIG9iai5pY29uICE9PSB0cnVlKSB8fCBvYmouaWNvbiA9PT0gZmFsc2UpIHtcblx0XHRcdFx0aWYob2JqLmljb24gPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmNoaWxkTm9kZXNbMF0uY2xhc3NOYW1lICs9ICcganN0cmVlLXRoZW1laWNvbi1oaWRkZW4nO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2UgaWYob2JqLmljb24uaW5kZXhPZignLycpID09PSAtMSAmJiBvYmouaWNvbi5pbmRleE9mKCcuJykgPT09IC0xKSB7XG5cdFx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmNoaWxkTm9kZXNbMF0uY2xhc3NOYW1lICs9ICcgJyArIG9iai5pY29uICsgJyBqc3RyZWUtdGhlbWVpY29uLWN1c3RvbSc7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZEltYWdlID0gJ3VybChcIicrb2JqLmljb24rJ1wiKSc7XG5cdFx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZFBvc2l0aW9uID0gJ2NlbnRlciBjZW50ZXInO1xuXHRcdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5jaGlsZE5vZGVzWzBdLnN0eWxlLmJhY2tncm91bmRTaXplID0gJ2F1dG8nO1xuXHRcdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5jaGlsZE5vZGVzWzBdLmNsYXNzTmFtZSArPSAnIGpzdHJlZS10aGVtZWljb24tY3VzdG9tJztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNvcmUuZm9yY2VfdGV4dCkge1xuXHRcdFx0XHRub2RlLmNoaWxkTm9kZXNbMV0uYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShvYmoudGV4dCkpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdG5vZGUuY2hpbGROb2Rlc1sxXS5pbm5lckhUTUwgKz0gb2JqLnRleHQ7XG5cdFx0XHR9XG5cblxuXHRcdFx0aWYoZGVlcCAmJiBvYmouY2hpbGRyZW4ubGVuZ3RoICYmIChvYmouc3RhdGUub3BlbmVkIHx8IGZvcmNlX3JlbmRlcikgJiYgb2JqLnN0YXRlLmxvYWRlZCkge1xuXHRcdFx0XHRrID0gZC5jcmVhdGVFbGVtZW50KCdVTCcpO1xuXHRcdFx0XHRrLnNldEF0dHJpYnV0ZSgncm9sZScsICdncm91cCcpO1xuXHRcdFx0XHRrLmNsYXNzTmFtZSA9ICdqc3RyZWUtY2hpbGRyZW4nO1xuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0ay5hcHBlbmRDaGlsZCh0aGlzLnJlZHJhd19ub2RlKG9iai5jaGlsZHJlbltpXSwgZGVlcCwgdHJ1ZSkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5vZGUuYXBwZW5kQ2hpbGQoayk7XG5cdFx0XHR9XG5cdFx0XHRpZihvbGQpIHtcblx0XHRcdFx0bm9kZS5hcHBlbmRDaGlsZChvbGQpO1xuXHRcdFx0fVxuXHRcdFx0aWYoIWlzX2NhbGxiYWNrKSB7XG5cdFx0XHRcdC8vIGFwcGVuZCBiYWNrIHVzaW5nIHBhciAvIGluZFxuXHRcdFx0XHRpZighcGFyKSB7XG5cdFx0XHRcdFx0cGFyID0gdGhpcy5lbGVtZW50WzBdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IHBhci5jaGlsZE5vZGVzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdGlmKHBhci5jaGlsZE5vZGVzW2ldICYmIHBhci5jaGlsZE5vZGVzW2ldLmNsYXNzTmFtZSAmJiBwYXIuY2hpbGROb2Rlc1tpXS5jbGFzc05hbWUuaW5kZXhPZignanN0cmVlLWNoaWxkcmVuJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSBwYXIuY2hpbGROb2Rlc1tpXTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRpZighdG1wKSB7XG5cdFx0XHRcdFx0dG1wID0gZC5jcmVhdGVFbGVtZW50KCdVTCcpO1xuXHRcdFx0XHRcdHRtcC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnZ3JvdXAnKTtcblx0XHRcdFx0XHR0bXAuY2xhc3NOYW1lID0gJ2pzdHJlZS1jaGlsZHJlbic7XG5cdFx0XHRcdFx0cGFyLmFwcGVuZENoaWxkKHRtcCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cGFyID0gdG1wO1xuXG5cdFx0XHRcdGlmKGluZCA8IHBhci5jaGlsZE5vZGVzLmxlbmd0aCkge1xuXHRcdFx0XHRcdHBhci5pbnNlcnRCZWZvcmUobm9kZSwgcGFyLmNoaWxkTm9kZXNbaW5kXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0cGFyLmFwcGVuZENoaWxkKG5vZGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKGYpIHtcblx0XHRcdFx0XHR0ID0gdGhpcy5lbGVtZW50WzBdLnNjcm9sbFRvcDtcblx0XHRcdFx0XHRsID0gdGhpcy5lbGVtZW50WzBdLnNjcm9sbExlZnQ7XG5cdFx0XHRcdFx0bm9kZS5jaGlsZE5vZGVzWzFdLmZvY3VzKCk7XG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50WzBdLnNjcm9sbFRvcCA9IHQ7XG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50WzBdLnNjcm9sbExlZnQgPSBsO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZihvYmouc3RhdGUub3BlbmVkICYmICFvYmouc3RhdGUubG9hZGVkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5vcGVuZWQgPSBmYWxzZTtcblx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dGhpcy5vcGVuX25vZGUob2JqLmlkLCBmYWxzZSwgMCk7XG5cdFx0XHRcdH0uYmluZCh0aGlzKSwgMCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbm9kZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIG9wZW5zIGEgbm9kZSwgcmV2ZWFsaW5nIGl0cyBjaGlsZHJlbi4gSWYgdGhlIG5vZGUgaXMgbm90IGxvYWRlZCBpdCB3aWxsIGJlIGxvYWRlZCBhbmQgb3BlbmVkIG9uY2UgcmVhZHkuXG5cdFx0ICogQG5hbWUgb3Blbl9ub2RlKG9iaiBbLCBjYWxsYmFjaywgYW5pbWF0aW9uXSlcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGUgdG8gb3BlblxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGEgZnVuY3Rpb24gdG8gZXhlY3V0ZSBvbmNlIHRoZSBub2RlIGlzIG9wZW5lZFxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBhbmltYXRpb24gdGhlIGFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgd2hlbiBvcGVuaW5nIHRoZSBub2RlIChvdmVycmlkZXMgdGhlIGBjb3JlLmFuaW1hdGlvbmAgc2V0dGluZykuIFVzZSBgZmFsc2VgIGZvciBubyBhbmltYXRpb24uXG5cdFx0ICogQHRyaWdnZXIgb3Blbl9ub2RlLmpzdHJlZSwgYWZ0ZXJfb3Blbi5qc3RyZWUsIGJlZm9yZV9vcGVuLmpzdHJlZVxuXHRcdCAqL1xuXHRcdG9wZW5fbm9kZSA6IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrLCBhbmltYXRpb24pIHtcblx0XHRcdHZhciB0MSwgdDIsIGQsIHQ7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLm9wZW5fbm9kZShvYmpbdDFdLCBjYWxsYmFjaywgYW5pbWF0aW9uKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGFuaW1hdGlvbiA9IGFuaW1hdGlvbiA9PT0gdW5kZWZpbmVkID8gdGhpcy5zZXR0aW5ncy5jb3JlLmFuaW1hdGlvbiA6IGFuaW1hdGlvbjtcblx0XHRcdGlmKCF0aGlzLmlzX2Nsb3NlZChvYmopKSB7XG5cdFx0XHRcdGlmKGNhbGxiYWNrKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCh0aGlzLCBvYmosIGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRpZighdGhpcy5pc19sb2FkZWQob2JqKSkge1xuXHRcdFx0XHRpZih0aGlzLmlzX2xvYWRpbmcob2JqKSkge1xuXHRcdFx0XHRcdHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHRoaXMub3Blbl9ub2RlKG9iaiwgY2FsbGJhY2ssIGFuaW1hdGlvbik7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpLCA1MDApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMubG9hZF9ub2RlKG9iaiwgZnVuY3Rpb24gKG8sIG9rKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9rID8gdGhpcy5vcGVuX25vZGUobywgY2FsbGJhY2ssIGFuaW1hdGlvbikgOiAoY2FsbGJhY2sgPyBjYWxsYmFjay5jYWxsKHRoaXMsIG8sIGZhbHNlKSA6IGZhbHNlKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0ZCA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdFx0dCA9IHRoaXM7XG5cdFx0XHRcdGlmKGQubGVuZ3RoKSB7XG5cdFx0XHRcdFx0aWYoYW5pbWF0aW9uICYmIGQuY2hpbGRyZW4oXCIuanN0cmVlLWNoaWxkcmVuXCIpLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0ZC5jaGlsZHJlbihcIi5qc3RyZWUtY2hpbGRyZW5cIikuc3RvcCh0cnVlLCB0cnVlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYob2JqLmNoaWxkcmVuLmxlbmd0aCAmJiAhdGhpcy5fZmlyc3RDaGlsZChkLmNoaWxkcmVuKCcuanN0cmVlLWNoaWxkcmVuJylbMF0pKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmRyYXdfY2hpbGRyZW4ob2JqKTtcblx0XHRcdFx0XHRcdC8vZCA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYoIWFuaW1hdGlvbikge1xuXHRcdFx0XHRcdFx0dGhpcy50cmlnZ2VyKCdiZWZvcmVfb3BlbicsIHsgXCJub2RlXCIgOiBvYmogfSk7XG5cdFx0XHRcdFx0XHRkWzBdLmNsYXNzTmFtZSA9IGRbMF0uY2xhc3NOYW1lLnJlcGxhY2UoJ2pzdHJlZS1jbG9zZWQnLCAnanN0cmVlLW9wZW4nKTtcblx0XHRcdFx0XHRcdGRbMF0uY2hpbGROb2Rlc1sxXS5zZXRBdHRyaWJ1dGUoXCJhcmlhLWV4cGFuZGVkXCIsIHRydWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMudHJpZ2dlcignYmVmb3JlX29wZW4nLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdFx0XHRcdFx0ZFxuXHRcdFx0XHRcdFx0XHQuY2hpbGRyZW4oXCIuanN0cmVlLWNoaWxkcmVuXCIpLmNzcyhcImRpc3BsYXlcIixcIm5vbmVcIikuZW5kKClcblx0XHRcdFx0XHRcdFx0LnJlbW92ZUNsYXNzKFwianN0cmVlLWNsb3NlZFwiKS5hZGRDbGFzcyhcImpzdHJlZS1vcGVuXCIpXG5cdFx0XHRcdFx0XHRcdFx0LmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsIHRydWUpLmVuZCgpXG5cdFx0XHRcdFx0XHRcdC5jaGlsZHJlbihcIi5qc3RyZWUtY2hpbGRyZW5cIikuc3RvcCh0cnVlLCB0cnVlKVxuXHRcdFx0XHRcdFx0XHRcdC5zbGlkZURvd24oYW5pbWF0aW9uLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHQuZWxlbWVudCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0LnRyaWdnZXIoXCJhZnRlcl9vcGVuXCIsIHsgXCJub2RlXCIgOiBvYmogfSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdG9iai5zdGF0ZS5vcGVuZWQgPSB0cnVlO1xuXHRcdFx0XHRpZihjYWxsYmFjaykge1xuXHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwodGhpcywgb2JqLCB0cnVlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZighZC5sZW5ndGgpIHtcblx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgYWJvdXQgdG8gYmUgb3BlbmVkIChpZiB0aGUgbm9kZSBpcyBzdXBwb3NlZCB0byBiZSBpbiB0aGUgRE9NLCBpdCB3aWxsIGJlLCBidXQgaXQgd29uJ3QgYmUgdmlzaWJsZSB5ZXQpXG5cdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0ICogQG5hbWUgYmVmb3JlX29wZW4uanN0cmVlXG5cdFx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIG9wZW5lZCBub2RlXG5cdFx0XHRcdFx0ICovXG5cdFx0XHRcdFx0dGhpcy50cmlnZ2VyKCdiZWZvcmVfb3BlbicsIHsgXCJub2RlXCIgOiBvYmogfSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0LyoqXG5cdFx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGEgbm9kZSBpcyBvcGVuZWQgKGlmIHRoZXJlIGlzIGFuIGFuaW1hdGlvbiBpdCB3aWxsIG5vdCBiZSBjb21wbGV0ZWQgeWV0KVxuXHRcdFx0XHQgKiBAZXZlbnRcblx0XHRcdFx0ICogQG5hbWUgb3Blbl9ub2RlLmpzdHJlZVxuXHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgb3BlbmVkIG5vZGVcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcignb3Blbl9ub2RlJywgeyBcIm5vZGVcIiA6IG9iaiB9KTtcblx0XHRcdFx0aWYoIWFuaW1hdGlvbiB8fCAhZC5sZW5ndGgpIHtcblx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgb3BlbmVkIGFuZCB0aGUgYW5pbWF0aW9uIGlzIGNvbXBsZXRlXG5cdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0ICogQG5hbWUgYWZ0ZXJfb3Blbi5qc3RyZWVcblx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgb3BlbmVkIG5vZGVcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHR0aGlzLnRyaWdnZXIoXCJhZnRlcl9vcGVuXCIsIHsgXCJub2RlXCIgOiBvYmogfSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBvcGVucyBldmVyeSBwYXJlbnQgb2YgYSBub2RlIChub2RlIHNob3VsZCBiZSBsb2FkZWQpXG5cdFx0ICogQG5hbWUgX29wZW5fdG8ob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byByZXZlYWxcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9vcGVuX3RvIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGksIGosIHAgPSBvYmoucGFyZW50cztcblx0XHRcdGZvcihpID0gMCwgaiA9IHAubGVuZ3RoOyBpIDwgajsgaSs9MSkge1xuXHRcdFx0XHRpZihpICE9PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdFx0dGhpcy5vcGVuX25vZGUocFtpXSwgZmFsc2UsIDApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJCgnIycgKyBvYmouaWQucmVwbGFjZSgkLmpzdHJlZS5pZHJlZ2V4LCdcXFxcJCYnKSwgdGhpcy5lbGVtZW50KTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNsb3NlcyBhIG5vZGUsIGhpZGluZyBpdHMgY2hpbGRyZW5cblx0XHQgKiBAbmFtZSBjbG9zZV9ub2RlKG9iaiBbLCBhbmltYXRpb25dKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBjbG9zZVxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBhbmltYXRpb24gdGhlIGFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgd2hlbiBjbG9zaW5nIHRoZSBub2RlIChvdmVycmlkZXMgdGhlIGBjb3JlLmFuaW1hdGlvbmAgc2V0dGluZykuIFVzZSBgZmFsc2VgIGZvciBubyBhbmltYXRpb24uXG5cdFx0ICogQHRyaWdnZXIgY2xvc2Vfbm9kZS5qc3RyZWUsIGFmdGVyX2Nsb3NlLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGNsb3NlX25vZGUgOiBmdW5jdGlvbiAob2JqLCBhbmltYXRpb24pIHtcblx0XHRcdHZhciB0MSwgdDIsIHQsIGQ7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLmNsb3NlX25vZGUob2JqW3QxXSwgYW5pbWF0aW9uKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuaXNfY2xvc2VkKG9iaikpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0YW5pbWF0aW9uID0gYW5pbWF0aW9uID09PSB1bmRlZmluZWQgPyB0aGlzLnNldHRpbmdzLmNvcmUuYW5pbWF0aW9uIDogYW5pbWF0aW9uO1xuXHRcdFx0dCA9IHRoaXM7XG5cdFx0XHRkID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXG5cdFx0XHRvYmouc3RhdGUub3BlbmVkID0gZmFsc2U7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGEgbm9kZSBpcyBjbG9zZWQgKGlmIHRoZXJlIGlzIGFuIGFuaW1hdGlvbiBpdCB3aWxsIG5vdCBiZSBjb21wbGV0ZSB5ZXQpXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGNsb3NlX25vZGUuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgY2xvc2VkIG5vZGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdjbG9zZV9ub2RlJyx7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdFx0aWYoIWQubGVuZ3RoKSB7XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgY2xvc2VkIGFuZCB0aGUgYW5pbWF0aW9uIGlzIGNvbXBsZXRlXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBhZnRlcl9jbG9zZS5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIGNsb3NlZCBub2RlXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoXCJhZnRlcl9jbG9zZVwiLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdGlmKCFhbmltYXRpb24pIHtcblx0XHRcdFx0XHRkWzBdLmNsYXNzTmFtZSA9IGRbMF0uY2xhc3NOYW1lLnJlcGxhY2UoJ2pzdHJlZS1vcGVuJywgJ2pzdHJlZS1jbG9zZWQnKTtcblx0XHRcdFx0XHRkLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsIGZhbHNlKTtcblx0XHRcdFx0XHRkLmNoaWxkcmVuKCcuanN0cmVlLWNoaWxkcmVuJykucmVtb3ZlKCk7XG5cdFx0XHRcdFx0dGhpcy50cmlnZ2VyKFwiYWZ0ZXJfY2xvc2VcIiwgeyBcIm5vZGVcIiA6IG9iaiB9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRkXG5cdFx0XHRcdFx0XHQuY2hpbGRyZW4oXCIuanN0cmVlLWNoaWxkcmVuXCIpLmF0dHIoXCJzdHlsZVwiLFwiZGlzcGxheTpibG9jayAhaW1wb3J0YW50XCIpLmVuZCgpXG5cdFx0XHRcdFx0XHQucmVtb3ZlQ2xhc3MoXCJqc3RyZWUtb3BlblwiKS5hZGRDbGFzcyhcImpzdHJlZS1jbG9zZWRcIilcblx0XHRcdFx0XHRcdFx0LmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsIGZhbHNlKS5lbmQoKVxuXHRcdFx0XHRcdFx0LmNoaWxkcmVuKFwiLmpzdHJlZS1jaGlsZHJlblwiKS5zdG9wKHRydWUsIHRydWUpLnNsaWRlVXAoYW5pbWF0aW9uLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHRcdFx0XHRcdGQuY2hpbGRyZW4oJy5qc3RyZWUtY2hpbGRyZW4nKS5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdFx0aWYgKHQuZWxlbWVudCkge1xuXHRcdFx0XHRcdFx0XHRcdHQudHJpZ2dlcihcImFmdGVyX2Nsb3NlXCIsIHsgXCJub2RlXCIgOiBvYmogfSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiB0b2dnbGVzIGEgbm9kZSAtIGNsb3NpbmcgaXQgaWYgaXQgaXMgb3Blbiwgb3BlbmluZyBpdCBpZiBpdCBpcyBjbG9zZWRcblx0XHQgKiBAbmFtZSB0b2dnbGVfbm9kZShvYmopXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlIHRvIHRvZ2dsZVxuXHRcdCAqL1xuXHRcdHRvZ2dsZV9ub2RlIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0dmFyIHQxLCB0Mjtcblx0XHRcdGlmKCQudmFrYXRhLmlzX2FycmF5KG9iaikpIHtcblx0XHRcdFx0b2JqID0gb2JqLnNsaWNlKCk7XG5cdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdHRoaXMudG9nZ2xlX25vZGUob2JqW3QxXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRpZih0aGlzLmlzX2Nsb3NlZChvYmopKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLm9wZW5fbm9kZShvYmopO1xuXHRcdFx0fVxuXHRcdFx0aWYodGhpcy5pc19vcGVuKG9iaikpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuY2xvc2Vfbm9kZShvYmopO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogb3BlbnMgYWxsIG5vZGVzIHdpdGhpbiBhIG5vZGUgKG9yIHRoZSB0cmVlKSwgcmV2ZWFsaW5nIHRoZWlyIGNoaWxkcmVuLiBJZiB0aGUgbm9kZSBpcyBub3QgbG9hZGVkIGl0IHdpbGwgYmUgbG9hZGVkIGFuZCBvcGVuZWQgb25jZSByZWFkeS5cblx0XHQgKiBAbmFtZSBvcGVuX2FsbChbb2JqLCBhbmltYXRpb24sIG9yaWdpbmFsX29ial0pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlIHRvIG9wZW4gcmVjdXJzaXZlbHksIG9taXQgdG8gb3BlbiBhbGwgbm9kZXMgaW4gdGhlIHRyZWVcblx0XHQgKiBAcGFyYW0ge051bWJlcn0gYW5pbWF0aW9uIHRoZSBhbmltYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIHdoZW4gb3BlbmluZyB0aGUgbm9kZXMsIHRoZSBkZWZhdWx0IGlzIG5vIGFuaW1hdGlvblxuXHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSByZWZlcmVuY2UgdG8gdGhlIG5vZGUgdGhhdCBzdGFydGVkIHRoZSBwcm9jZXNzIChpbnRlcm5hbCB1c2UpXG5cdFx0ICogQHRyaWdnZXIgb3Blbl9hbGwuanN0cmVlXG5cdFx0ICovXG5cdFx0b3Blbl9hbGwgOiBmdW5jdGlvbiAob2JqLCBhbmltYXRpb24sIG9yaWdpbmFsX29iaikge1xuXHRcdFx0aWYoIW9iaikgeyBvYmogPSAkLmpzdHJlZS5yb290OyB9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0dmFyIGRvbSA9IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCA/IHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpIDogdGhpcy5nZXRfbm9kZShvYmosIHRydWUpLCBpLCBqLCBfdGhpcztcblx0XHRcdGlmKCFkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZHJlbl9kLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdGlmKHRoaXMuaXNfY2xvc2VkKHRoaXMuX21vZGVsLmRhdGFbb2JqLmNoaWxkcmVuX2RbaV1dKSkge1xuXHRcdFx0XHRcdFx0dGhpcy5fbW9kZWwuZGF0YVtvYmouY2hpbGRyZW5fZFtpXV0uc3RhdGUub3BlbmVkID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMudHJpZ2dlcignb3Blbl9hbGwnLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdFx0fVxuXHRcdFx0b3JpZ2luYWxfb2JqID0gb3JpZ2luYWxfb2JqIHx8IGRvbTtcblx0XHRcdF90aGlzID0gdGhpcztcblx0XHRcdGRvbSA9IHRoaXMuaXNfY2xvc2VkKG9iaikgPyBkb20uZmluZCgnLmpzdHJlZS1jbG9zZWQnKS5hZGRCYWNrKCkgOiBkb20uZmluZCgnLmpzdHJlZS1jbG9zZWQnKTtcblx0XHRcdGRvbS5lYWNoKGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0X3RoaXMub3Blbl9ub2RlKFxuXHRcdFx0XHRcdHRoaXMsXG5cdFx0XHRcdFx0ZnVuY3Rpb24obm9kZSwgc3RhdHVzKSB7IGlmKHN0YXR1cyAmJiB0aGlzLmlzX3BhcmVudChub2RlKSkgeyB0aGlzLm9wZW5fYWxsKG5vZGUsIGFuaW1hdGlvbiwgb3JpZ2luYWxfb2JqKTsgfSB9LFxuXHRcdFx0XHRcdGFuaW1hdGlvbiB8fCAwXG5cdFx0XHRcdCk7XG5cdFx0XHR9KTtcblx0XHRcdGlmKG9yaWdpbmFsX29iai5maW5kKCcuanN0cmVlLWNsb3NlZCcpLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gYG9wZW5fYWxsYCBjYWxsIGNvbXBsZXRlc1xuXHRcdFx0XHQgKiBAZXZlbnRcblx0XHRcdFx0ICogQG5hbWUgb3Blbl9hbGwuanN0cmVlXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIHRoZSBvcGVuZWQgbm9kZVxuXHRcdFx0XHQgKi9cblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdvcGVuX2FsbCcsIHsgXCJub2RlXCIgOiB0aGlzLmdldF9ub2RlKG9yaWdpbmFsX29iaikgfSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBjbG9zZXMgYWxsIG5vZGVzIHdpdGhpbiBhIG5vZGUgKG9yIHRoZSB0cmVlKSwgcmV2ZWFsaW5nIHRoZWlyIGNoaWxkcmVuXG5cdFx0ICogQG5hbWUgY2xvc2VfYWxsKFtvYmosIGFuaW1hdGlvbl0pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlIHRvIGNsb3NlIHJlY3Vyc2l2ZWx5LCBvbWl0IHRvIGNsb3NlIGFsbCBub2RlcyBpbiB0aGUgdHJlZVxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBhbmltYXRpb24gdGhlIGFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgd2hlbiBjbG9zaW5nIHRoZSBub2RlcywgdGhlIGRlZmF1bHQgaXMgbm8gYW5pbWF0aW9uXG5cdFx0ICogQHRyaWdnZXIgY2xvc2VfYWxsLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGNsb3NlX2FsbCA6IGZ1bmN0aW9uIChvYmosIGFuaW1hdGlvbikge1xuXHRcdFx0aWYoIW9iaikgeyBvYmogPSAkLmpzdHJlZS5yb290OyB9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0dmFyIGRvbSA9IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCA/IHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpIDogdGhpcy5nZXRfbm9kZShvYmosIHRydWUpLFxuXHRcdFx0XHRfdGhpcyA9IHRoaXMsIGksIGo7XG5cdFx0XHRpZihkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdGRvbSA9IHRoaXMuaXNfb3BlbihvYmopID8gZG9tLmZpbmQoJy5qc3RyZWUtb3BlbicpLmFkZEJhY2soKSA6IGRvbS5maW5kKCcuanN0cmVlLW9wZW4nKTtcblx0XHRcdFx0JChkb20uZ2V0KCkucmV2ZXJzZSgpKS5lYWNoKGZ1bmN0aW9uICgpIHsgX3RoaXMuY2xvc2Vfbm9kZSh0aGlzLCBhbmltYXRpb24gfHwgMCk7IH0pO1xuXHRcdFx0fVxuXHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLmNoaWxkcmVuX2QubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdHRoaXMuX21vZGVsLmRhdGFbb2JqLmNoaWxkcmVuX2RbaV1dLnN0YXRlLm9wZW5lZCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBgY2xvc2VfYWxsYCBjYWxsIGNvbXBsZXRlc1xuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBjbG9zZV9hbGwuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgY2xvc2VkIG5vZGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdjbG9zZV9hbGwnLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY2hlY2tzIGlmIGEgbm9kZSBpcyBkaXNhYmxlZCAobm90IHNlbGVjdGFibGUpXG5cdFx0ICogQG5hbWUgaXNfZGlzYWJsZWQob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmpcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqL1xuXHRcdGlzX2Rpc2FibGVkIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuIG9iaiAmJiBvYmouc3RhdGUgJiYgb2JqLnN0YXRlLmRpc2FibGVkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZW5hYmxlcyBhIG5vZGUgLSBzbyB0aGF0IGl0IGNhbiBiZSBzZWxlY3RlZFxuXHRcdCAqIEBuYW1lIGVuYWJsZV9ub2RlKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGUgdG8gZW5hYmxlXG5cdFx0ICogQHRyaWdnZXIgZW5hYmxlX25vZGUuanN0cmVlXG5cdFx0ICovXG5cdFx0ZW5hYmxlX25vZGUgOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHR2YXIgdDEsIHQyO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRvYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBvYmoubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5lbmFibGVfbm9kZShvYmpbdDFdKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdG9iai5zdGF0ZS5kaXNhYmxlZCA9IGZhbHNlO1xuXHRcdFx0dGhpcy5nZXRfbm9kZShvYmosdHJ1ZSkuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCBmYWxzZSk7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGFuIG5vZGUgaXMgZW5hYmxlZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBlbmFibGVfbm9kZS5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIHRoZSBlbmFibGVkIG5vZGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdlbmFibGVfbm9kZScsIHsgJ25vZGUnIDogb2JqIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZGlzYWJsZXMgYSBub2RlIC0gc28gdGhhdCBpdCBjYW4gbm90IGJlIHNlbGVjdGVkXG5cdFx0ICogQG5hbWUgZGlzYWJsZV9ub2RlKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGUgdG8gZGlzYWJsZVxuXHRcdCAqIEB0cmlnZ2VyIGRpc2FibGVfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRkaXNhYmxlX25vZGUgOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHR2YXIgdDEsIHQyO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRvYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBvYmoubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5kaXNhYmxlX25vZGUob2JqW3QxXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRvYmouc3RhdGUuZGlzYWJsZWQgPSB0cnVlO1xuXHRcdFx0dGhpcy5nZXRfbm9kZShvYmosdHJ1ZSkuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykuYWRkQ2xhc3MoJ2pzdHJlZS1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCB0cnVlKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gbm9kZSBpcyBkaXNhYmxlZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBkaXNhYmxlX25vZGUuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgZGlzYWJsZWQgbm9kZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2Rpc2FibGVfbm9kZScsIHsgJ25vZGUnIDogb2JqIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZGV0ZXJtaW5lcyBpZiBhIG5vZGUgaXMgaGlkZGVuXG5cdFx0ICogQG5hbWUgaXNfaGlkZGVuKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGVcblx0XHQgKi9cblx0XHRpc19oaWRkZW4gOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRyZXR1cm4gb2JqLnN0YXRlLmhpZGRlbiA9PT0gdHJ1ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGhpZGVzIGEgbm9kZSAtIGl0IGlzIHN0aWxsIGluIHRoZSBzdHJ1Y3R1cmUgYnV0IHdpbGwgbm90IGJlIHZpc2libGVcblx0XHQgKiBAbmFtZSBoaWRlX25vZGUob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBoaWRlXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBza2lwX3JlZHJhdyBpbnRlcm5hbCBwYXJhbWV0ZXIgY29udHJvbGxpbmcgaWYgcmVkcmF3IGlzIGNhbGxlZFxuXHRcdCAqIEB0cmlnZ2VyIGhpZGVfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRoaWRlX25vZGUgOiBmdW5jdGlvbiAob2JqLCBza2lwX3JlZHJhdykge1xuXHRcdFx0dmFyIHQxLCB0Mjtcblx0XHRcdGlmKCQudmFrYXRhLmlzX2FycmF5KG9iaikpIHtcblx0XHRcdFx0b2JqID0gb2JqLnNsaWNlKCk7XG5cdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdHRoaXMuaGlkZV9ub2RlKG9ialt0MV0sIHRydWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICghc2tpcF9yZWRyYXcpIHtcblx0XHRcdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0aWYoIW9iai5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0b2JqLnN0YXRlLmhpZGRlbiA9IHRydWU7XG5cdFx0XHRcdHRoaXMuX25vZGVfY2hhbmdlZChvYmoucGFyZW50KTtcblx0XHRcdFx0aWYoIXNraXBfcmVkcmF3KSB7XG5cdFx0XHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gbm9kZSBpcyBoaWRkZW5cblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIGhpZGVfbm9kZS5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIGhpZGRlbiBub2RlXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2hpZGVfbm9kZScsIHsgJ25vZGUnIDogb2JqIH0pO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogc2hvd3MgYSBub2RlXG5cdFx0ICogQG5hbWUgc2hvd19ub2RlKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGUgdG8gc2hvd1xuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gc2tpcF9yZWRyYXcgaW50ZXJuYWwgcGFyYW1ldGVyIGNvbnRyb2xsaW5nIGlmIHJlZHJhdyBpcyBjYWxsZWRcblx0XHQgKiBAdHJpZ2dlciBzaG93X25vZGUuanN0cmVlXG5cdFx0ICovXG5cdFx0c2hvd19ub2RlIDogZnVuY3Rpb24gKG9iaiwgc2tpcF9yZWRyYXcpIHtcblx0XHRcdHZhciB0MSwgdDI7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnNob3dfbm9kZShvYmpbdDFdLCB0cnVlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIXNraXBfcmVkcmF3KSB7XG5cdFx0XHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKG9iai5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0b2JqLnN0YXRlLmhpZGRlbiA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLl9ub2RlX2NoYW5nZWQob2JqLnBhcmVudCk7XG5cdFx0XHRcdGlmKCFza2lwX3JlZHJhdykge1xuXHRcdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0LyoqXG5cdFx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGFuIG5vZGUgaXMgc2hvd25cblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIHNob3dfbm9kZS5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIHNob3duIG5vZGVcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcignc2hvd19ub2RlJywgeyAnbm9kZScgOiBvYmogfSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBoaWRlcyBhbGwgbm9kZXNcblx0XHQgKiBAbmFtZSBoaWRlX2FsbCgpXG5cdFx0ICogQHRyaWdnZXIgaGlkZV9hbGwuanN0cmVlXG5cdFx0ICovXG5cdFx0aGlkZV9hbGwgOiBmdW5jdGlvbiAoc2tpcF9yZWRyYXcpIHtcblx0XHRcdHZhciBpLCBtID0gdGhpcy5fbW9kZWwuZGF0YSwgaWRzID0gW107XG5cdFx0XHRmb3IoaSBpbiBtKSB7XG5cdFx0XHRcdGlmKG0uaGFzT3duUHJvcGVydHkoaSkgJiYgaSAhPT0gJC5qc3RyZWUucm9vdCAmJiAhbVtpXS5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0XHRtW2ldLnN0YXRlLmhpZGRlbiA9IHRydWU7XG5cdFx0XHRcdFx0aWRzLnB1c2goaSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMuX21vZGVsLmZvcmNlX2Z1bGxfcmVkcmF3ID0gdHJ1ZTtcblx0XHRcdGlmKCFza2lwX3JlZHJhdykge1xuXHRcdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdFx0fVxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbGwgbm9kZXMgYXJlIGhpZGRlblxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBoaWRlX2FsbC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGVzIHRoZSBJRHMgb2YgYWxsIGhpZGRlbiBub2Rlc1xuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2hpZGVfYWxsJywgeyAnbm9kZXMnIDogaWRzIH0pO1xuXHRcdFx0cmV0dXJuIGlkcztcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHNob3dzIGFsbCBub2Rlc1xuXHRcdCAqIEBuYW1lIHNob3dfYWxsKClcblx0XHQgKiBAdHJpZ2dlciBzaG93X2FsbC5qc3RyZWVcblx0XHQgKi9cblx0XHRzaG93X2FsbCA6IGZ1bmN0aW9uIChza2lwX3JlZHJhdykge1xuXHRcdFx0dmFyIGksIG0gPSB0aGlzLl9tb2RlbC5kYXRhLCBpZHMgPSBbXTtcblx0XHRcdGZvcihpIGluIG0pIHtcblx0XHRcdFx0aWYobS5oYXNPd25Qcm9wZXJ0eShpKSAmJiBpICE9PSAkLmpzdHJlZS5yb290ICYmIG1baV0uc3RhdGUuaGlkZGVuKSB7XG5cdFx0XHRcdFx0bVtpXS5zdGF0ZS5oaWRkZW4gPSBmYWxzZTtcblx0XHRcdFx0XHRpZHMucHVzaChpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcgPSB0cnVlO1xuXHRcdFx0aWYoIXNraXBfcmVkcmF3KSB7XG5cdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHR9XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGFsbCBub2RlcyBhcmUgc2hvd25cblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgc2hvd19hbGwuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge0FycmF5fSBub2RlcyB0aGUgSURzIG9mIGFsbCBzaG93biBub2Rlc1xuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ3Nob3dfYWxsJywgeyAnbm9kZXMnIDogaWRzIH0pO1xuXHRcdFx0cmV0dXJuIGlkcztcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNhbGxlZCB3aGVuIGEgbm9kZSBpcyBzZWxlY3RlZCBieSB0aGUgdXNlci4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgYWN0aXZhdGVfbm9kZShvYmosIGUpXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGUgdGhlIHJlbGF0ZWQgZXZlbnRcblx0XHQgKiBAdHJpZ2dlciBhY3RpdmF0ZV9ub2RlLmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRhY3RpdmF0ZV9ub2RlIDogZnVuY3Rpb24gKG9iaiwgZSkge1xuXHRcdFx0aWYodGhpcy5pc19kaXNhYmxlZChvYmopKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKCFlIHx8IHR5cGVvZiBlICE9PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRlID0ge307XG5cdFx0XHR9XG5cblx0XHRcdC8vIGVuc3VyZSBsYXN0X2NsaWNrZWQgaXMgc3RpbGwgaW4gdGhlIERPTSwgbWFrZSBpdCBmcmVzaCAobWF5YmUgaXQgd2FzIG1vdmVkPykgYW5kIG1ha2Ugc3VyZSBpdCBpcyBzdGlsbCBzZWxlY3RlZCwgaWYgbm90IC0gbWFrZSBsYXN0X2NsaWNrZWQgdGhlIGxhc3Qgc2VsZWN0ZWQgbm9kZVxuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZCA9IHRoaXMuX2RhdGEuY29yZS5sYXN0X2NsaWNrZWQgJiYgdGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZC5pZCAhPT0gdW5kZWZpbmVkID8gdGhpcy5nZXRfbm9kZSh0aGlzLl9kYXRhLmNvcmUubGFzdF9jbGlja2VkLmlkKSA6IG51bGw7XG5cdFx0XHRpZih0aGlzLl9kYXRhLmNvcmUubGFzdF9jbGlja2VkICYmICF0aGlzLl9kYXRhLmNvcmUubGFzdF9jbGlja2VkLnN0YXRlLnNlbGVjdGVkKSB7IHRoaXMuX2RhdGEuY29yZS5sYXN0X2NsaWNrZWQgPSBudWxsOyB9XG5cdFx0XHRpZighdGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZCAmJiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQubGVuZ3RoKSB7IHRoaXMuX2RhdGEuY29yZS5sYXN0X2NsaWNrZWQgPSB0aGlzLmdldF9ub2RlKHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZFt0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQubGVuZ3RoIC0gMV0pOyB9XG5cblx0XHRcdGlmKCF0aGlzLnNldHRpbmdzLmNvcmUubXVsdGlwbGUgfHwgKCFlLm1ldGFLZXkgJiYgIWUuY3RybEtleSAmJiAhZS5zaGlmdEtleSkgfHwgKGUuc2hpZnRLZXkgJiYgKCF0aGlzLl9kYXRhLmNvcmUubGFzdF9jbGlja2VkIHx8ICF0aGlzLmdldF9wYXJlbnQob2JqKSB8fCB0aGlzLmdldF9wYXJlbnQob2JqKSAhPT0gdGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZC5wYXJlbnQgKSApKSB7XG5cdFx0XHRcdGlmKCF0aGlzLnNldHRpbmdzLmNvcmUubXVsdGlwbGUgJiYgKGUubWV0YUtleSB8fCBlLmN0cmxLZXkgfHwgZS5zaGlmdEtleSkgJiYgdGhpcy5pc19zZWxlY3RlZChvYmopKSB7XG5cdFx0XHRcdFx0dGhpcy5kZXNlbGVjdF9ub2RlKG9iaiwgZmFsc2UsIGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdGlmICghdGhpcy5pc19zZWxlY3RlZChvYmopIHx8IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5sZW5ndGggIT09IDEpIHtcblx0XHRcdFx0XHRcdHRoaXMuZGVzZWxlY3RfYWxsKHRydWUpO1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3Rfbm9kZShvYmosIGZhbHNlLCBmYWxzZSwgZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2NsaWNrZWQgPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRpZihlLnNoaWZ0S2V5KSB7XG5cdFx0XHRcdFx0dmFyIG8gPSB0aGlzLmdldF9ub2RlKG9iaikuaWQsXG5cdFx0XHRcdFx0XHRsID0gdGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZC5pZCxcblx0XHRcdFx0XHRcdHAgPSB0aGlzLmdldF9ub2RlKHRoaXMuX2RhdGEuY29yZS5sYXN0X2NsaWNrZWQucGFyZW50KS5jaGlsZHJlbixcblx0XHRcdFx0XHRcdGMgPSBmYWxzZSxcblx0XHRcdFx0XHRcdGksIGo7XG5cdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gcC5sZW5ndGg7IGkgPCBqOyBpICs9IDEpIHtcblx0XHRcdFx0XHRcdC8vIHNlcGFyYXRlIElGcyB3b3JrIHdoZW0gbyBhbmQgbCBhcmUgdGhlIHNhbWVcblx0XHRcdFx0XHRcdGlmKHBbaV0gPT09IG8pIHtcblx0XHRcdFx0XHRcdFx0YyA9ICFjO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYocFtpXSA9PT0gbCkge1xuXHRcdFx0XHRcdFx0XHRjID0gIWM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZighdGhpcy5pc19kaXNhYmxlZChwW2ldKSAmJiAoYyB8fCBwW2ldID09PSBvIHx8IHBbaV0gPT09IGwpKSB7XG5cdFx0XHRcdFx0XHRcdGlmICghdGhpcy5pc19oaWRkZW4ocFtpXSkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlbGVjdF9ub2RlKHBbaV0sIHRydWUsIGZhbHNlLCBlKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGlmICghZS5jdHJsS2V5KSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5kZXNlbGVjdF9ub2RlKHBbaV0sIHRydWUsIGUpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHsgJ2FjdGlvbicgOiAnc2VsZWN0X25vZGUnLCAnbm9kZScgOiB0aGlzLmdldF9ub2RlKG9iaiksICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsICdldmVudCcgOiBlIH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdGlmKCF0aGlzLmlzX3NlbGVjdGVkKG9iaikpIHtcblx0XHRcdFx0XHRcdGlmIChlLmN0cmxLZXkpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfY2xpY2tlZCA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0X25vZGUob2JqLCBmYWxzZSwgZmFsc2UsIGUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMuZGVzZWxlY3Rfbm9kZShvYmosIGZhbHNlLCBlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gbm9kZSBpcyBjbGlja2VkIG9yIGludGVyY2F0ZWQgd2l0aCBieSB0aGUgdXNlclxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBhY3RpdmF0ZV9ub2RlLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCB0aGUgb29yaWdpbmFsIGV2ZW50IChpZiBhbnkpIHdoaWNoIHRyaWdnZXJlZCB0aGUgY2FsbCAobWF5IGJlIGFuIGVtcHR5IG9iamVjdClcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdhY3RpdmF0ZV9ub2RlJywgeyAnbm9kZScgOiB0aGlzLmdldF9ub2RlKG9iaiksICdldmVudCcgOiBlIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogYXBwbGllcyB0aGUgaG92ZXIgc3RhdGUgb24gYSBub2RlLCBjYWxsZWQgd2hlbiBhIG5vZGUgaXMgaG92ZXJlZCBieSB0aGUgdXNlci4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgaG92ZXJfbm9kZShvYmopXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqXG5cdFx0ICogQHRyaWdnZXIgaG92ZXJfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRob3Zlcl9ub2RlIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0aWYoIW9iaiB8fCAhb2JqLmxlbmd0aCB8fCBvYmouY2hpbGRyZW4oJy5qc3RyZWUtaG92ZXJlZCcpLmxlbmd0aCkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR2YXIgbyA9IHRoaXMuZWxlbWVudC5maW5kKCcuanN0cmVlLWhvdmVyZWQnKSwgdCA9IHRoaXMuZWxlbWVudDtcblx0XHRcdGlmKG8gJiYgby5sZW5ndGgpIHsgdGhpcy5kZWhvdmVyX25vZGUobyk7IH1cblxuXHRcdFx0b2JqLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmFkZENsYXNzKCdqc3RyZWUtaG92ZXJlZCcpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlIGlzIGhvdmVyZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgaG92ZXJfbm9kZS5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignaG92ZXJfbm9kZScsIHsgJ25vZGUnIDogdGhpcy5nZXRfbm9kZShvYmopIH0pO1xuXHRcdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7IHQuYXR0cignYXJpYS1hY3RpdmVkZXNjZW5kYW50Jywgb2JqWzBdLmlkKTsgfSwgMCk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiByZW1vdmVzIHRoZSBob3ZlciBzdGF0ZSBmcm9tIGEgbm9kZWNhbGxlZCB3aGVuIGEgbm9kZSBpcyBubyBsb25nZXIgaG92ZXJlZCBieSB0aGUgdXNlci4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgZGVob3Zlcl9ub2RlKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmpcblx0XHQgKiBAdHJpZ2dlciBkZWhvdmVyX25vZGUuanN0cmVlXG5cdFx0ICovXG5cdFx0ZGVob3Zlcl9ub2RlIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0aWYoIW9iaiB8fCAhb2JqLmxlbmd0aCB8fCAhb2JqLmNoaWxkcmVuKCcuanN0cmVlLWhvdmVyZWQnKS5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0b2JqLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLnJlbW92ZUNsYXNzKCdqc3RyZWUtaG92ZXJlZCcpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlIGlzIG5vIGxvbmdlciBob3ZlcmVkXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGRlaG92ZXJfbm9kZS5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignZGVob3Zlcl9ub2RlJywgeyAnbm9kZScgOiB0aGlzLmdldF9ub2RlKG9iaikgfSk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBzZWxlY3QgYSBub2RlXG5cdFx0ICogQG5hbWUgc2VsZWN0X25vZGUob2JqIFssIHN1cHJlc3NfZXZlbnQsIHByZXZlbnRfb3Blbl0pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIGFuIGFycmF5IGNhbiBiZSB1c2VkIHRvIHNlbGVjdCBtdWx0aXBsZSBub2Rlc1xuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gc3VwcmVzc19ldmVudCBpZiBzZXQgdG8gYHRydWVgIHRoZSBgY2hhbmdlZC5qc3RyZWVgIGV2ZW50IHdvbid0IGJlIHRyaWdnZXJlZFxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJldmVudF9vcGVuIGlmIHNldCB0byBgdHJ1ZWAgcGFyZW50cyBvZiB0aGUgc2VsZWN0ZWQgbm9kZSB3b24ndCBiZSBvcGVuZWRcblx0XHQgKiBAdHJpZ2dlciBzZWxlY3Rfbm9kZS5qc3RyZWUsIGNoYW5nZWQuanN0cmVlXG5cdFx0ICovXG5cdFx0c2VsZWN0X25vZGUgOiBmdW5jdGlvbiAob2JqLCBzdXByZXNzX2V2ZW50LCBwcmV2ZW50X29wZW4sIGUpIHtcblx0XHRcdHZhciBkb20sIHQxLCB0MiwgdGg7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdF9ub2RlKG9ialt0MV0sIHN1cHJlc3NfZXZlbnQsIHByZXZlbnRfb3BlbiwgZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSk7XG5cdFx0XHRpZighb2JqLnN0YXRlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5zZWxlY3RlZCA9IHRydWU7XG5cdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5wdXNoKG9iai5pZCk7XG5cdFx0XHRcdGlmKCFwcmV2ZW50X29wZW4pIHtcblx0XHRcdFx0XHRkb20gPSB0aGlzLl9vcGVuX3RvKG9iaik7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoZG9tICYmIGRvbS5sZW5ndGgpIHtcblx0XHRcdFx0XHRkb20uY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykuYWRkQ2xhc3MoJ2pzdHJlZS1jbGlja2VkJykuYXR0cignYXJpYS1zZWxlY3RlZCcsIHRydWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlIGlzIHNlbGVjdGVkXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBzZWxlY3Rfbm9kZS5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdFx0ICogQHBhcmFtIHtBcnJheX0gc2VsZWN0ZWQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCB0aGUgZXZlbnQgKGlmIGFueSkgdGhhdCB0cmlnZ2VyZWQgdGhpcyBzZWxlY3Rfbm9kZVxuXHRcdFx0XHQgKi9cblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdzZWxlY3Rfbm9kZScsIHsgJ25vZGUnIDogb2JqLCAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLCAnZXZlbnQnIDogZSB9KTtcblx0XHRcdFx0aWYoIXN1cHJlc3NfZXZlbnQpIHtcblx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBzZWxlY3Rpb24gY2hhbmdlc1xuXHRcdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHRcdCAqIEBuYW1lIGNoYW5nZWQuanN0cmVlXG5cdFx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIHRoZSBhY3Rpb24gdGhhdCBjYXVzZWQgdGhlIHNlbGVjdGlvbiB0byBjaGFuZ2Vcblx0XHRcdFx0XHQgKiBAcGFyYW0ge0FycmF5fSBzZWxlY3RlZCB0aGUgY3VycmVudCBzZWxlY3Rpb25cblx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgdGhlIGV2ZW50IChpZiBhbnkpIHRoYXQgdHJpZ2dlcmVkIHRoaXMgY2hhbmdlZCBldmVudFxuXHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHsgJ2FjdGlvbicgOiAnc2VsZWN0X25vZGUnLCAnbm9kZScgOiBvYmosICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsICdldmVudCcgOiBlIH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBkZXNlbGVjdCBhIG5vZGVcblx0XHQgKiBAbmFtZSBkZXNlbGVjdF9ub2RlKG9iaiBbLCBzdXByZXNzX2V2ZW50XSlcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogYW4gYXJyYXkgY2FuIGJlIHVzZWQgdG8gZGVzZWxlY3QgbXVsdGlwbGUgbm9kZXNcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHJlc3NfZXZlbnQgaWYgc2V0IHRvIGB0cnVlYCB0aGUgYGNoYW5nZWQuanN0cmVlYCBldmVudCB3b24ndCBiZSB0cmlnZ2VyZWRcblx0XHQgKiBAdHJpZ2dlciBkZXNlbGVjdF9ub2RlLmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRkZXNlbGVjdF9ub2RlIDogZnVuY3Rpb24gKG9iaiwgc3VwcmVzc19ldmVudCwgZSkge1xuXHRcdFx0dmFyIHQxLCB0MiwgZG9tO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRvYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBvYmoubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5kZXNlbGVjdF9ub2RlKG9ialt0MV0sIHN1cHJlc3NfZXZlbnQsIGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0ZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0aWYob2JqLnN0YXRlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5zZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQgPSAkLnZha2F0YS5hcnJheV9yZW1vdmVfaXRlbSh0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsIG9iai5pZCk7XG5cdFx0XHRcdGlmKGRvbS5sZW5ndGgpIHtcblx0XHRcdFx0XHRkb20uY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1jbGlja2VkJykuYXR0cignYXJpYS1zZWxlY3RlZCcsIGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gbm9kZSBpcyBkZXNlbGVjdGVkXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBkZXNlbGVjdF9ub2RlLmpzdHJlZVxuXHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZVxuXHRcdFx0XHQgKiBAcGFyYW0ge0FycmF5fSBzZWxlY3RlZCB0aGUgY3VycmVudCBzZWxlY3Rpb25cblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IHRoZSBldmVudCAoaWYgYW55KSB0aGF0IHRyaWdnZXJlZCB0aGlzIGRlc2VsZWN0X25vZGVcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcignZGVzZWxlY3Rfbm9kZScsIHsgJ25vZGUnIDogb2JqLCAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLCAnZXZlbnQnIDogZSB9KTtcblx0XHRcdFx0aWYoIXN1cHJlc3NfZXZlbnQpIHtcblx0XHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2NoYW5nZWQnLCB7ICdhY3Rpb24nIDogJ2Rlc2VsZWN0X25vZGUnLCAnbm9kZScgOiBvYmosICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsICdldmVudCcgOiBlIH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBzZWxlY3QgYWxsIG5vZGVzIGluIHRoZSB0cmVlXG5cdFx0ICogQG5hbWUgc2VsZWN0X2FsbChbc3VwcmVzc19ldmVudF0pXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBzdXByZXNzX2V2ZW50IGlmIHNldCB0byBgdHJ1ZWAgdGhlIGBjaGFuZ2VkLmpzdHJlZWAgZXZlbnQgd29uJ3QgYmUgdHJpZ2dlcmVkXG5cdFx0ICogQHRyaWdnZXIgc2VsZWN0X2FsbC5qc3RyZWUsIGNoYW5nZWQuanN0cmVlXG5cdFx0ICovXG5cdFx0c2VsZWN0X2FsbCA6IGZ1bmN0aW9uIChzdXByZXNzX2V2ZW50KSB7XG5cdFx0XHR2YXIgdG1wID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdChbXSksIGksIGo7XG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQgPSB0aGlzLl9tb2RlbC5kYXRhWyQuanN0cmVlLnJvb3RdLmNoaWxkcmVuX2QuY29uY2F0KCk7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldXSkge1xuXHRcdFx0XHRcdHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldXS5zdGF0ZS5zZWxlY3RlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMucmVkcmF3KHRydWUpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbGwgbm9kZXMgYXJlIHNlbGVjdGVkXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIHNlbGVjdF9hbGwuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge0FycmF5fSBzZWxlY3RlZCB0aGUgY3VycmVudCBzZWxlY3Rpb25cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzZWxlY3RfYWxsJywgeyAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkIH0pO1xuXHRcdFx0aWYoIXN1cHJlc3NfZXZlbnQpIHtcblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdjaGFuZ2VkJywgeyAnYWN0aW9uJyA6ICdzZWxlY3RfYWxsJywgJ3NlbGVjdGVkJyA6IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZCwgJ29sZF9zZWxlY3Rpb24nIDogdG1wIH0pO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZGVzZWxlY3QgYWxsIHNlbGVjdGVkIG5vZGVzXG5cdFx0ICogQG5hbWUgZGVzZWxlY3RfYWxsKFtzdXByZXNzX2V2ZW50XSlcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHJlc3NfZXZlbnQgaWYgc2V0IHRvIGB0cnVlYCB0aGUgYGNoYW5nZWQuanN0cmVlYCBldmVudCB3b24ndCBiZSB0cmlnZ2VyZWRcblx0XHQgKiBAdHJpZ2dlciBkZXNlbGVjdF9hbGwuanN0cmVlLCBjaGFuZ2VkLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGRlc2VsZWN0X2FsbCA6IGZ1bmN0aW9uIChzdXByZXNzX2V2ZW50KSB7XG5cdFx0XHR2YXIgdG1wID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdChbXSksIGksIGo7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldXSkge1xuXHRcdFx0XHRcdHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldXS5zdGF0ZS5zZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQgPSBbXTtcblx0XHRcdHRoaXMuZWxlbWVudC5maW5kKCcuanN0cmVlLWNsaWNrZWQnKS5yZW1vdmVDbGFzcygnanN0cmVlLWNsaWNrZWQnKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgZmFsc2UpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbGwgbm9kZXMgYXJlIGRlc2VsZWN0ZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgZGVzZWxlY3RfYWxsLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIHByZXZpb3VzIHNlbGVjdGlvblxuXHRcdFx0ICogQHBhcmFtIHtBcnJheX0gc2VsZWN0ZWQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignZGVzZWxlY3RfYWxsJywgeyAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLCAnbm9kZScgOiB0bXAgfSk7XG5cdFx0XHRpZighc3VwcmVzc19ldmVudCkge1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2NoYW5nZWQnLCB7ICdhY3Rpb24nIDogJ2Rlc2VsZWN0X2FsbCcsICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsICdvbGRfc2VsZWN0aW9uJyA6IHRtcCB9KTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNoZWNrcyBpZiBhIG5vZGUgaXMgc2VsZWN0ZWRcblx0XHQgKiBAbmFtZSBpc19zZWxlY3RlZChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9ICBvYmpcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqL1xuXHRcdGlzX3NlbGVjdGVkIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9iai5zdGF0ZS5zZWxlY3RlZDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCBhbiBhcnJheSBvZiBhbGwgc2VsZWN0ZWQgbm9kZXNcblx0XHQgKiBAbmFtZSBnZXRfc2VsZWN0ZWQoW2Z1bGxdKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSAgZnVsbCBpZiBzZXQgdG8gYHRydWVgIHRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGNvbnNpc3Qgb2YgdGhlIGZ1bGwgbm9kZSBvYmplY3RzLCBvdGhlcndpc2UgLSBvbmx5IElEcyB3aWxsIGJlIHJldHVybmVkXG5cdFx0ICogQHJldHVybiB7QXJyYXl9XG5cdFx0ICovXG5cdFx0Z2V0X3NlbGVjdGVkIDogZnVuY3Rpb24gKGZ1bGwpIHtcblx0XHRcdHJldHVybiBmdWxsID8gJC5tYXAodGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLCBmdW5jdGlvbiAoaSkgeyByZXR1cm4gdGhpcy5nZXRfbm9kZShpKTsgfS5iaW5kKHRoaXMpKSA6IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5zbGljZSgpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0IGFuIGFycmF5IG9mIGFsbCB0b3AgbGV2ZWwgc2VsZWN0ZWQgbm9kZXMgKGlnbm9yaW5nIGNoaWxkcmVuIG9mIHNlbGVjdGVkIG5vZGVzKVxuXHRcdCAqIEBuYW1lIGdldF90b3Bfc2VsZWN0ZWQoW2Z1bGxdKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSAgZnVsbCBpZiBzZXQgdG8gYHRydWVgIHRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGNvbnNpc3Qgb2YgdGhlIGZ1bGwgbm9kZSBvYmplY3RzLCBvdGhlcndpc2UgLSBvbmx5IElEcyB3aWxsIGJlIHJldHVybmVkXG5cdFx0ICogQHJldHVybiB7QXJyYXl9XG5cdFx0ICovXG5cdFx0Z2V0X3RvcF9zZWxlY3RlZCA6IGZ1bmN0aW9uIChmdWxsKSB7XG5cdFx0XHR2YXIgdG1wID0gdGhpcy5nZXRfc2VsZWN0ZWQodHJ1ZSksXG5cdFx0XHRcdG9iaiA9IHt9LCBpLCBqLCBrLCBsO1xuXHRcdFx0Zm9yKGkgPSAwLCBqID0gdG1wLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRvYmpbdG1wW2ldLmlkXSA9IHRtcFtpXTtcblx0XHRcdH1cblx0XHRcdGZvcihpID0gMCwgaiA9IHRtcC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wW2ldLmNoaWxkcmVuX2QubGVuZ3RoOyBrIDwgbDsgaysrKSB7XG5cdFx0XHRcdFx0aWYob2JqW3RtcFtpXS5jaGlsZHJlbl9kW2tdXSkge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIG9ialt0bXBbaV0uY2hpbGRyZW5fZFtrXV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0bXAgPSBbXTtcblx0XHRcdGZvcihpIGluIG9iaikge1xuXHRcdFx0XHRpZihvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHR0bXAucHVzaChpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZ1bGwgPyAkLm1hcCh0bXAsIGZ1bmN0aW9uIChpKSB7IHJldHVybiB0aGlzLmdldF9ub2RlKGkpOyB9LmJpbmQodGhpcykpIDogdG1wO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0IGFuIGFycmF5IG9mIGFsbCBib3R0b20gbGV2ZWwgc2VsZWN0ZWQgbm9kZXMgKGlnbm9yaW5nIHNlbGVjdGVkIHBhcmVudHMpXG5cdFx0ICogQG5hbWUgZ2V0X2JvdHRvbV9zZWxlY3RlZChbZnVsbF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9ICBmdWxsIGlmIHNldCB0byBgdHJ1ZWAgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgY29uc2lzdCBvZiB0aGUgZnVsbCBub2RlIG9iamVjdHMsIG90aGVyd2lzZSAtIG9ubHkgSURzIHdpbGwgYmUgcmV0dXJuZWRcblx0XHQgKiBAcmV0dXJuIHtBcnJheX1cblx0XHQgKi9cblx0XHRnZXRfYm90dG9tX3NlbGVjdGVkIDogZnVuY3Rpb24gKGZ1bGwpIHtcblx0XHRcdHZhciB0bXAgPSB0aGlzLmdldF9zZWxlY3RlZCh0cnVlKSxcblx0XHRcdFx0b2JqID0gW10sIGksIGo7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSB0bXAubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKCF0bXBbaV0uY2hpbGRyZW4ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0b2JqLnB1c2godG1wW2ldLmlkKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZ1bGwgPyAkLm1hcChvYmosIGZ1bmN0aW9uIChpKSB7IHJldHVybiB0aGlzLmdldF9ub2RlKGkpOyB9LmJpbmQodGhpcykpIDogb2JqO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgdHJlZSBzbyB0aGF0IGl0IGNhbiBiZSByZXN0b3JlZCBsYXRlciB3aXRoIGBzZXRfc3RhdGUoc3RhdGUpYC4gVXNlZCBpbnRlcm5hbGx5LlxuXHRcdCAqIEBuYW1lIGdldF9zdGF0ZSgpXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAcmV0dXJuIHtPYmplY3R9XG5cdFx0ICovXG5cdFx0Z2V0X3N0YXRlIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIHN0YXRlXHQ9IHtcblx0XHRcdFx0J2NvcmUnIDoge1xuXHRcdFx0XHRcdCdvcGVuJyA6IFtdLFxuXHRcdFx0XHRcdCdsb2FkZWQnIDogW10sXG5cdFx0XHRcdFx0J3Njcm9sbCcgOiB7XG5cdFx0XHRcdFx0XHQnbGVmdCcgOiB0aGlzLmVsZW1lbnQuc2Nyb2xsTGVmdCgpLFxuXHRcdFx0XHRcdFx0J3RvcCcgOiB0aGlzLmVsZW1lbnQuc2Nyb2xsVG9wKClcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdC8qIVxuXHRcdFx0XHRcdCd0aGVtZXMnIDoge1xuXHRcdFx0XHRcdFx0J25hbWUnIDogdGhpcy5nZXRfdGhlbWUoKSxcblx0XHRcdFx0XHRcdCdpY29ucycgOiB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmljb25zLFxuXHRcdFx0XHRcdFx0J2RvdHMnIDogdGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5kb3RzXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHQqL1xuXHRcdFx0XHRcdCdzZWxlY3RlZCcgOiBbXVxuXHRcdFx0XHR9XG5cdFx0XHR9LCBpO1xuXHRcdFx0Zm9yKGkgaW4gdGhpcy5fbW9kZWwuZGF0YSkge1xuXHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhLmhhc093blByb3BlcnR5KGkpKSB7XG5cdFx0XHRcdFx0aWYoaSAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRcdFx0aWYodGhpcy5fbW9kZWwuZGF0YVtpXS5zdGF0ZS5sb2FkZWQgJiYgdGhpcy5zZXR0aW5ncy5jb3JlLmxvYWRlZF9zdGF0ZSkge1xuXHRcdFx0XHRcdFx0XHRzdGF0ZS5jb3JlLmxvYWRlZC5wdXNoKGkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYodGhpcy5fbW9kZWwuZGF0YVtpXS5zdGF0ZS5vcGVuZWQpIHtcblx0XHRcdFx0XHRcdFx0c3RhdGUuY29yZS5vcGVuLnB1c2goaSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW2ldLnN0YXRlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRcdHN0YXRlLmNvcmUuc2VsZWN0ZWQucHVzaChpKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBzdGF0ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHNldHMgdGhlIHN0YXRlIG9mIHRoZSB0cmVlLiBVc2VkIGludGVybmFsbHkuXG5cdFx0ICogQG5hbWUgc2V0X3N0YXRlKHN0YXRlIFssIGNhbGxiYWNrXSlcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSB0aGUgc3RhdGUgdG8gcmVzdG9yZS4gS2VlcCBpbiBtaW5kIHRoaXMgb2JqZWN0IGlzIHBhc3NlZCBieSByZWZlcmVuY2UgYW5kIGpzdHJlZSB3aWxsIG1vZGlmeSBpdC5cblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBleGVjdXRlIG9uY2UgdGhlIHN0YXRlIGlzIHJlc3RvcmVkLlxuXHRcdCAqIEB0cmlnZ2VyIHNldF9zdGF0ZS5qc3RyZWVcblx0XHQgKi9cblx0XHRzZXRfc3RhdGUgOiBmdW5jdGlvbiAoc3RhdGUsIGNhbGxiYWNrKSB7XG5cdFx0XHRpZihzdGF0ZSkge1xuXHRcdFx0XHRpZihzdGF0ZS5jb3JlICYmIHN0YXRlLmNvcmUuc2VsZWN0ZWQgJiYgc3RhdGUuY29yZS5pbml0aWFsX3NlbGVjdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0c3RhdGUuY29yZS5pbml0aWFsX3NlbGVjdGlvbiA9IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5jb25jYXQoW10pLnNvcnQoKS5qb2luKCcsJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoc3RhdGUuY29yZSkge1xuXHRcdFx0XHRcdHZhciByZXMsIG4sIHQsIF90aGlzLCBpO1xuXHRcdFx0XHRcdGlmKHN0YXRlLmNvcmUubG9hZGVkKSB7XG5cdFx0XHRcdFx0XHRpZighdGhpcy5zZXR0aW5ncy5jb3JlLmxvYWRlZF9zdGF0ZSB8fCAhJC52YWthdGEuaXNfYXJyYXkoc3RhdGUuY29yZS5sb2FkZWQpIHx8ICFzdGF0ZS5jb3JlLmxvYWRlZC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIHN0YXRlLmNvcmUubG9hZGVkO1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNldF9zdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2xvYWRfbm9kZXMoc3RhdGUuY29yZS5sb2FkZWQsIGZ1bmN0aW9uIChub2Rlcykge1xuXHRcdFx0XHRcdFx0XHRcdGRlbGV0ZSBzdGF0ZS5jb3JlLmxvYWRlZDtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNldF9zdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYoc3RhdGUuY29yZS5vcGVuKSB7XG5cdFx0XHRcdFx0XHRpZighJC52YWthdGEuaXNfYXJyYXkoc3RhdGUuY29yZS5vcGVuKSB8fCAhc3RhdGUuY29yZS5vcGVuLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgc3RhdGUuY29yZS5vcGVuO1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNldF9zdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2xvYWRfbm9kZXMoc3RhdGUuY29yZS5vcGVuLCBmdW5jdGlvbiAobm9kZXMpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLm9wZW5fbm9kZShub2RlcywgZmFsc2UsIDApO1xuXHRcdFx0XHRcdFx0XHRcdGRlbGV0ZSBzdGF0ZS5jb3JlLm9wZW47XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZXRfc3RhdGUoc3RhdGUsIGNhbGxiYWNrKTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKHN0YXRlLmNvcmUuc2Nyb2xsKSB7XG5cdFx0XHRcdFx0XHRpZihzdGF0ZS5jb3JlLnNjcm9sbCAmJiBzdGF0ZS5jb3JlLnNjcm9sbC5sZWZ0ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LnNjcm9sbExlZnQoc3RhdGUuY29yZS5zY3JvbGwubGVmdCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZihzdGF0ZS5jb3JlLnNjcm9sbCAmJiBzdGF0ZS5jb3JlLnNjcm9sbC50b3AgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmVsZW1lbnQuc2Nyb2xsVG9wKHN0YXRlLmNvcmUuc2Nyb2xsLnRvcCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRkZWxldGUgc3RhdGUuY29yZS5zY3JvbGw7XG5cdFx0XHRcdFx0XHR0aGlzLnNldF9zdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZihzdGF0ZS5jb3JlLnNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRfdGhpcyA9IHRoaXM7XG5cdFx0XHRcdFx0XHRpZiAoc3RhdGUuY29yZS5pbml0aWFsX3NlbGVjdGlvbiA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0XHRcdHN0YXRlLmNvcmUuaW5pdGlhbF9zZWxlY3Rpb24gPT09IHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZC5jb25jYXQoW10pLnNvcnQoKS5qb2luKCcsJylcblx0XHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmRlc2VsZWN0X2FsbCgpO1xuXHRcdFx0XHRcdFx0XHQkLmVhY2goc3RhdGUuY29yZS5zZWxlY3RlZCwgZnVuY3Rpb24gKGksIHYpIHtcblx0XHRcdFx0XHRcdFx0XHRfdGhpcy5zZWxlY3Rfbm9kZSh2LCBmYWxzZSwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZGVsZXRlIHN0YXRlLmNvcmUuaW5pdGlhbF9zZWxlY3Rpb247XG5cdFx0XHRcdFx0XHRkZWxldGUgc3RhdGUuY29yZS5zZWxlY3RlZDtcblx0XHRcdFx0XHRcdHRoaXMuc2V0X3N0YXRlKHN0YXRlLCBjYWxsYmFjayk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGZvcihpIGluIHN0YXRlKSB7XG5cdFx0XHRcdFx0XHRpZihzdGF0ZS5oYXNPd25Qcm9wZXJ0eShpKSAmJiBpICE9PSBcImNvcmVcIiAmJiAkLmluQXJyYXkoaSwgdGhpcy5zZXR0aW5ncy5wbHVnaW5zKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIHN0YXRlW2ldO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZigkLmlzRW1wdHlPYmplY3Qoc3RhdGUuY29yZSkpIHtcblx0XHRcdFx0XHRcdGRlbGV0ZSBzdGF0ZS5jb3JlO1xuXHRcdFx0XHRcdFx0dGhpcy5zZXRfc3RhdGUoc3RhdGUsIGNhbGxiYWNrKTtcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoJC5pc0VtcHR5T2JqZWN0KHN0YXRlKSkge1xuXHRcdFx0XHRcdHN0YXRlID0gbnVsbDtcblx0XHRcdFx0XHRpZihjYWxsYmFjaykgeyBjYWxsYmFjay5jYWxsKHRoaXMpOyB9XG5cdFx0XHRcdFx0LyoqXG5cdFx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYSBgc2V0X3N0YXRlYCBjYWxsIGNvbXBsZXRlc1xuXHRcdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHRcdCAqIEBuYW1lIHNldF9zdGF0ZS5qc3RyZWVcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHR0aGlzLnRyaWdnZXIoJ3NldF9zdGF0ZScpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHJlZnJlc2hlcyB0aGUgdHJlZSAtIGFsbCBub2RlcyBhcmUgcmVsb2FkZWQgd2l0aCBjYWxscyB0byBgbG9hZF9ub2RlYC5cblx0XHQgKiBAbmFtZSByZWZyZXNoKClcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IHNraXBfbG9hZGluZyBhbiBvcHRpb24gdG8gc2tpcCBzaG93aW5nIHRoZSBsb2FkaW5nIGluZGljYXRvclxuXHRcdCAqIEBwYXJhbSB7TWl4ZWR9IGZvcmdldF9zdGF0ZSBpZiBzZXQgdG8gYHRydWVgIHN0YXRlIHdpbGwgbm90IGJlIHJlYXBwbGllZCwgaWYgc2V0IHRvIGEgZnVuY3Rpb24gKHJlY2VpdmluZyB0aGUgY3VycmVudCBzdGF0ZSBhcyBhcmd1bWVudCkgdGhlIHJlc3VsdCBvZiB0aGF0IGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCBhcyBzdGF0ZVxuXHRcdCAqIEB0cmlnZ2VyIHJlZnJlc2guanN0cmVlXG5cdFx0ICovXG5cdFx0cmVmcmVzaCA6IGZ1bmN0aW9uIChza2lwX2xvYWRpbmcsIGZvcmdldF9zdGF0ZSkge1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnN0YXRlID0gZm9yZ2V0X3N0YXRlID09PSB0cnVlID8ge30gOiB0aGlzLmdldF9zdGF0ZSgpO1xuXHRcdFx0aWYoZm9yZ2V0X3N0YXRlICYmICQudmFrYXRhLmlzX2Z1bmN0aW9uKGZvcmdldF9zdGF0ZSkpIHsgdGhpcy5fZGF0YS5jb3JlLnN0YXRlID0gZm9yZ2V0X3N0YXRlLmNhbGwodGhpcywgdGhpcy5fZGF0YS5jb3JlLnN0YXRlKTsgfVxuXHRcdFx0dGhpcy5fY250ID0gMDtcblx0XHRcdHRoaXMuX21vZGVsLmRhdGEgPSB7fTtcblx0XHRcdHRoaXMuX21vZGVsLmRhdGFbJC5qc3RyZWUucm9vdF0gPSB7XG5cdFx0XHRcdGlkIDogJC5qc3RyZWUucm9vdCxcblx0XHRcdFx0cGFyZW50IDogbnVsbCxcblx0XHRcdFx0cGFyZW50cyA6IFtdLFxuXHRcdFx0XHRjaGlsZHJlbiA6IFtdLFxuXHRcdFx0XHRjaGlsZHJlbl9kIDogW10sXG5cdFx0XHRcdHN0YXRlIDogeyBsb2FkZWQgOiBmYWxzZSB9XG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkID0gW107XG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9jbGlja2VkID0gbnVsbDtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS5mb2N1c2VkID0gbnVsbDtcblxuXHRcdFx0dmFyIGMgPSB0aGlzLmdldF9jb250YWluZXJfdWwoKVswXS5jbGFzc05hbWU7XG5cdFx0XHRpZighc2tpcF9sb2FkaW5nKSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudC5odG1sKFwiPFwiK1widWwgY2xhc3M9J1wiK2MrXCInIHJvbGU9J2dyb3VwJz48XCIrXCJsaSBjbGFzcz0nanN0cmVlLWluaXRpYWwtbm9kZSBqc3RyZWUtbG9hZGluZyBqc3RyZWUtbGVhZiBqc3RyZWUtbGFzdCcgcm9sZT0nbm9uZScgaWQ9J2pcIit0aGlzLl9pZCtcIl9sb2FkaW5nJz48aSBjbGFzcz0nanN0cmVlLWljb24ganN0cmVlLW9jbCc+PC9pPjxcIitcImEgY2xhc3M9J2pzdHJlZS1hbmNob3InIHJvbGU9J3RyZWVpdGVtJyBocmVmPScjJz48aSBjbGFzcz0nanN0cmVlLWljb24ganN0cmVlLXRoZW1laWNvbi1oaWRkZW4nPjwvaT5cIiArIHRoaXMuZ2V0X3N0cmluZyhcIkxvYWRpbmcgLi4uXCIpICsgXCI8L2E+PC9saT48L3VsPlwiKTtcblx0XHRcdFx0dGhpcy5lbGVtZW50LmF0dHIoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcsJ2onK3RoaXMuX2lkKydfbG9hZGluZycpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5sb2FkX25vZGUoJC5qc3RyZWUucm9vdCwgZnVuY3Rpb24gKG8sIHMpIHtcblx0XHRcdFx0aWYocykge1xuXHRcdFx0XHRcdHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpWzBdLmNsYXNzTmFtZSA9IGM7XG5cdFx0XHRcdFx0aWYodGhpcy5fZmlyc3RDaGlsZCh0aGlzLmdldF9jb250YWluZXJfdWwoKVswXSkpIHtcblx0XHRcdFx0XHRcdHRoaXMuZWxlbWVudC5hdHRyKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnLHRoaXMuX2ZpcnN0Q2hpbGQodGhpcy5nZXRfY29udGFpbmVyX3VsKClbMF0pLmlkKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5zZXRfc3RhdGUoJC5leHRlbmQodHJ1ZSwge30sIHRoaXMuX2RhdGEuY29yZS5zdGF0ZSksIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdC8qKlxuXHRcdFx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYSBgcmVmcmVzaGAgY2FsbCBjb21wbGV0ZXNcblx0XHRcdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHRcdFx0ICogQG5hbWUgcmVmcmVzaC5qc3RyZWVcblx0XHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdFx0dGhpcy50cmlnZ2VyKCdyZWZyZXNoJyk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLnN0YXRlID0gbnVsbDtcblx0XHRcdH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcmVmcmVzaGVzIGEgbm9kZSBpbiB0aGUgdHJlZSAocmVsb2FkIGl0cyBjaGlsZHJlbikgYWxsIG9wZW5lZCBub2RlcyBpbnNpZGUgdGhhdCBub2RlIGFyZSByZWxvYWRlZCB3aXRoIGNhbGxzIHRvIGBsb2FkX25vZGVgLlxuXHRcdCAqIEBuYW1lIHJlZnJlc2hfbm9kZShvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZVxuXHRcdCAqIEB0cmlnZ2VyIHJlZnJlc2hfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRyZWZyZXNoX25vZGUgOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHZhciBvcGVuZWQgPSBbXSwgdG9fbG9hZCA9IFtdLCBzID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdChbXSk7XG5cdFx0XHR0b19sb2FkLnB1c2gob2JqLmlkKTtcblx0XHRcdGlmKG9iai5zdGF0ZS5vcGVuZWQgPT09IHRydWUpIHsgb3BlbmVkLnB1c2gob2JqLmlkKTsgfVxuXHRcdFx0dGhpcy5nZXRfbm9kZShvYmosIHRydWUpLmZpbmQoJy5qc3RyZWUtb3BlbicpLmVhY2goZnVuY3Rpb24oKSB7IHRvX2xvYWQucHVzaCh0aGlzLmlkKTsgb3BlbmVkLnB1c2godGhpcy5pZCk7IH0pO1xuXHRcdFx0dGhpcy5fbG9hZF9ub2Rlcyh0b19sb2FkLCBmdW5jdGlvbiAobm9kZXMpIHtcblx0XHRcdFx0dGhpcy5vcGVuX25vZGUob3BlbmVkLCBmYWxzZSwgMCk7XG5cdFx0XHRcdHRoaXMuc2VsZWN0X25vZGUocyk7XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgcmVmcmVzaGVkXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSByZWZyZXNoX25vZGUuanN0cmVlXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIC0gdGhlIHJlZnJlc2hlZCBub2RlXG5cdFx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGVzIC0gYW4gYXJyYXkgb2YgdGhlIElEcyBvZiB0aGUgbm9kZXMgdGhhdCB3ZXJlIHJlbG9hZGVkXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ3JlZnJlc2hfbm9kZScsIHsgJ25vZGUnIDogb2JqLCAnbm9kZXMnIDogbm9kZXMgfSk7XG5cdFx0XHR9LmJpbmQodGhpcyksIGZhbHNlLCB0cnVlKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHNldCAoY2hhbmdlKSB0aGUgSUQgb2YgYSBub2RlXG5cdFx0ICogQG5hbWUgc2V0X2lkKG9iaiwgaWQpXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZVxuXHRcdCAqIEBwYXJhbSAge1N0cmluZ30gaWQgdGhlIG5ldyBJRFxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICogQHRyaWdnZXIgc2V0X2lkLmpzdHJlZVxuXHRcdCAqL1xuXHRcdHNldF9pZCA6IGZ1bmN0aW9uIChvYmosIGlkKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHZhciBpLCBqLCBtID0gdGhpcy5fbW9kZWwuZGF0YSwgb2xkID0gb2JqLmlkO1xuXHRcdFx0aWQgPSBpZC50b1N0cmluZygpO1xuXHRcdFx0Ly8gdXBkYXRlIHBhcmVudHMgKHJlcGxhY2UgY3VycmVudCBJRCB3aXRoIG5ldyBvbmUgaW4gY2hpbGRyZW4gYW5kIGNoaWxkcmVuX2QpXG5cdFx0XHRtW29iai5wYXJlbnRdLmNoaWxkcmVuWyQuaW5BcnJheShvYmouaWQsIG1bb2JqLnBhcmVudF0uY2hpbGRyZW4pXSA9IGlkO1xuXHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdG1bb2JqLnBhcmVudHNbaV1dLmNoaWxkcmVuX2RbJC5pbkFycmF5KG9iai5pZCwgbVtvYmoucGFyZW50c1tpXV0uY2hpbGRyZW5fZCldID0gaWQ7XG5cdFx0XHR9XG5cdFx0XHQvLyB1cGRhdGUgY2hpbGRyZW4gKHJlcGxhY2UgY3VycmVudCBJRCB3aXRoIG5ldyBvbmUgaW4gcGFyZW50IGFuZCBwYXJlbnRzKVxuXHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRtW29iai5jaGlsZHJlbltpXV0ucGFyZW50ID0gaWQ7XG5cdFx0XHR9XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGRyZW5fZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0bVtvYmouY2hpbGRyZW5fZFtpXV0ucGFyZW50c1skLmluQXJyYXkob2JqLmlkLCBtW29iai5jaGlsZHJlbl9kW2ldXS5wYXJlbnRzKV0gPSBpZDtcblx0XHRcdH1cblx0XHRcdGkgPSAkLmluQXJyYXkob2JqLmlkLCB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQpO1xuXHRcdFx0aWYoaSAhPT0gLTEpIHsgdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkW2ldID0gaWQ7IH1cblx0XHRcdC8vIHVwZGF0ZSBtb2RlbCBhbmQgb2JqIGl0c2VsZiAob2JqLmlkLCB0aGlzLl9tb2RlbC5kYXRhW0tFWV0pXG5cdFx0XHRpID0gdGhpcy5nZXRfbm9kZShvYmouaWQsIHRydWUpO1xuXHRcdFx0aWYoaSkge1xuXHRcdFx0XHRpLmF0dHIoJ2lkJywgaWQpOyAvLy5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5hdHRyKCdpZCcsIGlkICsgJ19hbmNob3InKS5lbmQoKS5hdHRyKCdhcmlhLWxhYmVsbGVkYnknLCBpZCArICdfYW5jaG9yJyk7XG5cdFx0XHRcdGlmKHRoaXMuZWxlbWVudC5hdHRyKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnKSA9PT0gb2JqLmlkKSB7XG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50LmF0dHIoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcsIGlkKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZGVsZXRlIG1bb2JqLmlkXTtcblx0XHRcdG9iai5pZCA9IGlkO1xuXHRcdFx0b2JqLmxpX2F0dHIuaWQgPSBpZDtcblx0XHRcdG1baWRdID0gb2JqO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaWQgdmFsdWUgaXMgY2hhbmdlZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBzZXRfaWQuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZVxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IG9sZCB0aGUgb2xkIGlkXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignc2V0X2lkJyx7IFwibm9kZVwiIDogb2JqLCBcIm5ld1wiIDogb2JqLmlkLCBcIm9sZFwiIDogb2xkIH0pO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBnZXQgdGhlIHRleHQgdmFsdWUgb2YgYSBub2RlXG5cdFx0ICogQG5hbWUgZ2V0X3RleHQob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmogdGhlIG5vZGVcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd9XG5cdFx0ICovXG5cdFx0Z2V0X3RleHQgOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRyZXR1cm4gKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSA/IGZhbHNlIDogb2JqLnRleHQ7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBzZXQgdGhlIHRleHQgdmFsdWUgb2YgYSBub2RlLiBVc2VkIGludGVybmFsbHksIHBsZWFzZSB1c2UgYHJlbmFtZV9ub2RlKG9iaiwgdmFsKWAuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBzZXRfdGV4dChvYmosIHZhbClcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqIHRoZSBub2RlLCB5b3UgY2FuIHBhc3MgYW4gYXJyYXkgdG8gc2V0IHRoZSB0ZXh0IG9uIG11bHRpcGxlIG5vZGVzXG5cdFx0ICogQHBhcmFtICB7U3RyaW5nfSB2YWwgdGhlIG5ldyB0ZXh0IHZhbHVlXG5cdFx0ICogQHJldHVybiB7Qm9vbGVhbn1cblx0XHQgKiBAdHJpZ2dlciBzZXRfdGV4dC5qc3RyZWVcblx0XHQgKi9cblx0XHRzZXRfdGV4dCA6IGZ1bmN0aW9uIChvYmosIHZhbCkge1xuXHRcdFx0dmFyIHQxLCB0Mjtcblx0XHRcdGlmKCQudmFrYXRhLmlzX2FycmF5KG9iaikpIHtcblx0XHRcdFx0b2JqID0gb2JqLnNsaWNlKCk7XG5cdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdHRoaXMuc2V0X3RleHQob2JqW3QxXSwgdmFsKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0b2JqLnRleHQgPSB2YWw7XG5cdFx0XHRpZih0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSkubGVuZ3RoKSB7XG5cdFx0XHRcdHRoaXMucmVkcmF3X25vZGUob2JqLmlkKTtcblx0XHRcdH1cblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYSBub2RlIHRleHQgdmFsdWUgaXMgY2hhbmdlZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBzZXRfdGV4dC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IHRoZSBuZXcgdmFsdWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzZXRfdGV4dCcseyBcIm9ialwiIDogb2JqLCBcInRleHRcIiA6IHZhbCB9KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyBhIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBub2RlIChvciB0aGUgd2hvbGUgdHJlZSlcblx0XHQgKiBAbmFtZSBnZXRfanNvbihbb2JqLCBvcHRpb25zXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gb3B0aW9ucy5ub19zdGF0ZSBkbyBub3QgcmV0dXJuIHN0YXRlIGluZm9ybWF0aW9uXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gb3B0aW9ucy5ub19pZCBkbyBub3QgcmV0dXJuIElEXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gb3B0aW9ucy5ub19jaGlsZHJlbiBkbyBub3QgaW5jbHVkZSBjaGlsZHJlblxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IG9wdGlvbnMubm9fZGF0YSBkbyBub3QgaW5jbHVkZSBub2RlIGRhdGFcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBvcHRpb25zLm5vX2xpX2F0dHIgZG8gbm90IGluY2x1ZGUgTEkgYXR0cmlidXRlc1xuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IG9wdGlvbnMubm9fYV9hdHRyIGRvIG5vdCBpbmNsdWRlIEEgYXR0cmlidXRlc1xuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IG9wdGlvbnMuZmxhdCByZXR1cm4gZmxhdCBKU09OIGluc3RlYWQgb2YgbmVzdGVkXG5cdFx0ICogQHJldHVybiB7T2JqZWN0fVxuXHRcdCAqL1xuXHRcdGdldF9qc29uIDogZnVuY3Rpb24gKG9iaiwgb3B0aW9ucywgZmxhdCkge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmogfHwgJC5qc3RyZWUucm9vdCk7XG5cdFx0XHRpZighb2JqKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0aWYob3B0aW9ucyAmJiBvcHRpb25zLmZsYXQgJiYgIWZsYXQpIHsgZmxhdCA9IFtdOyB9XG5cdFx0XHR2YXIgdG1wID0ge1xuXHRcdFx0XHQnaWQnIDogb2JqLmlkLFxuXHRcdFx0XHQndGV4dCcgOiBvYmoudGV4dCxcblx0XHRcdFx0J2ljb24nIDogdGhpcy5nZXRfaWNvbihvYmopLFxuXHRcdFx0XHQnbGlfYXR0cicgOiAkLmV4dGVuZCh0cnVlLCB7fSwgb2JqLmxpX2F0dHIpLFxuXHRcdFx0XHQnYV9hdHRyJyA6ICQuZXh0ZW5kKHRydWUsIHt9LCBvYmouYV9hdHRyKSxcblx0XHRcdFx0J3N0YXRlJyA6IHt9LFxuXHRcdFx0XHQnZGF0YScgOiBvcHRpb25zICYmIG9wdGlvbnMubm9fZGF0YSA/IGZhbHNlIDogJC5leHRlbmQodHJ1ZSwgJC52YWthdGEuaXNfYXJyYXkob2JqLmRhdGEpP1tdOnt9LCBvYmouZGF0YSlcblx0XHRcdFx0Ly8oIHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKS5sZW5ndGggPyB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSkuZGF0YSgpIDogb2JqLmRhdGEgKSxcblx0XHRcdH0sIGksIGo7XG5cdFx0XHRpZihvcHRpb25zICYmIG9wdGlvbnMuZmxhdCkge1xuXHRcdFx0XHR0bXAucGFyZW50ID0gb2JqLnBhcmVudDtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHR0bXAuY2hpbGRyZW4gPSBbXTtcblx0XHRcdH1cblx0XHRcdGlmKCFvcHRpb25zIHx8ICFvcHRpb25zLm5vX3N0YXRlKSB7XG5cdFx0XHRcdGZvcihpIGluIG9iai5zdGF0ZSkge1xuXHRcdFx0XHRcdGlmKG9iai5zdGF0ZS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0dG1wLnN0YXRlW2ldID0gb2JqLnN0YXRlW2ldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVsZXRlIHRtcC5zdGF0ZTtcblx0XHRcdH1cblx0XHRcdGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5ub19saV9hdHRyKSB7XG5cdFx0XHRcdGRlbGV0ZSB0bXAubGlfYXR0cjtcblx0XHRcdH1cblx0XHRcdGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5ub19hX2F0dHIpIHtcblx0XHRcdFx0ZGVsZXRlIHRtcC5hX2F0dHI7XG5cdFx0XHR9XG5cdFx0XHRpZihvcHRpb25zICYmIG9wdGlvbnMubm9faWQpIHtcblx0XHRcdFx0ZGVsZXRlIHRtcC5pZDtcblx0XHRcdFx0aWYodG1wLmxpX2F0dHIgJiYgdG1wLmxpX2F0dHIuaWQpIHtcblx0XHRcdFx0XHRkZWxldGUgdG1wLmxpX2F0dHIuaWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYodG1wLmFfYXR0ciAmJiB0bXAuYV9hdHRyLmlkKSB7XG5cdFx0XHRcdFx0ZGVsZXRlIHRtcC5hX2F0dHIuaWQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5mbGF0ICYmIG9iai5pZCAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRmbGF0LnB1c2godG1wKTtcblx0XHRcdH1cblx0XHRcdGlmKCFvcHRpb25zIHx8ICFvcHRpb25zLm5vX2NoaWxkcmVuKSB7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRpZihvcHRpb25zICYmIG9wdGlvbnMuZmxhdCkge1xuXHRcdFx0XHRcdFx0dGhpcy5nZXRfanNvbihvYmouY2hpbGRyZW5baV0sIG9wdGlvbnMsIGZsYXQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbi5wdXNoKHRoaXMuZ2V0X2pzb24ob2JqLmNoaWxkcmVuW2ldLCBvcHRpb25zKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gb3B0aW9ucyAmJiBvcHRpb25zLmZsYXQgPyBmbGF0IDogKG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCA/IHRtcC5jaGlsZHJlbiA6IHRtcCk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBjcmVhdGUgYSBuZXcgbm9kZSAoZG8gbm90IGNvbmZ1c2Ugd2l0aCBsb2FkX25vZGUpXG5cdFx0ICogQG5hbWUgY3JlYXRlX25vZGUoW3Bhciwgbm9kZSwgcG9zLCBjYWxsYmFjaywgaXNfbG9hZGVkXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gICBwYXIgICAgICAgdGhlIHBhcmVudCBub2RlICh0byBjcmVhdGUgYSByb290IG5vZGUgdXNlIGVpdGhlciBcIiNcIiAoc3RyaW5nKSBvciBgbnVsbGApXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9ICAgbm9kZSAgICAgIHRoZSBkYXRhIGZvciB0aGUgbmV3IG5vZGUgKGEgdmFsaWQgSlNPTiBvYmplY3QsIG9yIGEgc2ltcGxlIHN0cmluZyB3aXRoIHRoZSBuYW1lKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSAgIHBvcyAgICAgICB0aGUgaW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBub2RlLCBcImZpcnN0XCIgYW5kIFwibGFzdFwiIGFyZSBhbHNvIHN1cHBvcnRlZCwgZGVmYXVsdCBpcyBcImxhc3RcIlxuXHRcdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFjayBhIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbmNlIHRoZSBub2RlIGlzIGNyZWF0ZWRcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBpc19sb2FkZWQgaW50ZXJuYWwgYXJndW1lbnQgaW5kaWNhdGluZyBpZiB0aGUgcGFyZW50IG5vZGUgd2FzIHN1Y2Nlc2Z1bGx5IGxvYWRlZFxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gICAgICAgICAgICB0aGUgSUQgb2YgdGhlIG5ld2x5IGNyZWF0ZSBub2RlXG5cdFx0ICogQHRyaWdnZXIgbW9kZWwuanN0cmVlLCBjcmVhdGVfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRjcmVhdGVfbm9kZSA6IGZ1bmN0aW9uIChwYXIsIG5vZGUsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCkge1xuXHRcdFx0aWYocGFyID09PSBudWxsKSB7IHBhciA9ICQuanN0cmVlLnJvb3Q7IH1cblx0XHRcdHBhciA9IHRoaXMuZ2V0X25vZGUocGFyKTtcblx0XHRcdGlmKCFwYXIpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRwb3MgPSBwb3MgPT09IHVuZGVmaW5lZCA/IFwibGFzdFwiIDogcG9zO1xuXHRcdFx0aWYoIXBvcy50b1N0cmluZygpLm1hdGNoKC9eKGJlZm9yZXxhZnRlcikkLykgJiYgIWlzX2xvYWRlZCAmJiAhdGhpcy5pc19sb2FkZWQocGFyKSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5sb2FkX25vZGUocGFyLCBmdW5jdGlvbiAoKSB7IHRoaXMuY3JlYXRlX25vZGUocGFyLCBub2RlLCBwb3MsIGNhbGxiYWNrLCB0cnVlKTsgfSk7XG5cdFx0XHR9XG5cdFx0XHRpZighbm9kZSkgeyBub2RlID0geyBcInRleHRcIiA6IHRoaXMuZ2V0X3N0cmluZygnTmV3IG5vZGUnKSB9OyB9XG5cdFx0XHRpZih0eXBlb2Ygbm9kZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHRub2RlID0geyBcInRleHRcIiA6IG5vZGUgfTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5vZGUgPSAkLmV4dGVuZCh0cnVlLCB7fSwgbm9kZSk7XG5cdFx0XHR9XG5cdFx0XHRpZihub2RlLnRleHQgPT09IHVuZGVmaW5lZCkgeyBub2RlLnRleHQgPSB0aGlzLmdldF9zdHJpbmcoJ05ldyBub2RlJyk7IH1cblx0XHRcdHZhciB0bXAsIGRwYywgaSwgajtcblxuXHRcdFx0aWYocGFyLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdGlmKHBvcyA9PT0gXCJiZWZvcmVcIikgeyBwb3MgPSBcImZpcnN0XCI7IH1cblx0XHRcdFx0aWYocG9zID09PSBcImFmdGVyXCIpIHsgcG9zID0gXCJsYXN0XCI7IH1cblx0XHRcdH1cblx0XHRcdHN3aXRjaChwb3MpIHtcblx0XHRcdFx0Y2FzZSBcImJlZm9yZVwiOlxuXHRcdFx0XHRcdHRtcCA9IHRoaXMuZ2V0X25vZGUocGFyLnBhcmVudCk7XG5cdFx0XHRcdFx0cG9zID0gJC5pbkFycmF5KHBhci5pZCwgdG1wLmNoaWxkcmVuKTtcblx0XHRcdFx0XHRwYXIgPSB0bXA7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJhZnRlclwiIDpcblx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKHBhci5wYXJlbnQpO1xuXHRcdFx0XHRcdHBvcyA9ICQuaW5BcnJheShwYXIuaWQsIHRtcC5jaGlsZHJlbikgKyAxO1xuXHRcdFx0XHRcdHBhciA9IHRtcDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBcImluc2lkZVwiOlxuXHRcdFx0XHRjYXNlIFwiZmlyc3RcIjpcblx0XHRcdFx0XHRwb3MgPSAwO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwibGFzdFwiOlxuXHRcdFx0XHRcdHBvcyA9IHBhci5jaGlsZHJlbi5sZW5ndGg7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0aWYoIXBvcykgeyBwb3MgPSAwOyB9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZihwb3MgPiBwYXIuY2hpbGRyZW4ubGVuZ3RoKSB7IHBvcyA9IHBhci5jaGlsZHJlbi5sZW5ndGg7IH1cblx0XHRcdGlmKCFub2RlLmlkKSB7IG5vZGUuaWQgPSB0cnVlOyB9XG5cdFx0XHRpZighdGhpcy5jaGVjayhcImNyZWF0ZV9ub2RlXCIsIG5vZGUsIHBhciwgcG9zKSkge1xuXHRcdFx0XHR0aGlzLnNldHRpbmdzLmNvcmUuZXJyb3IuY2FsbCh0aGlzLCB0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvcik7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKG5vZGUuaWQgPT09IHRydWUpIHsgZGVsZXRlIG5vZGUuaWQ7IH1cblx0XHRcdG5vZGUgPSB0aGlzLl9wYXJzZV9tb2RlbF9mcm9tX2pzb24obm9kZSwgcGFyLmlkLCBwYXIucGFyZW50cy5jb25jYXQoKSk7XG5cdFx0XHRpZighbm9kZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHRtcCA9IHRoaXMuZ2V0X25vZGUobm9kZSk7XG5cdFx0XHRkcGMgPSBbXTtcblx0XHRcdGRwYy5wdXNoKG5vZGUpO1xuXHRcdFx0ZHBjID0gZHBjLmNvbmNhdCh0bXAuY2hpbGRyZW5fZCk7XG5cdFx0XHR0aGlzLnRyaWdnZXIoJ21vZGVsJywgeyBcIm5vZGVzXCIgOiBkcGMsIFwicGFyZW50XCIgOiBwYXIuaWQgfSk7XG5cblx0XHRcdHBhci5jaGlsZHJlbl9kID0gcGFyLmNoaWxkcmVuX2QuY29uY2F0KGRwYyk7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBwYXIucGFyZW50cy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0dGhpcy5fbW9kZWwuZGF0YVtwYXIucGFyZW50c1tpXV0uY2hpbGRyZW5fZCA9IHRoaXMuX21vZGVsLmRhdGFbcGFyLnBhcmVudHNbaV1dLmNoaWxkcmVuX2QuY29uY2F0KGRwYyk7XG5cdFx0XHR9XG5cdFx0XHRub2RlID0gdG1wO1xuXHRcdFx0dG1wID0gW107XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBwYXIuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdHRtcFtpID49IHBvcyA/IGkrMSA6IGldID0gcGFyLmNoaWxkcmVuW2ldO1xuXHRcdFx0fVxuXHRcdFx0dG1wW3Bvc10gPSBub2RlLmlkO1xuXHRcdFx0cGFyLmNoaWxkcmVuID0gdG1wO1xuXG5cdFx0XHR0aGlzLnJlZHJhd19ub2RlKHBhciwgdHJ1ZSk7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGEgbm9kZSBpcyBjcmVhdGVkXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGNyZWF0ZV9ub2RlLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXJlbnQgdGhlIHBhcmVudCdzIElEXG5cdFx0XHQgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgbm9kZSBhbW9uZyB0aGUgcGFyZW50J3MgY2hpbGRyZW5cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdjcmVhdGVfbm9kZScsIHsgXCJub2RlXCIgOiB0aGlzLmdldF9ub2RlKG5vZGUpLCBcInBhcmVudFwiIDogcGFyLmlkLCBcInBvc2l0aW9uXCIgOiBwb3MgfSk7XG5cdFx0XHRpZihjYWxsYmFjaykgeyBjYWxsYmFjay5jYWxsKHRoaXMsIHRoaXMuZ2V0X25vZGUobm9kZSkpOyB9XG5cdFx0XHRyZXR1cm4gbm9kZS5pZDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHNldCB0aGUgdGV4dCB2YWx1ZSBvZiBhIG5vZGVcblx0XHQgKiBAbmFtZSByZW5hbWVfbm9kZShvYmosIHZhbClcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqIHRoZSBub2RlLCB5b3UgY2FuIHBhc3MgYW4gYXJyYXkgdG8gcmVuYW1lIG11bHRpcGxlIG5vZGVzIHRvIHRoZSBzYW1lIG5hbWVcblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IHZhbCB0aGUgbmV3IHRleHQgdmFsdWVcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqIEB0cmlnZ2VyIHJlbmFtZV9ub2RlLmpzdHJlZVxuXHRcdCAqL1xuXHRcdHJlbmFtZV9ub2RlIDogZnVuY3Rpb24gKG9iaiwgdmFsKSB7XG5cdFx0XHR2YXIgdDEsIHQyLCBvbGQ7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnJlbmFtZV9ub2RlKG9ialt0MV0sIHZhbCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdG9sZCA9IG9iai50ZXh0O1xuXHRcdFx0aWYoIXRoaXMuY2hlY2soXCJyZW5hbWVfbm9kZVwiLCBvYmosIHRoaXMuZ2V0X3BhcmVudChvYmopLCB2YWwpKSB7XG5cdFx0XHRcdHRoaXMuc2V0dGluZ3MuY29yZS5lcnJvci5jYWxsKHRoaXMsIHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5zZXRfdGV4dChvYmosIHZhbCk7IC8vIC5hcHBseSh0aGlzLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgcmVuYW1lZFxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSByZW5hbWVfbm9kZS5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHQgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCB0aGUgbmV3IHZhbHVlXG5cdFx0XHQgKiBAcGFyYW0ge1N0cmluZ30gb2xkIHRoZSBvbGQgdmFsdWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdyZW5hbWVfbm9kZScsIHsgXCJub2RlXCIgOiBvYmosIFwidGV4dFwiIDogdmFsLCBcIm9sZFwiIDogb2xkIH0pO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiByZW1vdmUgYSBub2RlXG5cdFx0ICogQG5hbWUgZGVsZXRlX25vZGUob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmogdGhlIG5vZGUsIHlvdSBjYW4gcGFzcyBhbiBhcnJheSB0byBkZWxldGUgbXVsdGlwbGUgbm9kZXNcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqIEB0cmlnZ2VyIGRlbGV0ZV9ub2RlLmpzdHJlZSwgY2hhbmdlZC5qc3RyZWVcblx0XHQgKi9cblx0XHRkZWxldGVfbm9kZSA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdHZhciB0MSwgdDIsIHBhciwgcG9zLCB0bXAsIGksIGosIGssIGwsIGMsIHRvcCwgbGZ0O1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRvYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBvYmoubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5kZWxldGVfbm9kZShvYmpbdDFdKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0cGFyID0gdGhpcy5nZXRfbm9kZShvYmoucGFyZW50KTtcblx0XHRcdHBvcyA9ICQuaW5BcnJheShvYmouaWQsIHBhci5jaGlsZHJlbik7XG5cdFx0XHRjID0gZmFsc2U7XG5cdFx0XHRpZighdGhpcy5jaGVjayhcImRlbGV0ZV9ub2RlXCIsIG9iaiwgcGFyLCBwb3MpKSB7XG5cdFx0XHRcdHRoaXMuc2V0dGluZ3MuY29yZS5lcnJvci5jYWxsKHRoaXMsIHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0aWYocG9zICE9PSAtMSkge1xuXHRcdFx0XHRwYXIuY2hpbGRyZW4gPSAkLnZha2F0YS5hcnJheV9yZW1vdmUocGFyLmNoaWxkcmVuLCBwb3MpO1xuXHRcdFx0fVxuXHRcdFx0dG1wID0gb2JqLmNoaWxkcmVuX2QuY29uY2F0KFtdKTtcblx0XHRcdHRtcC5wdXNoKG9iai5pZCk7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBvYmoucGFyZW50cy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0dGhpcy5fbW9kZWwuZGF0YVtvYmoucGFyZW50c1tpXV0uY2hpbGRyZW5fZCA9ICQudmFrYXRhLmFycmF5X2ZpbHRlcih0aGlzLl9tb2RlbC5kYXRhW29iai5wYXJlbnRzW2ldXS5jaGlsZHJlbl9kLCBmdW5jdGlvbiAodikge1xuXHRcdFx0XHRcdHJldHVybiAkLmluQXJyYXkodiwgdG1wKSA9PT0gLTE7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wLmxlbmd0aDsgayA8IGw7IGsrKykge1xuXHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW3RtcFtrXV0uc3RhdGUuc2VsZWN0ZWQpIHtcblx0XHRcdFx0XHRjID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGMpIHtcblx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkID0gJC52YWthdGEuYXJyYXlfZmlsdGVyKHRoaXMuX2RhdGEuY29yZS5zZWxlY3RlZCwgZnVuY3Rpb24gKHYpIHtcblx0XHRcdFx0XHRyZXR1cm4gJC5pbkFycmF5KHYsIHRtcCkgPT09IC0xO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYSBub2RlIGlzIGRlbGV0ZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgZGVsZXRlX25vZGUuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZVxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IHBhcmVudCB0aGUgcGFyZW50J3MgSURcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdkZWxldGVfbm9kZScsIHsgXCJub2RlXCIgOiBvYmosIFwicGFyZW50XCIgOiBwYXIuaWQgfSk7XG5cdFx0XHRpZihjKSB7XG5cdFx0XHRcdHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHsgJ2FjdGlvbicgOiAnZGVsZXRlX25vZGUnLCAnbm9kZScgOiBvYmosICdzZWxlY3RlZCcgOiB0aGlzLl9kYXRhLmNvcmUuc2VsZWN0ZWQsICdwYXJlbnQnIDogcGFyLmlkIH0pO1xuXHRcdFx0fVxuXHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wLmxlbmd0aDsgayA8IGw7IGsrKykge1xuXHRcdFx0XHRkZWxldGUgdGhpcy5fbW9kZWwuZGF0YVt0bXBba11dO1xuXHRcdFx0fVxuXHRcdFx0aWYoJC5pbkFycmF5KHRoaXMuX2RhdGEuY29yZS5mb2N1c2VkLCB0bXApICE9PSAtMSkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUuZm9jdXNlZCA9IG51bGw7XG5cdFx0XHRcdHRvcCA9IHRoaXMuZWxlbWVudFswXS5zY3JvbGxUb3A7XG5cdFx0XHRcdGxmdCA9IHRoaXMuZWxlbWVudFswXS5zY3JvbGxMZWZ0O1xuXHRcdFx0XHRpZihwYXIuaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRpZiAodGhpcy5fbW9kZWwuZGF0YVskLmpzdHJlZS5yb290XS5jaGlsZHJlblswXSkge1xuXHRcdFx0XHRcdFx0dGhpcy5nZXRfbm9kZSh0aGlzLl9tb2RlbC5kYXRhWyQuanN0cmVlLnJvb3RdLmNoaWxkcmVuWzBdLCB0cnVlKS5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHR0aGlzLmdldF9ub2RlKHBhciwgdHJ1ZSkuY2hpbGRyZW4oJy5qc3RyZWUtYW5jaG9yJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmVsZW1lbnRbMF0uc2Nyb2xsVG9wICA9IHRvcDtcblx0XHRcdFx0dGhpcy5lbGVtZW50WzBdLnNjcm9sbExlZnQgPSBsZnQ7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnJlZHJhd19ub2RlKHBhciwgdHJ1ZSk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNoZWNrIGlmIGFuIG9wZXJhdGlvbiBpcyBwcmVtaXR0ZWQgb24gdGhlIHRyZWUuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIGNoZWNrKGNoaywgb2JqLCBwYXIsIHBvcylcblx0XHQgKiBAcGFyYW0gIHtTdHJpbmd9IGNoayB0aGUgb3BlcmF0aW9uIHRvIGNoZWNrLCBjYW4gYmUgXCJjcmVhdGVfbm9kZVwiLCBcInJlbmFtZV9ub2RlXCIsIFwiZGVsZXRlX25vZGVcIiwgXCJjb3B5X25vZGVcIiBvciBcIm1vdmVfbm9kZVwiXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBwYXIgdGhlIHBhcmVudFxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBwb3MgdGhlIHBvc2l0aW9uIHRvIGluc2VydCBhdCwgb3IgaWYgXCJyZW5hbWVfbm9kZVwiIC0gdGhlIG5ldyBuYW1lXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG1vcmUgc29tZSB2YXJpb3VzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24sIGZvciBleGFtcGxlIGlmIGEgXCJtb3ZlX25vZGVcIiBvcGVyYXRpb25zIGlzIHRyaWdnZXJlZCBieSBETkQgdGhpcyB3aWxsIGJlIHRoZSBob3ZlcmVkIG5vZGVcblx0XHQgKiBAcmV0dXJuIHtCb29sZWFufVxuXHRcdCAqL1xuXHRcdGNoZWNrIDogZnVuY3Rpb24gKGNoaywgb2JqLCBwYXIsIHBvcywgbW9yZSkge1xuXHRcdFx0b2JqID0gb2JqICYmIG9iai5pZCA/IG9iaiA6IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdHBhciA9IHBhciAmJiBwYXIuaWQgPyBwYXIgOiB0aGlzLmdldF9ub2RlKHBhcik7XG5cdFx0XHR2YXIgdG1wID0gY2hrLm1hdGNoKC9eKG1vdmVfbm9kZXxjb3B5X25vZGV8Y3JlYXRlX25vZGUpJC9pKSA/IHBhciA6IG9iaixcblx0XHRcdFx0Y2hjID0gdGhpcy5zZXR0aW5ncy5jb3JlLmNoZWNrX2NhbGxiYWNrO1xuXHRcdFx0aWYoY2hrID09PSBcIm1vdmVfbm9kZVwiIHx8IGNoayA9PT0gXCJjb3B5X25vZGVcIikge1xuXHRcdFx0XHRpZigoIW1vcmUgfHwgIW1vcmUuaXNfbXVsdGkpICYmIChjaGsgPT09IFwibW92ZV9ub2RlXCIgJiYgJC5pbkFycmF5KG9iai5pZCwgcGFyLmNoaWxkcmVuKSA9PT0gcG9zKSkge1xuXHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2NoZWNrJywgJ3BsdWdpbicgOiAnY29yZScsICdpZCcgOiAnY29yZV8wOCcsICdyZWFzb24nIDogJ01vdmluZyBub2RlIHRvIGl0cyBjdXJyZW50IHBvc2l0aW9uJywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoeyAnY2hrJyA6IGNoaywgJ3BvcycgOiBwb3MsICdvYmonIDogb2JqICYmIG9iai5pZCA/IG9iai5pZCA6IGZhbHNlLCAncGFyJyA6IHBhciAmJiBwYXIuaWQgPyBwYXIuaWQgOiBmYWxzZSB9KSB9O1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZigoIW1vcmUgfHwgIW1vcmUuaXNfbXVsdGkpICYmIChvYmouaWQgPT09IHBhci5pZCB8fCAoY2hrID09PSBcIm1vdmVfbm9kZVwiICYmICQuaW5BcnJheShvYmouaWQsIHBhci5jaGlsZHJlbikgPT09IHBvcykgfHwgJC5pbkFycmF5KHBhci5pZCwgb2JqLmNoaWxkcmVuX2QpICE9PSAtMSkpIHtcblx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvciA9IHsgJ2Vycm9yJyA6ICdjaGVjaycsICdwbHVnaW4nIDogJ2NvcmUnLCAnaWQnIDogJ2NvcmVfMDEnLCAncmVhc29uJyA6ICdNb3ZpbmcgcGFyZW50IGluc2lkZSBjaGlsZCcsICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2NoaycgOiBjaGssICdwb3MnIDogcG9zLCAnb2JqJyA6IG9iaiAmJiBvYmouaWQgPyBvYmouaWQgOiBmYWxzZSwgJ3BhcicgOiBwYXIgJiYgcGFyLmlkID8gcGFyLmlkIDogZmFsc2UgfSkgfTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKHRtcCAmJiB0bXAuZGF0YSkgeyB0bXAgPSB0bXAuZGF0YTsgfVxuXHRcdFx0aWYodG1wICYmIHRtcC5mdW5jdGlvbnMgJiYgKHRtcC5mdW5jdGlvbnNbY2hrXSA9PT0gZmFsc2UgfHwgdG1wLmZ1bmN0aW9uc1tjaGtdID09PSB0cnVlKSkge1xuXHRcdFx0XHRpZih0bXAuZnVuY3Rpb25zW2Noa10gPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IgPSB7ICdlcnJvcicgOiAnY2hlY2snLCAncGx1Z2luJyA6ICdjb3JlJywgJ2lkJyA6ICdjb3JlXzAyJywgJ3JlYXNvbicgOiAnTm9kZSBkYXRhIHByZXZlbnRzIGZ1bmN0aW9uOiAnICsgY2hrLCAnZGF0YScgOiBKU09OLnN0cmluZ2lmeSh7ICdjaGsnIDogY2hrLCAncG9zJyA6IHBvcywgJ29iaicgOiBvYmogJiYgb2JqLmlkID8gb2JqLmlkIDogZmFsc2UsICdwYXInIDogcGFyICYmIHBhci5pZCA/IHBhci5pZCA6IGZhbHNlIH0pIH07XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRtcC5mdW5jdGlvbnNbY2hrXTtcblx0XHRcdH1cblx0XHRcdGlmKGNoYyA9PT0gZmFsc2UgfHwgKCQudmFrYXRhLmlzX2Z1bmN0aW9uKGNoYykgJiYgY2hjLmNhbGwodGhpcywgY2hrLCBvYmosIHBhciwgcG9zLCBtb3JlKSA9PT0gZmFsc2UpIHx8IChjaGMgJiYgY2hjW2Noa10gPT09IGZhbHNlKSkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvciA9IHsgJ2Vycm9yJyA6ICdjaGVjaycsICdwbHVnaW4nIDogJ2NvcmUnLCAnaWQnIDogJ2NvcmVfMDMnLCAncmVhc29uJyA6ICdVc2VyIGNvbmZpZyBmb3IgY29yZS5jaGVja19jYWxsYmFjayBwcmV2ZW50cyBmdW5jdGlvbjogJyArIGNoaywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoeyAnY2hrJyA6IGNoaywgJ3BvcycgOiBwb3MsICdvYmonIDogb2JqICYmIG9iai5pZCA/IG9iai5pZCA6IGZhbHNlLCAncGFyJyA6IHBhciAmJiBwYXIuaWQgPyBwYXIuaWQgOiBmYWxzZSB9KSB9O1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCB0aGUgbGFzdCBlcnJvclxuXHRcdCAqIEBuYW1lIGxhc3RfZXJyb3IoKVxuXHRcdCAqIEByZXR1cm4ge09iamVjdH1cblx0XHQgKi9cblx0XHRsYXN0X2Vycm9yIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogbW92ZSBhIG5vZGUgdG8gYSBuZXcgcGFyZW50XG5cdFx0ICogQG5hbWUgbW92ZV9ub2RlKG9iaiwgcGFyIFssIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBtb3ZlLCBwYXNzIGFuIGFycmF5IHRvIG1vdmUgbXVsdGlwbGUgbm9kZXNcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gcGFyIHRoZSBuZXcgcGFyZW50XG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IHBvcyB0aGUgcG9zaXRpb24gdG8gaW5zZXJ0IGF0IChiZXNpZGVzIGludGVnZXIgdmFsdWVzLCBcImZpcnN0XCIgYW5kIFwibGFzdFwiIGFyZSBzdXBwb3J0ZWQsIGFzIHdlbGwgYXMgXCJiZWZvcmVcIiBhbmQgXCJhZnRlclwiKSwgZGVmYXVsdHMgdG8gaW50ZWdlciBgMGBcblx0XHQgKiBAcGFyYW0gIHtmdW5jdGlvbn0gY2FsbGJhY2sgYSBmdW5jdGlvbiB0byBjYWxsIG9uY2UgdGhlIG1vdmUgaXMgY29tcGxldGVkLCByZWNlaXZlcyAzIGFyZ3VtZW50cyAtIHRoZSBub2RlLCB0aGUgbmV3IHBhcmVudCBhbmQgdGhlIHBvc2l0aW9uXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gaXNfbG9hZGVkIGludGVybmFsIHBhcmFtZXRlciBpbmRpY2F0aW5nIGlmIHRoZSBwYXJlbnQgbm9kZSBoYXMgYmVlbiBsb2FkZWRcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBza2lwX3JlZHJhdyBpbnRlcm5hbCBwYXJhbWV0ZXIgaW5kaWNhdGluZyBpZiB0aGUgdHJlZSBzaG91bGQgYmUgcmVkcmF3blxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IGluc3RhbmNlIGludGVybmFsIHBhcmFtZXRlciBpbmRpY2F0aW5nIGlmIHRoZSBub2RlIGNvbWVzIGZyb20gYW5vdGhlciBpbnN0YW5jZVxuXHRcdCAqIEB0cmlnZ2VyIG1vdmVfbm9kZS5qc3RyZWVcblx0XHQgKi9cblx0XHRtb3ZlX25vZGUgOiBmdW5jdGlvbiAob2JqLCBwYXIsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCwgc2tpcF9yZWRyYXcsIG9yaWdpbikge1xuXHRcdFx0dmFyIHQxLCB0Miwgb2xkX3Bhciwgb2xkX3BvcywgbmV3X3Bhciwgb2xkX2lucywgaXNfbXVsdGksIGRwYywgdG1wLCBpLCBqLCBrLCBsLCBwO1xuXG5cdFx0XHRwYXIgPSB0aGlzLmdldF9ub2RlKHBhcik7XG5cdFx0XHRwb3MgPSBwb3MgPT09IHVuZGVmaW5lZCA/IDAgOiBwb3M7XG5cdFx0XHRpZighcGFyKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0aWYoIXBvcy50b1N0cmluZygpLm1hdGNoKC9eKGJlZm9yZXxhZnRlcikkLykgJiYgIWlzX2xvYWRlZCAmJiAhdGhpcy5pc19sb2FkZWQocGFyKSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5sb2FkX25vZGUocGFyLCBmdW5jdGlvbiAoKSB7IHRoaXMubW92ZV9ub2RlKG9iaiwgcGFyLCBwb3MsIGNhbGxiYWNrLCB0cnVlLCBmYWxzZSwgb3JpZ2luKTsgfSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmKCQudmFrYXRhLmlzX2FycmF5KG9iaikpIHtcblx0XHRcdFx0aWYob2JqLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdG9iaiA9IG9ialswXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHQvL29iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdFx0aWYoKHRtcCA9IHRoaXMubW92ZV9ub2RlKG9ialt0MV0sIHBhciwgcG9zLCBjYWxsYmFjaywgaXNfbG9hZGVkLCBmYWxzZSwgb3JpZ2luKSkpIHtcblx0XHRcdFx0XHRcdFx0cGFyID0gdG1wO1xuXHRcdFx0XHRcdFx0XHRwb3MgPSBcImFmdGVyXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG9iaiA9IG9iaiAmJiBvYmouaWQgPyBvYmogOiB0aGlzLmdldF9ub2RlKG9iaik7XG5cblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdFx0XHRvbGRfcGFyID0gKG9iai5wYXJlbnQgfHwgJC5qc3RyZWUucm9vdCkudG9TdHJpbmcoKTtcblx0XHRcdG5ld19wYXIgPSAoIXBvcy50b1N0cmluZygpLm1hdGNoKC9eKGJlZm9yZXxhZnRlcikkLykgfHwgcGFyLmlkID09PSAkLmpzdHJlZS5yb290KSA/IHBhciA6IHRoaXMuZ2V0X25vZGUocGFyLnBhcmVudCk7XG5cdFx0XHRvbGRfaW5zID0gb3JpZ2luID8gb3JpZ2luIDogKHRoaXMuX21vZGVsLmRhdGFbb2JqLmlkXSA/IHRoaXMgOiAkLmpzdHJlZS5yZWZlcmVuY2Uob2JqLmlkKSk7XG5cdFx0XHRpc19tdWx0aSA9ICFvbGRfaW5zIHx8ICFvbGRfaW5zLl9pZCB8fCAodGhpcy5faWQgIT09IG9sZF9pbnMuX2lkKTtcblx0XHRcdG9sZF9wb3MgPSBvbGRfaW5zICYmIG9sZF9pbnMuX2lkICYmIG9sZF9wYXIgJiYgb2xkX2lucy5fbW9kZWwuZGF0YVtvbGRfcGFyXSAmJiBvbGRfaW5zLl9tb2RlbC5kYXRhW29sZF9wYXJdLmNoaWxkcmVuID8gJC5pbkFycmF5KG9iai5pZCwgb2xkX2lucy5fbW9kZWwuZGF0YVtvbGRfcGFyXS5jaGlsZHJlbikgOiAtMTtcblx0XHRcdGlmKG9sZF9pbnMgJiYgb2xkX2lucy5faWQpIHtcblx0XHRcdFx0b2JqID0gb2xkX2lucy5fbW9kZWwuZGF0YVtvYmouaWRdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZihpc19tdWx0aSkge1xuXHRcdFx0XHRpZigodG1wID0gdGhpcy5jb3B5X25vZGUob2JqLCBwYXIsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCwgZmFsc2UsIG9yaWdpbikpKSB7XG5cdFx0XHRcdFx0aWYob2xkX2lucykgeyBvbGRfaW5zLmRlbGV0ZV9ub2RlKG9iaik7IH1cblx0XHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdC8vdmFyIG0gPSB0aGlzLl9tb2RlbC5kYXRhO1xuXHRcdFx0aWYocGFyLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdGlmKHBvcyA9PT0gXCJiZWZvcmVcIikgeyBwb3MgPSBcImZpcnN0XCI7IH1cblx0XHRcdFx0aWYocG9zID09PSBcImFmdGVyXCIpIHsgcG9zID0gXCJsYXN0XCI7IH1cblx0XHRcdH1cblx0XHRcdHN3aXRjaChwb3MpIHtcblx0XHRcdFx0Y2FzZSBcImJlZm9yZVwiOlxuXHRcdFx0XHRcdHBvcyA9ICQuaW5BcnJheShwYXIuaWQsIG5ld19wYXIuY2hpbGRyZW4pO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwiYWZ0ZXJcIiA6XG5cdFx0XHRcdFx0cG9zID0gJC5pbkFycmF5KHBhci5pZCwgbmV3X3Bhci5jaGlsZHJlbikgKyAxO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwiaW5zaWRlXCI6XG5cdFx0XHRcdGNhc2UgXCJmaXJzdFwiOlxuXHRcdFx0XHRcdHBvcyA9IDA7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJsYXN0XCI6XG5cdFx0XHRcdFx0cG9zID0gbmV3X3Bhci5jaGlsZHJlbi5sZW5ndGg7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0aWYoIXBvcykgeyBwb3MgPSAwOyB9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZihwb3MgPiBuZXdfcGFyLmNoaWxkcmVuLmxlbmd0aCkgeyBwb3MgPSBuZXdfcGFyLmNoaWxkcmVuLmxlbmd0aDsgfVxuXHRcdFx0aWYoIXRoaXMuY2hlY2soXCJtb3ZlX25vZGVcIiwgb2JqLCBuZXdfcGFyLCBwb3MsIHsgJ2NvcmUnIDogdHJ1ZSwgJ29yaWdpbicgOiBvcmlnaW4sICdpc19tdWx0aScgOiAob2xkX2lucyAmJiBvbGRfaW5zLl9pZCAmJiBvbGRfaW5zLl9pZCAhPT0gdGhpcy5faWQpLCAnaXNfZm9yZWlnbicgOiAoIW9sZF9pbnMgfHwgIW9sZF9pbnMuX2lkKSB9KSkge1xuXHRcdFx0XHR0aGlzLnNldHRpbmdzLmNvcmUuZXJyb3IuY2FsbCh0aGlzLCB0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvcik7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKG9iai5wYXJlbnQgPT09IG5ld19wYXIuaWQpIHtcblx0XHRcdFx0ZHBjID0gbmV3X3Bhci5jaGlsZHJlbi5jb25jYXQoKTtcblx0XHRcdFx0dG1wID0gJC5pbkFycmF5KG9iai5pZCwgZHBjKTtcblx0XHRcdFx0aWYodG1wICE9PSAtMSkge1xuXHRcdFx0XHRcdGRwYyA9ICQudmFrYXRhLmFycmF5X3JlbW92ZShkcGMsIHRtcCk7XG5cdFx0XHRcdFx0aWYocG9zID4gdG1wKSB7IHBvcy0tOyB9XG5cdFx0XHRcdH1cblx0XHRcdFx0dG1wID0gW107XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IGRwYy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHR0bXBbaSA+PSBwb3MgPyBpKzEgOiBpXSA9IGRwY1tpXTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0bXBbcG9zXSA9IG9iai5pZDtcblx0XHRcdFx0bmV3X3Bhci5jaGlsZHJlbiA9IHRtcDtcblx0XHRcdFx0dGhpcy5fbm9kZV9jaGFuZ2VkKG5ld19wYXIuaWQpO1xuXHRcdFx0XHR0aGlzLnJlZHJhdyhuZXdfcGFyLmlkID09PSAkLmpzdHJlZS5yb290KTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHQvLyBjbGVhbiBvbGQgcGFyZW50IGFuZCB1cFxuXHRcdFx0XHR0bXAgPSBvYmouY2hpbGRyZW5fZC5jb25jYXQoKTtcblx0XHRcdFx0dG1wLnB1c2gob2JqLmlkKTtcblx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0ZHBjID0gW107XG5cdFx0XHRcdFx0cCA9IG9sZF9pbnMuX21vZGVsLmRhdGFbb2JqLnBhcmVudHNbaV1dLmNoaWxkcmVuX2Q7XG5cdFx0XHRcdFx0Zm9yKGsgPSAwLCBsID0gcC5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRcdGlmKCQuaW5BcnJheShwW2tdLCB0bXApID09PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRkcGMucHVzaChwW2tdKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0b2xkX2lucy5fbW9kZWwuZGF0YVtvYmoucGFyZW50c1tpXV0uY2hpbGRyZW5fZCA9IGRwYztcblx0XHRcdFx0fVxuXHRcdFx0XHRvbGRfaW5zLl9tb2RlbC5kYXRhW29sZF9wYXJdLmNoaWxkcmVuID0gJC52YWthdGEuYXJyYXlfcmVtb3ZlX2l0ZW0ob2xkX2lucy5fbW9kZWwuZGF0YVtvbGRfcGFyXS5jaGlsZHJlbiwgb2JqLmlkKTtcblxuXHRcdFx0XHQvLyBpbnNlcnQgaW50byBuZXcgcGFyZW50IGFuZCB1cFxuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBuZXdfcGFyLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5fbW9kZWwuZGF0YVtuZXdfcGFyLnBhcmVudHNbaV1dLmNoaWxkcmVuX2QgPSB0aGlzLl9tb2RlbC5kYXRhW25ld19wYXIucGFyZW50c1tpXV0uY2hpbGRyZW5fZC5jb25jYXQodG1wKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkcGMgPSBbXTtcblx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gbmV3X3Bhci5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRkcGNbaSA+PSBwb3MgPyBpKzEgOiBpXSA9IG5ld19wYXIuY2hpbGRyZW5baV07XG5cdFx0XHRcdH1cblx0XHRcdFx0ZHBjW3Bvc10gPSBvYmouaWQ7XG5cdFx0XHRcdG5ld19wYXIuY2hpbGRyZW4gPSBkcGM7XG5cdFx0XHRcdG5ld19wYXIuY2hpbGRyZW5fZC5wdXNoKG9iai5pZCk7XG5cdFx0XHRcdG5ld19wYXIuY2hpbGRyZW5fZCA9IG5ld19wYXIuY2hpbGRyZW5fZC5jb25jYXQob2JqLmNoaWxkcmVuX2QpO1xuXG5cdFx0XHRcdC8vIHVwZGF0ZSBvYmplY3Rcblx0XHRcdFx0b2JqLnBhcmVudCA9IG5ld19wYXIuaWQ7XG5cdFx0XHRcdHRtcCA9IG5ld19wYXIucGFyZW50cy5jb25jYXQoKTtcblx0XHRcdFx0dG1wLnVuc2hpZnQobmV3X3Bhci5pZCk7XG5cdFx0XHRcdHAgPSBvYmoucGFyZW50cy5sZW5ndGg7XG5cdFx0XHRcdG9iai5wYXJlbnRzID0gdG1wO1xuXG5cdFx0XHRcdC8vIHVwZGF0ZSBvYmplY3QgY2hpbGRyZW5cblx0XHRcdFx0dG1wID0gdG1wLmNvbmNhdCgpO1xuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGRyZW5fZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHR0aGlzLl9tb2RlbC5kYXRhW29iai5jaGlsZHJlbl9kW2ldXS5wYXJlbnRzID0gdGhpcy5fbW9kZWwuZGF0YVtvYmouY2hpbGRyZW5fZFtpXV0ucGFyZW50cy5zbGljZSgwLHAqLTEpO1xuXHRcdFx0XHRcdEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMuX21vZGVsLmRhdGFbb2JqLmNoaWxkcmVuX2RbaV1dLnBhcmVudHMsIHRtcCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZihvbGRfcGFyID09PSAkLmpzdHJlZS5yb290IHx8IG5ld19wYXIuaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHR0aGlzLl9tb2RlbC5mb3JjZV9mdWxsX3JlZHJhdyA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIXRoaXMuX21vZGVsLmZvcmNlX2Z1bGxfcmVkcmF3KSB7XG5cdFx0XHRcdFx0dGhpcy5fbm9kZV9jaGFuZ2VkKG9sZF9wYXIpO1xuXHRcdFx0XHRcdHRoaXMuX25vZGVfY2hhbmdlZChuZXdfcGFyLmlkKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZighc2tpcF9yZWRyYXcpIHtcblx0XHRcdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZihjYWxsYmFjaykgeyBjYWxsYmFjay5jYWxsKHRoaXMsIG9iaiwgbmV3X3BhciwgcG9zKTsgfVxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhIG5vZGUgaXMgbW92ZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgbW92ZV9ub2RlLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXJlbnQgdGhlIHBhcmVudCdzIElEXG5cdFx0XHQgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBub2RlIGFtb25nIHRoZSBwYXJlbnQncyBjaGlsZHJlblxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IG9sZF9wYXJlbnQgdGhlIG9sZCBwYXJlbnQgb2YgdGhlIG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBvbGRfcG9zaXRpb24gdGhlIG9sZCBwb3NpdGlvbiBvZiB0aGUgbm9kZVxuXHRcdFx0ICogQHBhcmFtIHtCb29sZWFufSBpc19tdWx0aSBkbyB0aGUgbm9kZSBhbmQgbmV3IHBhcmVudCBiZWxvbmcgdG8gZGlmZmVyZW50IGluc3RhbmNlc1xuXHRcdFx0ICogQHBhcmFtIHtqc1RyZWV9IG9sZF9pbnN0YW5jZSB0aGUgaW5zdGFuY2UgdGhlIG5vZGUgY2FtZSBmcm9tXG5cdFx0XHQgKiBAcGFyYW0ge2pzVHJlZX0gbmV3X2luc3RhbmNlIHRoZSBpbnN0YW5jZSBvZiB0aGUgbmV3IHBhcmVudFxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ21vdmVfbm9kZScsIHsgXCJub2RlXCIgOiBvYmosIFwicGFyZW50XCIgOiBuZXdfcGFyLmlkLCBcInBvc2l0aW9uXCIgOiBwb3MsIFwib2xkX3BhcmVudFwiIDogb2xkX3BhciwgXCJvbGRfcG9zaXRpb25cIiA6IG9sZF9wb3MsICdpc19tdWx0aScgOiAob2xkX2lucyAmJiBvbGRfaW5zLl9pZCAmJiBvbGRfaW5zLl9pZCAhPT0gdGhpcy5faWQpLCAnaXNfZm9yZWlnbicgOiAoIW9sZF9pbnMgfHwgIW9sZF9pbnMuX2lkKSwgJ29sZF9pbnN0YW5jZScgOiBvbGRfaW5zLCAnbmV3X2luc3RhbmNlJyA6IHRoaXMgfSk7XG5cdFx0XHRyZXR1cm4gb2JqLmlkO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY29weSBhIG5vZGUgdG8gYSBuZXcgcGFyZW50XG5cdFx0ICogQG5hbWUgY29weV9ub2RlKG9iaiwgcGFyIFssIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBjb3B5LCBwYXNzIGFuIGFycmF5IHRvIGNvcHkgbXVsdGlwbGUgbm9kZXNcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gcGFyIHRoZSBuZXcgcGFyZW50XG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IHBvcyB0aGUgcG9zaXRpb24gdG8gaW5zZXJ0IGF0IChiZXNpZGVzIGludGVnZXIgdmFsdWVzLCBcImZpcnN0XCIgYW5kIFwibGFzdFwiIGFyZSBzdXBwb3J0ZWQsIGFzIHdlbGwgYXMgXCJiZWZvcmVcIiBhbmQgXCJhZnRlclwiKSwgZGVmYXVsdHMgdG8gaW50ZWdlciBgMGBcblx0XHQgKiBAcGFyYW0gIHtmdW5jdGlvbn0gY2FsbGJhY2sgYSBmdW5jdGlvbiB0byBjYWxsIG9uY2UgdGhlIG1vdmUgaXMgY29tcGxldGVkLCByZWNlaXZlcyAzIGFyZ3VtZW50cyAtIHRoZSBub2RlLCB0aGUgbmV3IHBhcmVudCBhbmQgdGhlIHBvc2l0aW9uXG5cdFx0ICogQHBhcmFtICB7Qm9vbGVhbn0gaXNfbG9hZGVkIGludGVybmFsIHBhcmFtZXRlciBpbmRpY2F0aW5nIGlmIHRoZSBwYXJlbnQgbm9kZSBoYXMgYmVlbiBsb2FkZWRcblx0XHQgKiBAcGFyYW0gIHtCb29sZWFufSBza2lwX3JlZHJhdyBpbnRlcm5hbCBwYXJhbWV0ZXIgaW5kaWNhdGluZyBpZiB0aGUgdHJlZSBzaG91bGQgYmUgcmVkcmF3blxuXHRcdCAqIEBwYXJhbSAge0Jvb2xlYW59IGluc3RhbmNlIGludGVybmFsIHBhcmFtZXRlciBpbmRpY2F0aW5nIGlmIHRoZSBub2RlIGNvbWVzIGZyb20gYW5vdGhlciBpbnN0YW5jZVxuXHRcdCAqIEB0cmlnZ2VyIG1vZGVsLmpzdHJlZSBjb3B5X25vZGUuanN0cmVlXG5cdFx0ICovXG5cdFx0Y29weV9ub2RlIDogZnVuY3Rpb24gKG9iaiwgcGFyLCBwb3MsIGNhbGxiYWNrLCBpc19sb2FkZWQsIHNraXBfcmVkcmF3LCBvcmlnaW4pIHtcblx0XHRcdHZhciB0MSwgdDIsIGRwYywgdG1wLCBpLCBqLCBub2RlLCBvbGRfcGFyLCBuZXdfcGFyLCBvbGRfaW5zLCBpc19tdWx0aTtcblxuXHRcdFx0cGFyID0gdGhpcy5nZXRfbm9kZShwYXIpO1xuXHRcdFx0cG9zID0gcG9zID09PSB1bmRlZmluZWQgPyAwIDogcG9zO1xuXHRcdFx0aWYoIXBhcikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdGlmKCFwb3MudG9TdHJpbmcoKS5tYXRjaCgvXihiZWZvcmV8YWZ0ZXIpJC8pICYmICFpc19sb2FkZWQgJiYgIXRoaXMuaXNfbG9hZGVkKHBhcikpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMubG9hZF9ub2RlKHBhciwgZnVuY3Rpb24gKCkgeyB0aGlzLmNvcHlfbm9kZShvYmosIHBhciwgcG9zLCBjYWxsYmFjaywgdHJ1ZSwgZmFsc2UsIG9yaWdpbik7IH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdGlmKG9iai5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0XHRvYmogPSBvYmpbMF07XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0Ly9vYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHRcdGlmKCh0bXAgPSB0aGlzLmNvcHlfbm9kZShvYmpbdDFdLCBwYXIsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCwgdHJ1ZSwgb3JpZ2luKSkpIHtcblx0XHRcdFx0XHRcdFx0cGFyID0gdG1wO1xuXHRcdFx0XHRcdFx0XHRwb3MgPSBcImFmdGVyXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG9iaiA9IG9iaiAmJiBvYmouaWQgPyBvYmogOiB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRcdFx0b2xkX3BhciA9IChvYmoucGFyZW50IHx8ICQuanN0cmVlLnJvb3QpLnRvU3RyaW5nKCk7XG5cdFx0XHRuZXdfcGFyID0gKCFwb3MudG9TdHJpbmcoKS5tYXRjaCgvXihiZWZvcmV8YWZ0ZXIpJC8pIHx8IHBhci5pZCA9PT0gJC5qc3RyZWUucm9vdCkgPyBwYXIgOiB0aGlzLmdldF9ub2RlKHBhci5wYXJlbnQpO1xuXHRcdFx0b2xkX2lucyA9IG9yaWdpbiA/IG9yaWdpbiA6ICh0aGlzLl9tb2RlbC5kYXRhW29iai5pZF0gPyB0aGlzIDogJC5qc3RyZWUucmVmZXJlbmNlKG9iai5pZCkpO1xuXHRcdFx0aXNfbXVsdGkgPSAhb2xkX2lucyB8fCAhb2xkX2lucy5faWQgfHwgKHRoaXMuX2lkICE9PSBvbGRfaW5zLl9pZCk7XG5cblx0XHRcdGlmKG9sZF9pbnMgJiYgb2xkX2lucy5faWQpIHtcblx0XHRcdFx0b2JqID0gb2xkX2lucy5fbW9kZWwuZGF0YVtvYmouaWRdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZihwYXIuaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0aWYocG9zID09PSBcImJlZm9yZVwiKSB7IHBvcyA9IFwiZmlyc3RcIjsgfVxuXHRcdFx0XHRpZihwb3MgPT09IFwiYWZ0ZXJcIikgeyBwb3MgPSBcImxhc3RcIjsgfVxuXHRcdFx0fVxuXHRcdFx0c3dpdGNoKHBvcykge1xuXHRcdFx0XHRjYXNlIFwiYmVmb3JlXCI6XG5cdFx0XHRcdFx0cG9zID0gJC5pbkFycmF5KHBhci5pZCwgbmV3X3Bhci5jaGlsZHJlbik7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJhZnRlclwiIDpcblx0XHRcdFx0XHRwb3MgPSAkLmluQXJyYXkocGFyLmlkLCBuZXdfcGFyLmNoaWxkcmVuKSArIDE7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJpbnNpZGVcIjpcblx0XHRcdFx0Y2FzZSBcImZpcnN0XCI6XG5cdFx0XHRcdFx0cG9zID0gMDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBcImxhc3RcIjpcblx0XHRcdFx0XHRwb3MgPSBuZXdfcGFyLmNoaWxkcmVuLmxlbmd0aDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRpZighcG9zKSB7IHBvcyA9IDA7IH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmKHBvcyA+IG5ld19wYXIuY2hpbGRyZW4ubGVuZ3RoKSB7IHBvcyA9IG5ld19wYXIuY2hpbGRyZW4ubGVuZ3RoOyB9XG5cdFx0XHRpZighdGhpcy5jaGVjayhcImNvcHlfbm9kZVwiLCBvYmosIG5ld19wYXIsIHBvcywgeyAnY29yZScgOiB0cnVlLCAnb3JpZ2luJyA6IG9yaWdpbiwgJ2lzX211bHRpJyA6IChvbGRfaW5zICYmIG9sZF9pbnMuX2lkICYmIG9sZF9pbnMuX2lkICE9PSB0aGlzLl9pZCksICdpc19mb3JlaWduJyA6ICghb2xkX2lucyB8fCAhb2xkX2lucy5faWQpIH0pKSB7XG5cdFx0XHRcdHRoaXMuc2V0dGluZ3MuY29yZS5lcnJvci5jYWxsKHRoaXMsIHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0bm9kZSA9IG9sZF9pbnMgPyBvbGRfaW5zLmdldF9qc29uKG9iaiwgeyBub19pZCA6IHRydWUsIG5vX2RhdGEgOiB0cnVlLCBub19zdGF0ZSA6IHRydWUgfSkgOiBvYmo7XG5cdFx0XHRpZighbm9kZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdGlmKG5vZGUuaWQgPT09IHRydWUpIHsgZGVsZXRlIG5vZGUuaWQ7IH1cblx0XHRcdG5vZGUgPSB0aGlzLl9wYXJzZV9tb2RlbF9mcm9tX2pzb24obm9kZSwgbmV3X3Bhci5pZCwgbmV3X3Bhci5wYXJlbnRzLmNvbmNhdCgpKTtcblx0XHRcdGlmKCFub2RlKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0dG1wID0gdGhpcy5nZXRfbm9kZShub2RlKTtcblx0XHRcdGlmKG9iaiAmJiBvYmouc3RhdGUgJiYgb2JqLnN0YXRlLmxvYWRlZCA9PT0gZmFsc2UpIHsgdG1wLnN0YXRlLmxvYWRlZCA9IGZhbHNlOyB9XG5cdFx0XHRkcGMgPSBbXTtcblx0XHRcdGRwYy5wdXNoKG5vZGUpO1xuXHRcdFx0ZHBjID0gZHBjLmNvbmNhdCh0bXAuY2hpbGRyZW5fZCk7XG5cdFx0XHR0aGlzLnRyaWdnZXIoJ21vZGVsJywgeyBcIm5vZGVzXCIgOiBkcGMsIFwicGFyZW50XCIgOiBuZXdfcGFyLmlkIH0pO1xuXG5cdFx0XHQvLyBpbnNlcnQgaW50byBuZXcgcGFyZW50IGFuZCB1cFxuXHRcdFx0Zm9yKGkgPSAwLCBqID0gbmV3X3Bhci5wYXJlbnRzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHR0aGlzLl9tb2RlbC5kYXRhW25ld19wYXIucGFyZW50c1tpXV0uY2hpbGRyZW5fZCA9IHRoaXMuX21vZGVsLmRhdGFbbmV3X3Bhci5wYXJlbnRzW2ldXS5jaGlsZHJlbl9kLmNvbmNhdChkcGMpO1xuXHRcdFx0fVxuXHRcdFx0ZHBjID0gW107XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBuZXdfcGFyLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRkcGNbaSA+PSBwb3MgPyBpKzEgOiBpXSA9IG5ld19wYXIuY2hpbGRyZW5baV07XG5cdFx0XHR9XG5cdFx0XHRkcGNbcG9zXSA9IHRtcC5pZDtcblx0XHRcdG5ld19wYXIuY2hpbGRyZW4gPSBkcGM7XG5cdFx0XHRuZXdfcGFyLmNoaWxkcmVuX2QucHVzaCh0bXAuaWQpO1xuXHRcdFx0bmV3X3Bhci5jaGlsZHJlbl9kID0gbmV3X3Bhci5jaGlsZHJlbl9kLmNvbmNhdCh0bXAuY2hpbGRyZW5fZCk7XG5cblx0XHRcdGlmKG5ld19wYXIuaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0dGhpcy5fbW9kZWwuZm9yY2VfZnVsbF9yZWRyYXcgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0aWYoIXRoaXMuX21vZGVsLmZvcmNlX2Z1bGxfcmVkcmF3KSB7XG5cdFx0XHRcdHRoaXMuX25vZGVfY2hhbmdlZChuZXdfcGFyLmlkKTtcblx0XHRcdH1cblx0XHRcdGlmKCFza2lwX3JlZHJhdykge1xuXHRcdFx0XHR0aGlzLnJlZHJhdyhuZXdfcGFyLmlkID09PSAkLmpzdHJlZS5yb290KTtcblx0XHRcdH1cblx0XHRcdGlmKGNhbGxiYWNrKSB7IGNhbGxiYWNrLmNhbGwodGhpcywgdG1wLCBuZXdfcGFyLCBwb3MpOyB9XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGEgbm9kZSBpcyBjb3BpZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgY29weV9ub2RlLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGUgdGhlIGNvcGllZCBub2RlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gb3JpZ2luYWwgdGhlIG9yaWdpbmFsIG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXJlbnQgdGhlIHBhcmVudCdzIElEXG5cdFx0XHQgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBub2RlIGFtb25nIHRoZSBwYXJlbnQncyBjaGlsZHJlblxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IG9sZF9wYXJlbnQgdGhlIG9sZCBwYXJlbnQgb2YgdGhlIG5vZGVcblx0XHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBvbGRfcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBvcmlnaW5hbCBub2RlXG5cdFx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IGlzX211bHRpIGRvIHRoZSBub2RlIGFuZCBuZXcgcGFyZW50IGJlbG9uZyB0byBkaWZmZXJlbnQgaW5zdGFuY2VzXG5cdFx0XHQgKiBAcGFyYW0ge2pzVHJlZX0gb2xkX2luc3RhbmNlIHRoZSBpbnN0YW5jZSB0aGUgbm9kZSBjYW1lIGZyb21cblx0XHRcdCAqIEBwYXJhbSB7anNUcmVlfSBuZXdfaW5zdGFuY2UgdGhlIGluc3RhbmNlIG9mIHRoZSBuZXcgcGFyZW50XG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignY29weV9ub2RlJywgeyBcIm5vZGVcIiA6IHRtcCwgXCJvcmlnaW5hbFwiIDogb2JqLCBcInBhcmVudFwiIDogbmV3X3Bhci5pZCwgXCJwb3NpdGlvblwiIDogcG9zLCBcIm9sZF9wYXJlbnRcIiA6IG9sZF9wYXIsIFwib2xkX3Bvc2l0aW9uXCIgOiBvbGRfaW5zICYmIG9sZF9pbnMuX2lkICYmIG9sZF9wYXIgJiYgb2xkX2lucy5fbW9kZWwuZGF0YVtvbGRfcGFyXSAmJiBvbGRfaW5zLl9tb2RlbC5kYXRhW29sZF9wYXJdLmNoaWxkcmVuID8gJC5pbkFycmF5KG9iai5pZCwgb2xkX2lucy5fbW9kZWwuZGF0YVtvbGRfcGFyXS5jaGlsZHJlbikgOiAtMSwnaXNfbXVsdGknIDogKG9sZF9pbnMgJiYgb2xkX2lucy5faWQgJiYgb2xkX2lucy5faWQgIT09IHRoaXMuX2lkKSwgJ2lzX2ZvcmVpZ24nIDogKCFvbGRfaW5zIHx8ICFvbGRfaW5zLl9pZCksICdvbGRfaW5zdGFuY2UnIDogb2xkX2lucywgJ25ld19pbnN0YW5jZScgOiB0aGlzIH0pO1xuXHRcdFx0cmV0dXJuIHRtcC5pZDtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGN1dCBhIG5vZGUgKGEgbGF0ZXIgY2FsbCB0byBgcGFzdGUob2JqKWAgd291bGQgbW92ZSB0aGUgbm9kZSlcblx0XHQgKiBAbmFtZSBjdXQob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmogbXVsdGlwbGUgb2JqZWN0cyBjYW4gYmUgcGFzc2VkIHVzaW5nIGFuIGFycmF5XG5cdFx0ICogQHRyaWdnZXIgY3V0LmpzdHJlZVxuXHRcdCAqL1xuXHRcdGN1dCA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdGlmKCFvYmopIHsgb2JqID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdCgpOyB9XG5cdFx0XHRpZighJC52YWthdGEuaXNfYXJyYXkob2JqKSkgeyBvYmogPSBbb2JqXTsgfVxuXHRcdFx0aWYoIW9iai5sZW5ndGgpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHR2YXIgdG1wID0gW10sIG8sIHQxLCB0Mjtcblx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRvID0gdGhpcy5nZXRfbm9kZShvYmpbdDFdKTtcblx0XHRcdFx0aWYobyAmJiBvLmlkICYmIG8uaWQgIT09ICQuanN0cmVlLnJvb3QpIHsgdG1wLnB1c2gobyk7IH1cblx0XHRcdH1cblx0XHRcdGlmKCF0bXAubGVuZ3RoKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0Y2NwX25vZGUgPSB0bXA7XG5cdFx0XHRjY3BfaW5zdCA9IHRoaXM7XG5cdFx0XHRjY3BfbW9kZSA9ICdtb3ZlX25vZGUnO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBub2RlcyBhcmUgYWRkZWQgdG8gdGhlIGJ1ZmZlciBmb3IgbW92aW5nXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGN1dC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdjdXQnLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY29weSBhIG5vZGUgKGEgbGF0ZXIgY2FsbCB0byBgcGFzdGUob2JqKWAgd291bGQgY29weSB0aGUgbm9kZSlcblx0XHQgKiBAbmFtZSBjb3B5KG9iailcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqIG11bHRpcGxlIG9iamVjdHMgY2FuIGJlIHBhc3NlZCB1c2luZyBhbiBhcnJheVxuXHRcdCAqIEB0cmlnZ2VyIGNvcHkuanN0cmVlXG5cdFx0ICovXG5cdFx0Y29weSA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdGlmKCFvYmopIHsgb2JqID0gdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkLmNvbmNhdCgpOyB9XG5cdFx0XHRpZighJC52YWthdGEuaXNfYXJyYXkob2JqKSkgeyBvYmogPSBbb2JqXTsgfVxuXHRcdFx0aWYoIW9iai5sZW5ndGgpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHR2YXIgdG1wID0gW10sIG8sIHQxLCB0Mjtcblx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRvID0gdGhpcy5nZXRfbm9kZShvYmpbdDFdKTtcblx0XHRcdFx0aWYobyAmJiBvLmlkICYmIG8uaWQgIT09ICQuanN0cmVlLnJvb3QpIHsgdG1wLnB1c2gobyk7IH1cblx0XHRcdH1cblx0XHRcdGlmKCF0bXAubGVuZ3RoKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0Y2NwX25vZGUgPSB0bXA7XG5cdFx0XHRjY3BfaW5zdCA9IHRoaXM7XG5cdFx0XHRjY3BfbW9kZSA9ICdjb3B5X25vZGUnO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBub2RlcyBhcmUgYWRkZWQgdG8gdGhlIGJ1ZmZlciBmb3IgY29weWluZ1xuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBjb3B5LmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2NvcHknLCB7IFwibm9kZVwiIDogb2JqIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0IHRoZSBjdXJyZW50IGJ1ZmZlciAoYW55IG5vZGVzIHRoYXQgYXJlIHdhaXRpbmcgZm9yIGEgcGFzdGUgb3BlcmF0aW9uKVxuXHRcdCAqIEBuYW1lIGdldF9idWZmZXIoKVxuXHRcdCAqIEByZXR1cm4ge09iamVjdH0gYW4gb2JqZWN0IGNvbnNpc3Rpbmcgb2YgYG1vZGVgIChcImNvcHlfbm9kZVwiIG9yIFwibW92ZV9ub2RlXCIpLCBgbm9kZWAgKGFuIGFycmF5IG9mIG9iamVjdHMpIGFuZCBgaW5zdGAgKHRoZSBpbnN0YW5jZSlcblx0XHQgKi9cblx0XHRnZXRfYnVmZmVyIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHsgJ21vZGUnIDogY2NwX21vZGUsICdub2RlJyA6IGNjcF9ub2RlLCAnaW5zdCcgOiBjY3BfaW5zdCB9O1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogY2hlY2sgaWYgdGhlcmUgaXMgc29tZXRoaW5nIGluIHRoZSBidWZmZXIgdG8gcGFzdGVcblx0XHQgKiBAbmFtZSBjYW5fcGFzdGUoKVxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0Y2FuX3Bhc3RlIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIGNjcF9tb2RlICE9PSBmYWxzZSAmJiBjY3Bfbm9kZSAhPT0gZmFsc2U7IC8vICYmIGNjcF9pbnN0Ll9tb2RlbC5kYXRhW2NjcF9ub2RlXTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGNvcHkgb3IgbW92ZSB0aGUgcHJldmlvdXNseSBjdXQgb3IgY29waWVkIG5vZGVzIHRvIGEgbmV3IHBhcmVudFxuXHRcdCAqIEBuYW1lIHBhc3RlKG9iaiBbLCBwb3NdKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSBvYmogdGhlIG5ldyBwYXJlbnRcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gcG9zIHRoZSBwb3NpdGlvbiB0byBpbnNlcnQgYXQgKGJlc2lkZXMgaW50ZWdlciwgXCJmaXJzdFwiIGFuZCBcImxhc3RcIiBhcmUgc3VwcG9ydGVkKSwgZGVmYXVsdHMgdG8gaW50ZWdlciBgMGBcblx0XHQgKiBAdHJpZ2dlciBwYXN0ZS5qc3RyZWVcblx0XHQgKi9cblx0XHRwYXN0ZSA6IGZ1bmN0aW9uIChvYmosIHBvcykge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCAhY2NwX21vZGUgfHwgIWNjcF9tb2RlLm1hdGNoKC9eKGNvcHlfbm9kZXxtb3ZlX25vZGUpJC8pIHx8ICFjY3Bfbm9kZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdGlmKHRoaXNbY2NwX21vZGVdKGNjcF9ub2RlLCBvYmosIHBvcywgZmFsc2UsIGZhbHNlLCBmYWxzZSwgY2NwX2luc3QpKSB7XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBwYXN0ZSBpcyBpbnZva2VkXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBwYXN0ZS5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IHBhcmVudCB0aGUgSUQgb2YgdGhlIHJlY2VpdmluZyBub2RlXG5cdFx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGUgdGhlIG5vZGVzIGluIHRoZSBidWZmZXJcblx0XHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IG1vZGUgdGhlIHBlcmZvcm1lZCBvcGVyYXRpb24gLSBcImNvcHlfbm9kZVwiIG9yIFwibW92ZV9ub2RlXCJcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcigncGFzdGUnLCB7IFwicGFyZW50XCIgOiBvYmouaWQsIFwibm9kZVwiIDogY2NwX25vZGUsIFwibW9kZVwiIDogY2NwX21vZGUgfSk7XG5cdFx0XHR9XG5cdFx0XHRjY3Bfbm9kZSA9IGZhbHNlO1xuXHRcdFx0Y2NwX21vZGUgPSBmYWxzZTtcblx0XHRcdGNjcF9pbnN0ID0gZmFsc2U7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBjbGVhciB0aGUgYnVmZmVyIG9mIHByZXZpb3VzbHkgY29waWVkIG9yIGN1dCBub2Rlc1xuXHRcdCAqIEBuYW1lIGNsZWFyX2J1ZmZlcigpXG5cdFx0ICogQHRyaWdnZXIgY2xlYXJfYnVmZmVyLmpzdHJlZVxuXHRcdCAqL1xuXHRcdGNsZWFyX2J1ZmZlciA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdGNjcF9ub2RlID0gZmFsc2U7XG5cdFx0XHRjY3BfbW9kZSA9IGZhbHNlO1xuXHRcdFx0Y2NwX2luc3QgPSBmYWxzZTtcblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gdGhlIGNvcHkgLyBjdXQgYnVmZmVyIGlzIGNsZWFyZWRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgY2xlYXJfYnVmZmVyLmpzdHJlZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2NsZWFyX2J1ZmZlcicpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogcHV0IGEgbm9kZSBpbiBlZGl0IG1vZGUgKGlucHV0IGZpZWxkIHRvIHJlbmFtZSB0aGUgbm9kZSlcblx0XHQgKiBAbmFtZSBlZGl0KG9iaiBbLCBkZWZhdWx0X3RleHQsIGNhbGxiYWNrXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqXG5cdFx0ICogQHBhcmFtICB7U3RyaW5nfSBkZWZhdWx0X3RleHQgdGhlIHRleHQgdG8gcG9wdWxhdGUgdGhlIGlucHV0IHdpdGggKGlmIG9taXR0ZWQgb3Igc2V0IHRvIGEgbm9uLXN0cmluZyB2YWx1ZSB0aGUgbm9kZSdzIHRleHQgdmFsdWUgaXMgdXNlZClcblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2sgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb25jZSB0aGUgdGV4dCBib3ggaXMgYmx1cnJlZCwgaXQgaXMgY2FsbGVkIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlIGFuZCByZWNlaXZlcyB0aGUgbm9kZSwgYSBzdGF0dXMgcGFyYW1ldGVyICh0cnVlIGlmIHRoZSByZW5hbWUgaXMgc3VjY2Vzc2Z1bCwgZmFsc2Ugb3RoZXJ3aXNlKSwgYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHVzZXIgY2FuY2VsbGVkIHRoZSBlZGl0IGFuZCB0aGUgb3JpZ2luYWwgdW5lc2NhcGVkIHZhbHVlIHByb3ZpZGVkIGJ5IHRoZSB1c2VyLiBZb3UgY2FuIGFsc28gYWNjZXNzIHRoZSBub2RlJ3MgdGl0bGUgdXNpbmcgLnRleHRcblx0XHQgKi9cblx0XHRlZGl0IDogZnVuY3Rpb24gKG9iaiwgZGVmYXVsdF90ZXh0LCBjYWxsYmFjaykge1xuXHRcdFx0dmFyIHJ0bCwgdywgYSwgcywgdCwgaDEsIGgyLCBmbiwgdG1wLCBjYW5jZWwgPSBmYWxzZTtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmopIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRpZighdGhpcy5jaGVjayhcImVkaXRcIiwgb2JqLCB0aGlzLmdldF9wYXJlbnQob2JqKSkpIHtcblx0XHRcdFx0dGhpcy5zZXR0aW5ncy5jb3JlLmVycm9yLmNhbGwodGhpcywgdGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IpO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR0bXAgPSBvYmo7XG5cdFx0XHRkZWZhdWx0X3RleHQgPSB0eXBlb2YgZGVmYXVsdF90ZXh0ID09PSAnc3RyaW5nJyA/IGRlZmF1bHRfdGV4dCA6IG9iai50ZXh0O1xuXHRcdFx0dGhpcy5zZXRfdGV4dChvYmosIFwiXCIpO1xuXHRcdFx0b2JqID0gdGhpcy5fb3Blbl90byhvYmopO1xuXHRcdFx0dG1wLnRleHQgPSBkZWZhdWx0X3RleHQ7XG5cblx0XHRcdHJ0bCA9IHRoaXMuX2RhdGEuY29yZS5ydGw7XG5cdFx0XHR3ICA9IHRoaXMuZWxlbWVudC53aWR0aCgpO1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLmZvY3VzZWQgPSB0bXAuaWQ7XG5cdFx0XHRhICA9IG9iai5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0cyAgPSAkKCc8c3Bhbj48L3NwYW4+Jyk7XG5cdFx0XHQvKiFcblx0XHRcdG9pID0gb2JqLmNoaWxkcmVuKFwiaTp2aXNpYmxlXCIpLFxuXHRcdFx0YWkgPSBhLmNoaWxkcmVuKFwiaTp2aXNpYmxlXCIpLFxuXHRcdFx0dzEgPSBvaS53aWR0aCgpICogb2kubGVuZ3RoLFxuXHRcdFx0dzIgPSBhaS53aWR0aCgpICogYWkubGVuZ3RoLFxuXHRcdFx0Ki9cblx0XHRcdHQgID0gZGVmYXVsdF90ZXh0O1xuXHRcdFx0aDEgPSAkKFwiPFwiK1wiZGl2PjwvZGl2PlwiLCB7IGNzcyA6IHsgXCJwb3NpdGlvblwiIDogXCJhYnNvbHV0ZVwiLCBcInRvcFwiIDogXCItMjAwcHhcIiwgXCJsZWZ0XCIgOiAocnRsID8gXCIwcHhcIiA6IFwiLTEwMDBweFwiKSwgXCJ2aXNpYmlsaXR5XCIgOiBcImhpZGRlblwiIH0gfSkuYXBwZW5kVG8oZG9jdW1lbnQuYm9keSk7XG5cdFx0XHRoMiA9ICQoXCI8XCIrXCJpbnB1dCAvPlwiLCB7XG5cdFx0XHRcdFx0XHRcInZhbHVlXCIgOiB0LFxuXHRcdFx0XHRcdFx0XCJjbGFzc1wiIDogXCJqc3RyZWUtcmVuYW1lLWlucHV0XCIsXG5cdFx0XHRcdFx0XHQvLyBcInNpemVcIiA6IHQubGVuZ3RoLFxuXHRcdFx0XHRcdFx0XCJjc3NcIiA6IHtcblx0XHRcdFx0XHRcdFx0XCJwYWRkaW5nXCIgOiBcIjBcIixcblx0XHRcdFx0XHRcdFx0XCJib3JkZXJcIiA6IFwiMXB4IHNvbGlkIHNpbHZlclwiLFxuXHRcdFx0XHRcdFx0XHRcImJveC1zaXppbmdcIiA6IFwiYm9yZGVyLWJveFwiLFxuXHRcdFx0XHRcdFx0XHRcImRpc3BsYXlcIiA6IFwiaW5saW5lLWJsb2NrXCIsXG5cdFx0XHRcdFx0XHRcdFwiaGVpZ2h0XCIgOiAodGhpcy5fZGF0YS5jb3JlLmxpX2hlaWdodCkgKyBcInB4XCIsXG5cdFx0XHRcdFx0XHRcdFwibGluZUhlaWdodFwiIDogKHRoaXMuX2RhdGEuY29yZS5saV9oZWlnaHQpICsgXCJweFwiLFxuXHRcdFx0XHRcdFx0XHRcIndpZHRoXCIgOiBcIjE1MHB4XCIgLy8gd2lsbCBiZSBzZXQgYSBiaXQgZnVydGhlciBkb3duXG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XCJibHVyXCIgOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdHZhciBpID0gcy5jaGlsZHJlbihcIi5qc3RyZWUtcmVuYW1lLWlucHV0XCIpLFxuXHRcdFx0XHRcdFx0XHRcdHYgPSBpLnZhbCgpLFxuXHRcdFx0XHRcdFx0XHRcdGYgPSB0aGlzLnNldHRpbmdzLmNvcmUuZm9yY2VfdGV4dCxcblx0XHRcdFx0XHRcdFx0XHRudjtcblx0XHRcdFx0XHRcdFx0aWYodiA9PT0gXCJcIikgeyB2ID0gdDsgfVxuXHRcdFx0XHRcdFx0XHRoMS5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdFx0cy5yZXBsYWNlV2l0aChhKTtcblx0XHRcdFx0XHRcdFx0cy5yZW1vdmUoKTtcblx0XHRcdFx0XHRcdFx0dCA9IGYgPyB0IDogJCgnPGRpdj48L2Rpdj4nKS5hcHBlbmQoJC5wYXJzZUhUTUwodCkpLmh0bWwoKTtcblx0XHRcdFx0XHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNldF90ZXh0KG9iaiwgdCk7XG5cdFx0XHRcdFx0XHRcdG52ID0gISF0aGlzLnJlbmFtZV9ub2RlKG9iaiwgZiA/ICQoJzxkaXY+PC9kaXY+JykudGV4dCh2KS50ZXh0KCkgOiAkKCc8ZGl2PjwvZGl2PicpLmFwcGVuZCgkLnBhcnNlSFRNTCh2KSkuaHRtbCgpKTtcblx0XHRcdFx0XHRcdFx0aWYoIW52KSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZXRfdGV4dChvYmosIHQpOyAvLyBtb3ZlIHRoaXMgdXA/IGFuZCBmaXggIzQ4M1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5mb2N1c2VkID0gdG1wLmlkO1xuXHRcdFx0XHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgbm9kZSA9IHRoaXMuZ2V0X25vZGUodG1wLmlkLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0XHRpZihub2RlLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmZvY3VzZWQgPSB0bXAuaWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRub2RlLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9LmJpbmQodGhpcyksIDApO1xuXHRcdFx0XHRcdFx0XHRpZihjYWxsYmFjaykge1xuXHRcdFx0XHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwodGhpcywgdG1wLCBudiwgY2FuY2VsLCB2KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRoMiA9IG51bGw7XG5cdFx0XHRcdFx0XHR9LmJpbmQodGhpcyksXG5cdFx0XHRcdFx0XHRcImtleWRvd25cIiA6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBrZXkgPSBlLndoaWNoO1xuXHRcdFx0XHRcdFx0XHRpZihrZXkgPT09IDI3KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2FuY2VsID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnZhbHVlID0gdDtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihrZXkgPT09IDI3IHx8IGtleSA9PT0gMTMgfHwga2V5ID09PSAzNyB8fCBrZXkgPT09IDM4IHx8IGtleSA9PT0gMzkgfHwga2V5ID09PSA0MCB8fCBrZXkgPT09IDMyKSB7XG5cdFx0XHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZihrZXkgPT09IDI3IHx8IGtleSA9PT0gMTMpIHtcblx0XHRcdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5ibHVyKCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcImNsaWNrXCIgOiBmdW5jdGlvbiAoZSkgeyBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpOyB9LFxuXHRcdFx0XHRcdFx0XCJtb3VzZWRvd25cIiA6IGZ1bmN0aW9uIChlKSB7IGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7IH0sXG5cdFx0XHRcdFx0XHRcImtleXVwXCIgOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0XHRoMi53aWR0aChNYXRoLm1pbihoMS50ZXh0KFwicFdcIiArIHRoaXMudmFsdWUpLndpZHRoKCksdykpO1xuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFwia2V5cHJlc3NcIiA6IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0XHRcdFx0aWYoZS53aGljaCA9PT0gMTMpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdGZuID0ge1xuXHRcdFx0XHRcdFx0Zm9udEZhbWlseVx0XHQ6IGEuY3NzKCdmb250RmFtaWx5JylcdFx0fHwgJycsXG5cdFx0XHRcdFx0XHRmb250U2l6ZVx0XHQ6IGEuY3NzKCdmb250U2l6ZScpXHRcdFx0fHwgJycsXG5cdFx0XHRcdFx0XHRmb250V2VpZ2h0XHRcdDogYS5jc3MoJ2ZvbnRXZWlnaHQnKVx0XHR8fCAnJyxcblx0XHRcdFx0XHRcdGZvbnRTdHlsZVx0XHQ6IGEuY3NzKCdmb250U3R5bGUnKVx0XHR8fCAnJyxcblx0XHRcdFx0XHRcdGZvbnRTdHJldGNoXHRcdDogYS5jc3MoJ2ZvbnRTdHJldGNoJylcdFx0fHwgJycsXG5cdFx0XHRcdFx0XHRmb250VmFyaWFudFx0XHQ6IGEuY3NzKCdmb250VmFyaWFudCcpXHRcdHx8ICcnLFxuXHRcdFx0XHRcdFx0bGV0dGVyU3BhY2luZ1x0OiBhLmNzcygnbGV0dGVyU3BhY2luZycpXHR8fCAnJyxcblx0XHRcdFx0XHRcdHdvcmRTcGFjaW5nXHRcdDogYS5jc3MoJ3dvcmRTcGFjaW5nJylcdFx0fHwgJydcblx0XHRcdFx0fTtcblx0XHRcdHMuYXR0cignY2xhc3MnLCBhLmF0dHIoJ2NsYXNzJykpLmFwcGVuZChhLmNvbnRlbnRzKCkuY2xvbmUoKSkuYXBwZW5kKGgyKTtcblx0XHRcdGEucmVwbGFjZVdpdGgocyk7XG5cdFx0XHRoMS5jc3MoZm4pO1xuXHRcdFx0aDIuY3NzKGZuKS53aWR0aChNYXRoLm1pbihoMS50ZXh0KFwicFdcIiArIGgyWzBdLnZhbHVlKS53aWR0aCgpLHcpKVswXS5zZWxlY3QoKTtcblx0XHRcdCQoZG9jdW1lbnQpLm9uZSgnbW91c2Vkb3duLmpzdHJlZSB0b3VjaHN0YXJ0LmpzdHJlZSBkbmRfc3RhcnQudmFrYXRhJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0aWYgKGgyICYmIGUudGFyZ2V0ICE9PSBoMikge1xuXHRcdFx0XHRcdCQoaDIpLnRyaWdnZXIoJ2JsdXInKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSxcblxuXG5cdFx0LyoqXG5cdFx0ICogY2hhbmdlcyB0aGUgdGhlbWVcblx0XHQgKiBAbmFtZSBzZXRfdGhlbWUodGhlbWVfbmFtZSBbLCB0aGVtZV91cmxdKVxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSB0aGVtZV9uYW1lIHRoZSBuYW1lIG9mIHRoZSBuZXcgdGhlbWUgdG8gYXBwbHlcblx0XHQgKiBAcGFyYW0ge21peGVkfSB0aGVtZV91cmwgIHRoZSBsb2NhdGlvbiBvZiB0aGUgQ1NTIGZpbGUgZm9yIHRoaXMgdGhlbWUuIE9taXQgb3Igc2V0IHRvIGBmYWxzZWAgaWYgeW91IG1hbnVhbGx5IGluY2x1ZGVkIHRoZSBmaWxlLiBTZXQgdG8gYHRydWVgIHRvIGF1dG9sb2FkIGZyb20gdGhlIGBjb3JlLnRoZW1lcy5kaXJgIGRpcmVjdG9yeS5cblx0XHQgKiBAdHJpZ2dlciBzZXRfdGhlbWUuanN0cmVlXG5cdFx0ICovXG5cdFx0c2V0X3RoZW1lIDogZnVuY3Rpb24gKHRoZW1lX25hbWUsIHRoZW1lX3VybCkge1xuXHRcdFx0aWYoIXRoZW1lX25hbWUpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRpZih0aGVtZV91cmwgPT09IHRydWUpIHtcblx0XHRcdFx0dmFyIGRpciA9IHRoaXMuc2V0dGluZ3MuY29yZS50aGVtZXMuZGlyO1xuXHRcdFx0XHRpZighZGlyKSB7IGRpciA9ICQuanN0cmVlLnBhdGggKyAnL3RoZW1lcyc7IH1cblx0XHRcdFx0dGhlbWVfdXJsID0gZGlyICsgJy8nICsgdGhlbWVfbmFtZSArICcvc3R5bGUuY3NzJztcblx0XHRcdH1cblx0XHRcdGlmKHRoZW1lX3VybCAmJiAkLmluQXJyYXkodGhlbWVfdXJsLCB0aGVtZXNfbG9hZGVkKSA9PT0gLTEpIHtcblx0XHRcdFx0JCgnaGVhZCcpLmFwcGVuZCgnPCcrJ2xpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCInICsgdGhlbWVfdXJsICsgJ1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiIC8+Jyk7XG5cdFx0XHRcdHRoZW1lc19sb2FkZWQucHVzaCh0aGVtZV91cmwpO1xuXHRcdFx0fVxuXHRcdFx0aWYodGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5uYW1lKSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzcygnanN0cmVlLScgKyB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLm5hbWUpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5uYW1lID0gdGhlbWVfbmFtZTtcblx0XHRcdHRoaXMuZWxlbWVudC5hZGRDbGFzcygnanN0cmVlLScgKyB0aGVtZV9uYW1lKTtcblx0XHRcdHRoaXMuZWxlbWVudFt0aGlzLnNldHRpbmdzLmNvcmUudGhlbWVzLnJlc3BvbnNpdmUgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJyBdKCdqc3RyZWUtJyArIHRoZW1lX25hbWUgKyAnLXJlc3BvbnNpdmUnKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYSB0aGVtZSBpcyBzZXRcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgc2V0X3RoZW1lLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IHRoZW1lIHRoZSBuZXcgdGhlbWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzZXRfdGhlbWUnLCB7ICd0aGVtZScgOiB0aGVtZV9uYW1lIH0pO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogZ2V0cyB0aGUgbmFtZSBvZiB0aGUgY3VycmVudGx5IGFwcGxpZWQgdGhlbWUgbmFtZVxuXHRcdCAqIEBuYW1lIGdldF90aGVtZSgpXG5cdFx0ICogQHJldHVybiB7U3RyaW5nfVxuXHRcdCAqL1xuXHRcdGdldF90aGVtZSA6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RhdGEuY29yZS50aGVtZXMubmFtZTsgfSxcblx0XHQvKipcblx0XHQgKiBjaGFuZ2VzIHRoZSB0aGVtZSB2YXJpYW50IChpZiB0aGUgdGhlbWUgaGFzIHZhcmlhbnRzKVxuXHRcdCAqIEBuYW1lIHNldF90aGVtZV92YXJpYW50KHZhcmlhbnRfbmFtZSlcblx0XHQgKiBAcGFyYW0ge1N0cmluZ3xCb29sZWFufSB2YXJpYW50X25hbWUgdGhlIHZhcmlhbnQgdG8gYXBwbHkgKGlmIGBmYWxzZWAgaXMgdXNlZCB0aGUgY3VycmVudCB2YXJpYW50IGlzIHJlbW92ZWQpXG5cdFx0ICovXG5cdFx0c2V0X3RoZW1lX3ZhcmlhbnQgOiBmdW5jdGlvbiAodmFyaWFudF9uYW1lKSB7XG5cdFx0XHRpZih0aGlzLl9kYXRhLmNvcmUudGhlbWVzLnZhcmlhbnQpIHtcblx0XHRcdFx0dGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKCdqc3RyZWUtJyArIHRoaXMuX2RhdGEuY29yZS50aGVtZXMubmFtZSArICctJyArIHRoaXMuX2RhdGEuY29yZS50aGVtZXMudmFyaWFudCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9kYXRhLmNvcmUudGhlbWVzLnZhcmlhbnQgPSB2YXJpYW50X25hbWU7XG5cdFx0XHRpZih2YXJpYW50X25hbWUpIHtcblx0XHRcdFx0dGhpcy5lbGVtZW50LmFkZENsYXNzKCdqc3RyZWUtJyArIHRoaXMuX2RhdGEuY29yZS50aGVtZXMubmFtZSArICctJyArIHRoaXMuX2RhdGEuY29yZS50aGVtZXMudmFyaWFudCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBnZXRzIHRoZSBuYW1lIG9mIHRoZSBjdXJyZW50bHkgYXBwbGllZCB0aGVtZSB2YXJpYW50XG5cdFx0ICogQG5hbWUgZ2V0X3RoZW1lKClcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd9XG5cdFx0ICovXG5cdFx0Z2V0X3RoZW1lX3ZhcmlhbnQgOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9kYXRhLmNvcmUudGhlbWVzLnZhcmlhbnQ7IH0sXG5cdFx0LyoqXG5cdFx0ICogc2hvd3MgYSBzdHJpcGVkIGJhY2tncm91bmQgb24gdGhlIGNvbnRhaW5lciAoaWYgdGhlIHRoZW1lIHN1cHBvcnRzIGl0KVxuXHRcdCAqIEBuYW1lIHNob3dfc3RyaXBlcygpXG5cdFx0ICovXG5cdFx0c2hvd19zdHJpcGVzIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5zdHJpcGVzID0gdHJ1ZTtcblx0XHRcdHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpLmFkZENsYXNzKFwianN0cmVlLXN0cmlwZWRcIik7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIHN0cmlwZXMgYXJlIHNob3duXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIHNob3dfc3RyaXBlcy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzaG93X3N0cmlwZXMnKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGhpZGVzIHRoZSBzdHJpcGVkIGJhY2tncm91bmQgb24gdGhlIGNvbnRhaW5lclxuXHRcdCAqIEBuYW1lIGhpZGVfc3RyaXBlcygpXG5cdFx0ICovXG5cdFx0aGlkZV9zdHJpcGVzIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5zdHJpcGVzID0gZmFsc2U7XG5cdFx0XHR0aGlzLmdldF9jb250YWluZXJfdWwoKS5yZW1vdmVDbGFzcyhcImpzdHJlZS1zdHJpcGVkXCIpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBzdHJpcGVzIGFyZSBoaWRkZW5cblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgaGlkZV9zdHJpcGVzLmpzdHJlZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2hpZGVfc3RyaXBlcycpO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogdG9nZ2xlcyB0aGUgc3RyaXBlZCBiYWNrZ3JvdW5kIG9uIHRoZSBjb250YWluZXJcblx0XHQgKiBAbmFtZSB0b2dnbGVfc3RyaXBlcygpXG5cdFx0ICovXG5cdFx0dG9nZ2xlX3N0cmlwZXMgOiBmdW5jdGlvbiAoKSB7IGlmKHRoaXMuX2RhdGEuY29yZS50aGVtZXMuc3RyaXBlcykgeyB0aGlzLmhpZGVfc3RyaXBlcygpOyB9IGVsc2UgeyB0aGlzLnNob3dfc3RyaXBlcygpOyB9IH0sXG5cdFx0LyoqXG5cdFx0ICogc2hvd3MgdGhlIGNvbm5lY3RpbmcgZG90cyAoaWYgdGhlIHRoZW1lIHN1cHBvcnRzIGl0KVxuXHRcdCAqIEBuYW1lIHNob3dfZG90cygpXG5cdFx0ICovXG5cdFx0c2hvd19kb3RzIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5kb3RzID0gdHJ1ZTtcblx0XHRcdHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpLnJlbW92ZUNsYXNzKFwianN0cmVlLW5vLWRvdHNcIik7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGRvdHMgYXJlIHNob3duXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIHNob3dfZG90cy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzaG93X2RvdHMnKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGhpZGVzIHRoZSBjb25uZWN0aW5nIGRvdHNcblx0XHQgKiBAbmFtZSBoaWRlX2RvdHMoKVxuXHRcdCAqL1xuXHRcdGhpZGVfZG90cyA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS50aGVtZXMuZG90cyA9IGZhbHNlO1xuXHRcdFx0dGhpcy5nZXRfY29udGFpbmVyX3VsKCkuYWRkQ2xhc3MoXCJqc3RyZWUtbm8tZG90c1wiKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gZG90cyBhcmUgaGlkZGVuXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGhpZGVfZG90cy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdoaWRlX2RvdHMnKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHRvZ2dsZXMgdGhlIGNvbm5lY3RpbmcgZG90c1xuXHRcdCAqIEBuYW1lIHRvZ2dsZV9kb3RzKClcblx0XHQgKi9cblx0XHR0b2dnbGVfZG90cyA6IGZ1bmN0aW9uICgpIHsgaWYodGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5kb3RzKSB7IHRoaXMuaGlkZV9kb3RzKCk7IH0gZWxzZSB7IHRoaXMuc2hvd19kb3RzKCk7IH0gfSxcblx0XHQvKipcblx0XHQgKiBzaG93IHRoZSBub2RlIGljb25zXG5cdFx0ICogQG5hbWUgc2hvd19pY29ucygpXG5cdFx0ICovXG5cdFx0c2hvd19pY29ucyA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS50aGVtZXMuaWNvbnMgPSB0cnVlO1xuXHRcdFx0dGhpcy5nZXRfY29udGFpbmVyX3VsKCkucmVtb3ZlQ2xhc3MoXCJqc3RyZWUtbm8taWNvbnNcIik7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGljb25zIGFyZSBzaG93blxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBzaG93X2ljb25zLmpzdHJlZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ3Nob3dfaWNvbnMnKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGhpZGUgdGhlIG5vZGUgaWNvbnNcblx0XHQgKiBAbmFtZSBoaWRlX2ljb25zKClcblx0XHQgKi9cblx0XHRoaWRlX2ljb25zIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0dGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5pY29ucyA9IGZhbHNlO1xuXHRcdFx0dGhpcy5nZXRfY29udGFpbmVyX3VsKCkuYWRkQ2xhc3MoXCJqc3RyZWUtbm8taWNvbnNcIik7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGljb25zIGFyZSBoaWRkZW5cblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgaGlkZV9pY29ucy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdoaWRlX2ljb25zJyk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiB0b2dnbGUgdGhlIG5vZGUgaWNvbnNcblx0XHQgKiBAbmFtZSB0b2dnbGVfaWNvbnMoKVxuXHRcdCAqL1xuXHRcdHRvZ2dsZV9pY29ucyA6IGZ1bmN0aW9uICgpIHsgaWYodGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5pY29ucykgeyB0aGlzLmhpZGVfaWNvbnMoKTsgfSBlbHNlIHsgdGhpcy5zaG93X2ljb25zKCk7IH0gfSxcblx0XHQvKipcblx0XHQgKiBzaG93IHRoZSBub2RlIGVsbGlwc2lzXG5cdFx0ICogQG5hbWUgc2hvd19pY29ucygpXG5cdFx0ICovXG5cdFx0c2hvd19lbGxpcHNpcyA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS50aGVtZXMuZWxsaXBzaXMgPSB0cnVlO1xuXHRcdFx0dGhpcy5nZXRfY29udGFpbmVyX3VsKCkuYWRkQ2xhc3MoXCJqc3RyZWUtZWxsaXBzaXNcIik7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIGVsbGlzaXMgaXMgc2hvd25cblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgc2hvd19lbGxpcHNpcy5qc3RyZWVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzaG93X2VsbGlwc2lzJyk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBoaWRlIHRoZSBub2RlIGVsbGlwc2lzXG5cdFx0ICogQG5hbWUgaGlkZV9lbGxpcHNpcygpXG5cdFx0ICovXG5cdFx0aGlkZV9lbGxpcHNpcyA6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMuX2RhdGEuY29yZS50aGVtZXMuZWxsaXBzaXMgPSBmYWxzZTtcblx0XHRcdHRoaXMuZ2V0X2NvbnRhaW5lcl91bCgpLnJlbW92ZUNsYXNzKFwianN0cmVlLWVsbGlwc2lzXCIpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBlbGxpc2lzIGlzIGhpZGRlblxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSBoaWRlX2VsbGlwc2lzLmpzdHJlZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2hpZGVfZWxsaXBzaXMnKTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHRvZ2dsZSB0aGUgbm9kZSBlbGxpcHNpc1xuXHRcdCAqIEBuYW1lIHRvZ2dsZV9pY29ucygpXG5cdFx0ICovXG5cdFx0dG9nZ2xlX2VsbGlwc2lzIDogZnVuY3Rpb24gKCkgeyBpZih0aGlzLl9kYXRhLmNvcmUudGhlbWVzLmVsbGlwc2lzKSB7IHRoaXMuaGlkZV9lbGxpcHNpcygpOyB9IGVsc2UgeyB0aGlzLnNob3dfZWxsaXBzaXMoKTsgfSB9LFxuXHRcdC8qKlxuXHRcdCAqIHNldCB0aGUgbm9kZSBpY29uIGZvciBhIG5vZGVcblx0XHQgKiBAbmFtZSBzZXRfaWNvbihvYmosIGljb24pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGljb24gdGhlIG5ldyBpY29uIC0gY2FuIGJlIGEgcGF0aCB0byBhbiBpY29uIG9yIGEgY2xhc3NOYW1lLCBpZiB1c2luZyBhbiBpbWFnZSB0aGF0IGlzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB1c2UgYSBgLi9gIHByZWZpeCwgb3RoZXJ3aXNlIGl0IHdpbGwgYmUgZGV0ZWN0ZWQgYXMgYSBjbGFzc1xuXHRcdCAqL1xuXHRcdHNldF9pY29uIDogZnVuY3Rpb24gKG9iaiwgaWNvbikge1xuXHRcdFx0dmFyIHQxLCB0MiwgZG9tLCBvbGQ7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnNldF9pY29uKG9ialt0MV0sIGljb24pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRvbGQgPSBvYmouaWNvbjtcblx0XHRcdG9iai5pY29uID0gaWNvbiA9PT0gdHJ1ZSB8fCBpY29uID09PSBudWxsIHx8IGljb24gPT09IHVuZGVmaW5lZCB8fCBpY29uID09PSAnJyA/IHRydWUgOiBpY29uO1xuXHRcdFx0ZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpLmNoaWxkcmVuKFwiLmpzdHJlZS1hbmNob3JcIikuY2hpbGRyZW4oXCIuanN0cmVlLXRoZW1laWNvblwiKTtcblx0XHRcdGlmKGljb24gPT09IGZhbHNlKSB7XG5cdFx0XHRcdGRvbS5yZW1vdmVDbGFzcygnanN0cmVlLXRoZW1laWNvbi1jdXN0b20gJyArIG9sZCkuY3NzKFwiYmFja2dyb3VuZFwiLFwiXCIpLnJlbW92ZUF0dHIoXCJyZWxcIik7XG5cdFx0XHRcdHRoaXMuaGlkZV9pY29uKG9iaik7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIGlmKGljb24gPT09IHRydWUgfHwgaWNvbiA9PT0gbnVsbCB8fCBpY29uID09PSB1bmRlZmluZWQgfHwgaWNvbiA9PT0gJycpIHtcblx0XHRcdFx0ZG9tLnJlbW92ZUNsYXNzKCdqc3RyZWUtdGhlbWVpY29uLWN1c3RvbSAnICsgb2xkKS5jc3MoXCJiYWNrZ3JvdW5kXCIsXCJcIikucmVtb3ZlQXR0cihcInJlbFwiKTtcblx0XHRcdFx0aWYob2xkID09PSBmYWxzZSkgeyB0aGlzLnNob3dfaWNvbihvYmopOyB9XG5cdFx0XHR9XG5cdFx0XHRlbHNlIGlmKGljb24uaW5kZXhPZihcIi9cIikgPT09IC0xICYmIGljb24uaW5kZXhPZihcIi5cIikgPT09IC0xKSB7XG5cdFx0XHRcdGRvbS5yZW1vdmVDbGFzcyhvbGQpLmNzcyhcImJhY2tncm91bmRcIixcIlwiKTtcblx0XHRcdFx0ZG9tLmFkZENsYXNzKGljb24gKyAnIGpzdHJlZS10aGVtZWljb24tY3VzdG9tJykuYXR0cihcInJlbFwiLGljb24pO1xuXHRcdFx0XHRpZihvbGQgPT09IGZhbHNlKSB7IHRoaXMuc2hvd19pY29uKG9iaik7IH1cblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRkb20ucmVtb3ZlQ2xhc3Mob2xkKS5jc3MoXCJiYWNrZ3JvdW5kXCIsXCJcIik7XG5cdFx0XHRcdGRvbS5hZGRDbGFzcygnanN0cmVlLXRoZW1laWNvbi1jdXN0b20nKS5jc3MoXCJiYWNrZ3JvdW5kXCIsIFwidXJsKCdcIiArIGljb24gKyBcIicpIGNlbnRlciBjZW50ZXIgbm8tcmVwZWF0XCIpLmF0dHIoXCJyZWxcIixpY29uKTtcblx0XHRcdFx0aWYob2xkID09PSBmYWxzZSkgeyB0aGlzLnNob3dfaWNvbihvYmopOyB9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIGdldCB0aGUgbm9kZSBpY29uIGZvciBhIG5vZGVcblx0XHQgKiBAbmFtZSBnZXRfaWNvbihvYmopXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqXG5cdFx0ICogQHJldHVybiB7U3RyaW5nfVxuXHRcdCAqL1xuXHRcdGdldF9pY29uIDogZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cmV0dXJuICghb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgPyBmYWxzZSA6IG9iai5pY29uO1xuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogaGlkZSB0aGUgaWNvbiBvbiBhbiBpbmRpdmlkdWFsIG5vZGVcblx0XHQgKiBAbmFtZSBoaWRlX2ljb24ob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9ialxuXHRcdCAqL1xuXHRcdGhpZGVfaWNvbiA6IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdHZhciB0MSwgdDI7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLmhpZGVfaWNvbihvYmpbdDFdKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0b2JqLmljb24gPSBmYWxzZTtcblx0XHRcdHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKS5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpLmNoaWxkcmVuKFwiLmpzdHJlZS10aGVtZWljb25cIikuYWRkQ2xhc3MoJ2pzdHJlZS10aGVtZWljb24taGlkZGVuJyk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIHNob3cgdGhlIGljb24gb24gYW4gaW5kaXZpZHVhbCBub2RlXG5cdFx0ICogQG5hbWUgc2hvd19pY29uKG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmpcblx0XHQgKi9cblx0XHRzaG93X2ljb24gOiBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHR2YXIgdDEsIHQyLCBkb207XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnNob3dfaWNvbihvYmpbdDFdKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0ZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0b2JqLmljb24gPSBkb20ubGVuZ3RoID8gZG9tLmNoaWxkcmVuKFwiLmpzdHJlZS1hbmNob3JcIikuY2hpbGRyZW4oXCIuanN0cmVlLXRoZW1laWNvblwiKS5hdHRyKCdyZWwnKSA6IHRydWU7XG5cdFx0XHRpZighb2JqLmljb24pIHsgb2JqLmljb24gPSB0cnVlOyB9XG5cdFx0XHRkb20uY2hpbGRyZW4oXCIuanN0cmVlLWFuY2hvclwiKS5jaGlsZHJlbihcIi5qc3RyZWUtdGhlbWVpY29uXCIpLnJlbW92ZUNsYXNzKCdqc3RyZWUtdGhlbWVpY29uLWhpZGRlbicpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9O1xuXG5cdC8vIGhlbHBlcnNcblx0JC52YWthdGEgPSB7fTtcblx0Ly8gY29sbGVjdCBhdHRyaWJ1dGVzXG5cdCQudmFrYXRhLmF0dHJpYnV0ZXMgPSBmdW5jdGlvbihub2RlLCB3aXRoX3ZhbHVlcykge1xuXHRcdG5vZGUgPSAkKG5vZGUpWzBdO1xuXHRcdHZhciBhdHRyID0gd2l0aF92YWx1ZXMgPyB7fSA6IFtdO1xuXHRcdGlmKG5vZGUgJiYgbm9kZS5hdHRyaWJ1dGVzKSB7XG5cdFx0XHQkLmVhY2gobm9kZS5hdHRyaWJ1dGVzLCBmdW5jdGlvbiAoaSwgdikge1xuXHRcdFx0XHRpZigkLmluQXJyYXkodi5uYW1lLnRvTG93ZXJDYXNlKCksWydzdHlsZScsJ2NvbnRlbnRlZGl0YWJsZScsJ2hhc2ZvY3VzJywndGFiaW5kZXgnXSkgIT09IC0xKSB7IHJldHVybjsgfVxuXHRcdFx0XHRpZih2LnZhbHVlICE9PSBudWxsICYmICQudmFrYXRhLnRyaW0odi52YWx1ZSkgIT09ICcnKSB7XG5cdFx0XHRcdFx0aWYod2l0aF92YWx1ZXMpIHsgYXR0clt2Lm5hbWVdID0gdi52YWx1ZTsgfVxuXHRcdFx0XHRcdGVsc2UgeyBhdHRyLnB1c2godi5uYW1lKTsgfVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIGF0dHI7XG5cdH07XG5cdCQudmFrYXRhLmFycmF5X3VuaXF1ZSA9IGZ1bmN0aW9uKGFycmF5KSB7XG5cdFx0dmFyIGEgPSBbXSwgaSwgaiwgbCwgbyA9IHt9O1xuXHRcdGZvcihpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuXHRcdFx0aWYob1thcnJheVtpXV0gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRhLnB1c2goYXJyYXlbaV0pO1xuXHRcdFx0XHRvW2FycmF5W2ldXSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBhO1xuXHR9O1xuXHQvLyByZW1vdmUgaXRlbSBmcm9tIGFycmF5XG5cdCQudmFrYXRhLmFycmF5X3JlbW92ZSA9IGZ1bmN0aW9uKGFycmF5LCBmcm9tKSB7XG5cdFx0YXJyYXkuc3BsaWNlKGZyb20sIDEpO1xuXHRcdHJldHVybiBhcnJheTtcblx0XHQvL3ZhciByZXN0ID0gYXJyYXkuc2xpY2UoKHRvIHx8IGZyb20pICsgMSB8fCBhcnJheS5sZW5ndGgpO1xuXHRcdC8vYXJyYXkubGVuZ3RoID0gZnJvbSA8IDAgPyBhcnJheS5sZW5ndGggKyBmcm9tIDogZnJvbTtcblx0XHQvL2FycmF5LnB1c2guYXBwbHkoYXJyYXksIHJlc3QpO1xuXHRcdC8vcmV0dXJuIGFycmF5O1xuXHR9O1xuXHQvLyByZW1vdmUgaXRlbSBmcm9tIGFycmF5XG5cdCQudmFrYXRhLmFycmF5X3JlbW92ZV9pdGVtID0gZnVuY3Rpb24oYXJyYXksIGl0ZW0pIHtcblx0XHR2YXIgdG1wID0gJC5pbkFycmF5KGl0ZW0sIGFycmF5KTtcblx0XHRyZXR1cm4gdG1wICE9PSAtMSA/ICQudmFrYXRhLmFycmF5X3JlbW92ZShhcnJheSwgdG1wKSA6IGFycmF5O1xuXHR9O1xuXHQkLnZha2F0YS5hcnJheV9maWx0ZXIgPSBmdW5jdGlvbihjLGEsYixkLGUpIHtcblx0XHRpZiAoYy5maWx0ZXIpIHtcblx0XHRcdHJldHVybiBjLmZpbHRlcihhLCBiKTtcblx0XHR9XG5cdFx0ZD1bXTtcblx0XHRmb3IgKGUgaW4gYykge1xuXHRcdFx0aWYgKH5+ZSsnJz09PWUrJycgJiYgZT49MCAmJiBhLmNhbGwoYixjW2VdLCtlLGMpKSB7XG5cdFx0XHRcdGQucHVzaChjW2VdKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGQ7XG5cdH07XG5cdCQudmFrYXRhLnRyaW0gPSBmdW5jdGlvbiAodGV4dCkge1xuXHRcdHJldHVybiBTdHJpbmcucHJvdG90eXBlLnRyaW0gPyBcblx0XHRcdFN0cmluZy5wcm90b3R5cGUudHJpbS5jYWxsKHRleHQudG9TdHJpbmcoKSkgOlxuXHRcdFx0dGV4dC50b1N0cmluZygpLnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG5cdH07XG5cdCQudmFrYXRhLmlzX2Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygb2JqLm5vZGVUeXBlICE9PSBcIm51bWJlclwiO1xuXHR9O1xuXHQkLnZha2F0YS5pc19hcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKG9iaikge1xuXHRcdHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xuXHR9O1xuXG5cdC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9vYmplY3RzL0Z1bmN0aW9uL2JpbmQjcG9seWZpbGxcblx0aWYgKCFGdW5jdGlvbi5wcm90b3R5cGUuYmluZCkge1xuXHRcdEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIHRoYXRGdW5jID0gdGhpcywgdGhhdEFyZyA9IGFyZ3VtZW50c1swXTtcblx0XHRcdHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0XHRcdGlmICh0eXBlb2YgdGhhdEZ1bmMgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0Ly8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XG5cdFx0XHRcdC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cblx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmdW5jdGlvbigpe1xuXHRcdFx0XHR2YXIgZnVuY0FyZ3MgPSBhcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKTtcblx0XHRcdFx0cmV0dXJuIHRoYXRGdW5jLmFwcGx5KHRoYXRBcmcsIGZ1bmNBcmdzKTtcblx0XHRcdH07XG5cdFx0fTtcblx0fVxuXG5cbi8qKlxuICogIyMjIENoYW5nZWQgcGx1Z2luXG4gKlxuICogVGhpcyBwbHVnaW4gYWRkcyBtb3JlIGluZm9ybWF0aW9uIHRvIHRoZSBgY2hhbmdlZC5qc3RyZWVgIGV2ZW50LiBUaGUgbmV3IGRhdGEgaXMgY29udGFpbmVkIGluIHRoZSBgY2hhbmdlZGAgZXZlbnQgZGF0YSBwcm9wZXJ0eSwgYW5kIGNvbnRhaW5zIGEgbGlzdHMgb2YgYHNlbGVjdGVkYCBhbmQgYGRlc2VsZWN0ZWRgIG5vZGVzLlxuICovXG5cblx0JC5qc3RyZWUucGx1Z2lucy5jaGFuZ2VkID0gZnVuY3Rpb24gKG9wdGlvbnMsIHBhcmVudCkge1xuXHRcdHZhciBsYXN0ID0gW107XG5cdFx0dGhpcy50cmlnZ2VyID0gZnVuY3Rpb24gKGV2LCBkYXRhKSB7XG5cdFx0XHR2YXIgaSwgajtcblx0XHRcdGlmKCFkYXRhKSB7XG5cdFx0XHRcdGRhdGEgPSB7fTtcblx0XHRcdH1cblx0XHRcdGlmKGV2LnJlcGxhY2UoJy5qc3RyZWUnLCcnKSA9PT0gJ2NoYW5nZWQnKSB7XG5cdFx0XHRcdGRhdGEuY2hhbmdlZCA9IHsgc2VsZWN0ZWQgOiBbXSwgZGVzZWxlY3RlZCA6IFtdIH07XG5cdFx0XHRcdHZhciB0bXAgPSB7fTtcblx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gbGFzdC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHR0bXBbbGFzdFtpXV0gPSAxO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IGRhdGEuc2VsZWN0ZWQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0aWYoIXRtcFtkYXRhLnNlbGVjdGVkW2ldXSkge1xuXHRcdFx0XHRcdFx0ZGF0YS5jaGFuZ2VkLnNlbGVjdGVkLnB1c2goZGF0YS5zZWxlY3RlZFtpXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0dG1wW2RhdGEuc2VsZWN0ZWRbaV1dID0gMjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gbGFzdC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRpZih0bXBbbGFzdFtpXV0gPT09IDEpIHtcblx0XHRcdFx0XHRcdGRhdGEuY2hhbmdlZC5kZXNlbGVjdGVkLnB1c2gobGFzdFtpXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGxhc3QgPSBkYXRhLnNlbGVjdGVkLnNsaWNlKCk7XG5cdFx0XHR9XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIHNlbGVjdGlvbiBjaGFuZ2VzICh0aGUgXCJjaGFuZ2VkXCIgcGx1Z2luIGVuaGFuY2VzIHRoZSBvcmlnaW5hbCBldmVudCB3aXRoIG1vcmUgZGF0YSlcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgY2hhbmdlZC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gYWN0aW9uIHRoZSBhY3Rpb24gdGhhdCBjYXVzZWQgdGhlIHNlbGVjdGlvbiB0byBjaGFuZ2Vcblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IHNlbGVjdGVkIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuXHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IGNoYW5nZWQgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdHdvIHByb3BlcnRpZXMgYHNlbGVjdGVkYCBhbmQgYGRlc2VsZWN0ZWRgIC0gYm90aCBhcnJheXMgb2Ygbm9kZSBJRHMsIHdoaWNoIHdlcmUgc2VsZWN0ZWQgb3IgZGVzZWxlY3RlZCBzaW5jZSB0aGUgbGFzdCBjaGFuZ2VkIGV2ZW50XG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgdGhlIGV2ZW50IChpZiBhbnkpIHRoYXQgdHJpZ2dlcmVkIHRoaXMgY2hhbmdlZCBldmVudFxuXHRcdFx0ICogQHBsdWdpbiBjaGFuZ2VkXG5cdFx0XHQgKi9cblx0XHRcdHBhcmVudC50cmlnZ2VyLmNhbGwodGhpcywgZXYsIGRhdGEpO1xuXHRcdH07XG5cdFx0dGhpcy5yZWZyZXNoID0gZnVuY3Rpb24gKHNraXBfbG9hZGluZywgZm9yZ2V0X3N0YXRlKSB7XG5cdFx0XHRsYXN0ID0gW107XG5cdFx0XHRyZXR1cm4gcGFyZW50LnJlZnJlc2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHR9O1xuXHR9O1xuXG4vKipcbiAqICMjIyBDaGVja2JveCBwbHVnaW5cbiAqXG4gKiBUaGlzIHBsdWdpbiByZW5kZXJzIGNoZWNrYm94IGljb25zIGluIGZyb250IG9mIGVhY2ggbm9kZSwgbWFraW5nIG11bHRpcGxlIHNlbGVjdGlvbiBtdWNoIGVhc2llci5cbiAqIEl0IGFsc28gc3VwcG9ydHMgdHJpLXN0YXRlIGJlaGF2aW9yLCBtZWFuaW5nIHRoYXQgaWYgYSBub2RlIGhhcyBhIGZldyBvZiBpdHMgY2hpbGRyZW4gY2hlY2tlZCBpdCB3aWxsIGJlIHJlbmRlcmVkIGFzIHVuZGV0ZXJtaW5lZCwgYW5kIHN0YXRlIHdpbGwgYmUgcHJvcGFnYXRlZCB1cC5cbiAqL1xuXG5cdHZhciBfaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0knKTtcblx0X2kuY2xhc3NOYW1lID0gJ2pzdHJlZS1pY29uIGpzdHJlZS1jaGVja2JveCc7XG5cdF9pLnNldEF0dHJpYnV0ZSgncm9sZScsICdwcmVzZW50YXRpb24nKTtcblx0LyoqXG5cdCAqIHN0b3JlcyBhbGwgZGVmYXVsdHMgZm9yIHRoZSBjaGVja2JveCBwbHVnaW5cblx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3hcblx0ICogQHBsdWdpbiBjaGVja2JveFxuXHQgKi9cblx0JC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3ggPSB7XG5cdFx0LyoqXG5cdFx0ICogYSBib29sZWFuIGluZGljYXRpbmcgaWYgY2hlY2tib3hlcyBzaG91bGQgYmUgdmlzaWJsZSAoY2FuIGJlIGNoYW5nZWQgYXQgYSBsYXRlciB0aW1lIHVzaW5nIGBzaG93X2NoZWNrYm94ZXMoKWAgYW5kIGBoaWRlX2NoZWNrYm94ZXNgKS4gRGVmYXVsdHMgdG8gYHRydWVgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNoZWNrYm94LnZpc2libGVcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dmlzaWJsZVx0XHRcdFx0OiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIGNoZWNrYm94ZXMgc2hvdWxkIGNhc2NhZGUgZG93biBhbmQgaGF2ZSBhbiB1bmRldGVybWluZWQgc3RhdGUuIERlZmF1bHRzIHRvIGB0cnVlYC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jaGVja2JveC50aHJlZV9zdGF0ZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aHJlZV9zdGF0ZVx0XHRcdDogdHJ1ZSxcblx0XHQvKipcblx0XHQgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBjbGlja2luZyBhbnl3aGVyZSBvbiB0aGUgbm9kZSBzaG91bGQgYWN0IGFzIGNsaWNraW5nIG9uIHRoZSBjaGVja2JveC4gRGVmYXVsdHMgdG8gYHRydWVgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNoZWNrYm94Lndob2xlX25vZGVcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0d2hvbGVfbm9kZVx0XHRcdDogdHJ1ZSxcblx0XHQvKipcblx0XHQgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgc2VsZWN0ZWQgc3R5bGUgb2YgYSBub2RlIHNob3VsZCBiZSBrZXB0LCBvciByZW1vdmVkLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3gua2VlcF9zZWxlY3RlZF9zdHlsZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHRrZWVwX3NlbGVjdGVkX3N0eWxlXHQ6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogVGhpcyBzZXR0aW5nIGNvbnRyb2xzIGhvdyBjYXNjYWRpbmcgYW5kIHVuZGV0ZXJtaW5lZCBub2RlcyBhcmUgYXBwbGllZC5cblx0XHQgKiBJZiAndXAnIGlzIGluIHRoZSBzdHJpbmcgLSBjYXNjYWRpbmcgdXAgaXMgZW5hYmxlZCwgaWYgJ2Rvd24nIGlzIGluIHRoZSBzdHJpbmcgLSBjYXNjYWRpbmcgZG93biBpcyBlbmFibGVkLCBpZiAndW5kZXRlcm1pbmVkJyBpcyBpbiB0aGUgc3RyaW5nIC0gdW5kZXRlcm1pbmVkIG5vZGVzIHdpbGwgYmUgdXNlZC5cblx0XHQgKiBJZiBgdGhyZWVfc3RhdGVgIGlzIHNldCB0byBgdHJ1ZWAgdGhpcyBzZXR0aW5nIGlzIGF1dG9tYXRpY2FsbHkgc2V0IHRvICd1cCtkb3duK3VuZGV0ZXJtaW5lZCcuIERlZmF1bHRzIHRvICcnLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNoZWNrYm94LmNhc2NhZGVcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0Y2FzY2FkZVx0XHRcdFx0OiAnJyxcblx0XHQvKipcblx0XHQgKiBUaGlzIHNldHRpbmcgY29udHJvbHMgaWYgY2hlY2tib3ggYXJlIGJvdW5kIHRvIHRoZSBnZW5lcmFsIHRyZWUgc2VsZWN0aW9uIG9yIHRvIGFuIGludGVybmFsIGFycmF5IG1haW50YWluZWQgYnkgdGhlIGNoZWNrYm94IHBsdWdpbi4gRGVmYXVsdHMgdG8gYHRydWVgLCBvbmx5IHNldCB0byBgZmFsc2VgIGlmIHlvdSBrbm93IGV4YWN0bHkgd2hhdCB5b3UgYXJlIGRvaW5nLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb25cblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGllX3NlbGVjdGlvblx0XHQ6IHRydWUsXG5cblx0XHQvKipcblx0XHQgKiBUaGlzIHNldHRpbmcgY29udHJvbHMgaWYgY2FzY2FkaW5nIGRvd24gYWZmZWN0cyBkaXNhYmxlZCBjaGVja2JveGVzXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3guY2FzY2FkZV90b19kaXNhYmxlZFxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHRjYXNjYWRlX3RvX2Rpc2FibGVkIDogdHJ1ZSxcblxuXHRcdC8qKlxuXHRcdCAqIFRoaXMgc2V0dGluZyBjb250cm9scyBpZiBjYXNjYWRpbmcgZG93biBhZmZlY3RzIGhpZGRlbiBjaGVja2JveGVzXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3guY2FzY2FkZV90b19oaWRkZW5cblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0Y2FzY2FkZV90b19oaWRkZW4gOiB0cnVlXG5cdH07XG5cdCQuanN0cmVlLnBsdWdpbnMuY2hlY2tib3ggPSBmdW5jdGlvbiAob3B0aW9ucywgcGFyZW50KSB7XG5cdFx0dGhpcy5iaW5kID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cGFyZW50LmJpbmQuY2FsbCh0aGlzKTtcblx0XHRcdHRoaXMuX2RhdGEuY2hlY2tib3gudXRvID0gZmFsc2U7XG5cdFx0XHR0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkID0gW107XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRocmVlX3N0YXRlKSB7XG5cdFx0XHRcdHRoaXMuc2V0dGluZ3MuY2hlY2tib3guY2FzY2FkZSA9ICd1cCtkb3duK3VuZGV0ZXJtaW5lZCc7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0Lm9uKFwiaW5pdC5qc3RyZWVcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jaGVja2JveC52aXNpYmxlID0gdGhpcy5zZXR0aW5ncy5jaGVja2JveC52aXNpYmxlO1xuXHRcdFx0XHRcdFx0aWYoIXRoaXMuc2V0dGluZ3MuY2hlY2tib3gua2VlcF9zZWxlY3RlZF9zdHlsZSkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmVsZW1lbnQuYWRkQ2xhc3MoJ2pzdHJlZS1jaGVja2JveC1uby1jbGlja2VkJyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24pIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LmFkZENsYXNzKCdqc3RyZWUtY2hlY2tib3gtc2VsZWN0aW9uJyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJsb2FkaW5nLmpzdHJlZVwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHR0aGlzWyB0aGlzLl9kYXRhLmNoZWNrYm94LnZpc2libGUgPyAnc2hvd19jaGVja2JveGVzJyA6ICdoaWRlX2NoZWNrYm94ZXMnIF0oKTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlLmluZGV4T2YoJ3VuZGV0ZXJtaW5lZCcpICE9PSAtMSkge1xuXHRcdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0XHQub24oJ2NoYW5nZWQuanN0cmVlIHVuY2hlY2tfbm9kZS5qc3RyZWUgY2hlY2tfbm9kZS5qc3RyZWUgdW5jaGVja19hbGwuanN0cmVlIGNoZWNrX2FsbC5qc3RyZWUgbW92ZV9ub2RlLmpzdHJlZSBjb3B5X25vZGUuanN0cmVlIHJlZHJhdy5qc3RyZWUgb3Blbl9ub2RlLmpzdHJlZScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdFx0Ly8gb25seSBpZiB1bmRldGVybWluZWQgaXMgaW4gc2V0dGluZ1xuXHRcdFx0XHRcdFx0XHRpZih0aGlzLl9kYXRhLmNoZWNrYm94LnV0bykgeyBjbGVhclRpbWVvdXQodGhpcy5fZGF0YS5jaGVja2JveC51dG8pOyB9XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY2hlY2tib3gudXRvID0gc2V0VGltZW91dCh0aGlzLl91bmRldGVybWluZWQuYmluZCh0aGlzKSwgNTApO1xuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdH1cblx0XHRcdGlmKCF0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24pIHtcblx0XHRcdFx0dGhpcy5lbGVtZW50XG5cdFx0XHRcdFx0Lm9uKCdtb2RlbC5qc3RyZWUnLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0dmFyIG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRcdFx0XHRwID0gbVtkYXRhLnBhcmVudF0sXG5cdFx0XHRcdFx0XHRcdGRwYyA9IGRhdGEubm9kZXMsXG5cdFx0XHRcdFx0XHRcdGksIGo7XG5cdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBkcGMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdG1bZHBjW2ldXS5zdGF0ZS5jaGVja2VkID0gbVtkcGNbaV1dLnN0YXRlLmNoZWNrZWQgfHwgKG1bZHBjW2ldXS5vcmlnaW5hbCAmJiBtW2RwY1tpXV0ub3JpZ2luYWwuc3RhdGUgJiYgbVtkcGNbaV1dLm9yaWdpbmFsLnN0YXRlLmNoZWNrZWQpO1xuXHRcdFx0XHRcdFx0XHRpZihtW2RwY1tpXV0uc3RhdGUuY2hlY2tlZCkge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQucHVzaChkcGNbaV0pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3guY2FzY2FkZS5pbmRleE9mKCd1cCcpICE9PSAtMSB8fCB0aGlzLnNldHRpbmdzLmNoZWNrYm94LmNhc2NhZGUuaW5kZXhPZignZG93bicpICE9PSAtMSkge1xuXHRcdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0XHQub24oJ21vZGVsLmpzdHJlZScsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBtID0gdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0XHRcdFx0XHRwID0gbVtkYXRhLnBhcmVudF0sXG5cdFx0XHRcdFx0XHRcdFx0ZHBjID0gZGF0YS5ub2Rlcyxcblx0XHRcdFx0XHRcdFx0XHRjaGQgPSBbXSxcblx0XHRcdFx0XHRcdFx0XHRjLCBpLCBqLCBrLCBsLCB0bXAsIHMgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LmNhc2NhZGUsIHQgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb247XG5cblx0XHRcdFx0XHRcdFx0aWYocy5pbmRleE9mKCdkb3duJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gYXBwbHkgZG93blxuXHRcdFx0XHRcdFx0XHRcdGlmKHAuc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF0pIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IGRwYy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0bVtkcGNbaV1dLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZCA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQuY29uY2F0KGRwYyk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gZHBjLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZihtW2RwY1tpXV0uc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF0pIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRmb3IoayA9IDAsIGwgPSBtW2RwY1tpXV0uY2hpbGRyZW5fZC5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1bbVtkcGNbaV1dLmNoaWxkcmVuX2Rba11dLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZCA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQuY29uY2F0KG1bZHBjW2ldXS5jaGlsZHJlbl9kKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmKHMuaW5kZXhPZigndXAnKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBhcHBseSB1cFxuXHRcdFx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IHAuY2hpbGRyZW5fZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKCFtW3AuY2hpbGRyZW5fZFtpXV0uY2hpbGRyZW4ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGNoZC5wdXNoKG1bcC5jaGlsZHJlbl9kW2ldXS5wYXJlbnQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRjaGQgPSAkLnZha2F0YS5hcnJheV91bmlxdWUoY2hkKTtcblx0XHRcdFx0XHRcdFx0XHRmb3IoayA9IDAsIGwgPSBjaGQubGVuZ3RoOyBrIDwgbDsgaysrKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwID0gbVtjaGRba11dO1xuXHRcdFx0XHRcdFx0XHRcdFx0d2hpbGUocCAmJiBwLmlkICE9PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGMgPSAwO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBwLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGMgKz0gbVtwLmNoaWxkcmVuW2ldXS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZihjID09PSBqKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZC5wdXNoKHAuaWQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRtcCA9IHRoaXMuZ2V0X25vZGUocCwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYodG1wICYmIHRtcC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgdHJ1ZSkuYWRkQ2xhc3MoIHQgPyAnanN0cmVlLWNsaWNrZWQnIDogJ2pzdHJlZS1jaGVja2VkJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHAgPSB0aGlzLmdldF9ub2RlKHAucGFyZW50KTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkID0gJC52YWthdGEuYXJyYXlfdW5pcXVlKHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQpO1xuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHRcdC5vbih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24gPyAnc2VsZWN0X25vZGUuanN0cmVlJyA6ICdjaGVja19ub2RlLmpzdHJlZScsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBzZWxmID0gdGhpcyxcblx0XHRcdFx0XHRcdFx0XHRvYmogPSBkYXRhLm5vZGUsXG5cdFx0XHRcdFx0XHRcdFx0bSA9IHRoaXMuX21vZGVsLmRhdGEsXG5cdFx0XHRcdFx0XHRcdFx0cGFyID0gdGhpcy5nZXRfbm9kZShvYmoucGFyZW50KSxcblx0XHRcdFx0XHRcdFx0XHRpLCBqLCBjLCB0bXAsIHMgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LmNhc2NhZGUsIHQgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24sXG5cdFx0XHRcdFx0XHRcdFx0c2VsID0ge30sIGN1ciA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQ7XG5cblx0XHRcdFx0XHRcdFx0Zm9yIChpID0gMCwgaiA9IGN1ci5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRzZWxbY3VyW2ldXSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyBhcHBseSBkb3duXG5cdFx0XHRcdFx0XHRcdGlmKHMuaW5kZXhPZignZG93bicpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdC8vdGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZCA9ICQudmFrYXRhLmFycmF5X3VuaXF1ZSh0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkLmNvbmNhdChvYmouY2hpbGRyZW5fZCkpO1xuXHRcdFx0XHRcdFx0XHRcdHZhciBzZWxlY3RlZElkcyA9IHRoaXMuX2Nhc2NhZGVfbmV3X2NoZWNrZWRfc3RhdGUob2JqLmlkLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0XHR2YXIgdGVtcCA9IG9iai5jaGlsZHJlbl9kLmNvbmNhdChvYmouaWQpO1xuXHRcdFx0XHRcdFx0XHRcdGZvciAoaSA9IDAsIGogPSB0ZW1wLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdGVkSWRzLmluZGV4T2YodGVtcFtpXSkgPiAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRzZWxbdGVtcFtpXV0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGRlbGV0ZSBzZWxbdGVtcFtpXV07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Ly8gYXBwbHkgdXBcblx0XHRcdFx0XHRcdFx0aWYocy5pbmRleE9mKCd1cCcpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlKHBhciAmJiBwYXIuaWQgIT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGMgPSAwO1xuXHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gcGFyLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRjICs9IG1bcGFyLmNoaWxkcmVuW2ldXS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdGlmKGMgPT09IGopIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cGFyLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0c2VsW3Bhci5pZF0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQvL3RoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQucHVzaChwYXIuaWQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKHBhciwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKHRtcCAmJiB0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKS5hZGRDbGFzcyh0ID8gJ2pzdHJlZS1jbGlja2VkJyA6ICdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRwYXIgPSB0aGlzLmdldF9ub2RlKHBhci5wYXJlbnQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGN1ciA9IFtdO1xuXHRcdFx0XHRcdFx0XHRmb3IgKGkgaW4gc2VsKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHNlbC5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3VyLnB1c2goaSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQgPSBjdXI7XG5cdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdFx0Lm9uKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiA/ICdkZXNlbGVjdF9hbGwuanN0cmVlJyA6ICd1bmNoZWNrX2FsbC5qc3RyZWUnLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0XHR2YXIgb2JqID0gdGhpcy5nZXRfbm9kZSgkLmpzdHJlZS5yb290KSxcblx0XHRcdFx0XHRcdFx0XHRtID0gdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0XHRcdFx0XHRpLCBqLCB0bXA7XG5cdFx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZHJlbl9kLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdHRtcCA9IG1bb2JqLmNoaWxkcmVuX2RbaV1dO1xuXHRcdFx0XHRcdFx0XHRcdGlmKHRtcCAmJiB0bXAub3JpZ2luYWwgJiYgdG1wLm9yaWdpbmFsLnN0YXRlICYmIHRtcC5vcmlnaW5hbC5zdGF0ZS51bmRldGVybWluZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5vcmlnaW5hbC5zdGF0ZS51bmRldGVybWluZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0XHQub24odGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uID8gJ2Rlc2VsZWN0X25vZGUuanN0cmVlJyA6ICd1bmNoZWNrX25vZGUuanN0cmVlJywgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHNlbGYgPSB0aGlzLFxuXHRcdFx0XHRcdFx0XHRcdG9iaiA9IGRhdGEubm9kZSxcblx0XHRcdFx0XHRcdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSksXG5cdFx0XHRcdFx0XHRcdFx0aSwgaiwgdG1wLCBzID0gdGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlLCB0ID0gdGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uLFxuXHRcdFx0XHRcdFx0XHRcdGN1ciA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQsIHNlbCA9IHt9LFxuXHRcdFx0XHRcdFx0XHRcdHN0aWxsU2VsZWN0ZWRJZHMgPSBbXSxcblx0XHRcdFx0XHRcdFx0XHRhbGxJZHMgPSBvYmouY2hpbGRyZW5fZC5jb25jYXQob2JqLmlkKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBhcHBseSBkb3duXG5cdFx0XHRcdFx0XHRcdGlmKHMuaW5kZXhPZignZG93bicpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBzZWxlY3RlZElkcyA9IHRoaXMuX2Nhc2NhZGVfbmV3X2NoZWNrZWRfc3RhdGUob2JqLmlkLCBmYWxzZSk7XG5cblx0XHRcdFx0XHRcdFx0XHRjdXIgPSAkLnZha2F0YS5hcnJheV9maWx0ZXIoY3VyLCBmdW5jdGlvbihpZCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGFsbElkcy5pbmRleE9mKGlkKSA9PT0gLTEgfHwgc2VsZWN0ZWRJZHMuaW5kZXhPZihpZCkgPiAtMTtcblx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIG9ubHkgYXBwbHkgdXAgaWYgY2FzY2FkZSB1cCBpcyBlbmFibGVkIGFuZCBpZiB0aGlzIG5vZGUgaXMgbm90IHNlbGVjdGVkXG5cdFx0XHRcdFx0XHRcdC8vIChpZiBhbGwgY2hpbGQgbm9kZXMgYXJlIGRpc2FibGVkIGFuZCBjYXNjYWRlX3RvX2Rpc2FibGVkID09PSBmYWxzZSB0aGVuIHRoaXMgbm9kZSB3aWxsIHRpbGwgYmUgc2VsZWN0ZWQpLlxuXHRcdFx0XHRcdFx0XHRpZihzLmluZGV4T2YoJ3VwJykgIT09IC0xICYmIGN1ci5pbmRleE9mKG9iai5pZCkgPT09IC0xKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLnBhcmVudHMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0aGlzLl9tb2RlbC5kYXRhW29iai5wYXJlbnRzW2ldXTtcblx0XHRcdFx0XHRcdFx0XHRcdHRtcC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYodG1wICYmIHRtcC5vcmlnaW5hbCAmJiB0bXAub3JpZ2luYWwuc3RhdGUgJiYgdG1wLm9yaWdpbmFsLnN0YXRlLnVuZGV0ZXJtaW5lZCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKG9iai5wYXJlbnRzW2ldLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKHRtcCAmJiB0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgZmFsc2UpLnJlbW92ZUNsYXNzKHQgPyAnanN0cmVlLWNsaWNrZWQnIDogJ2pzdHJlZS1jaGVja2VkJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0Y3VyID0gJC52YWthdGEuYXJyYXlfZmlsdGVyKGN1ciwgZnVuY3Rpb24oaWQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBvYmoucGFyZW50cy5pbmRleE9mKGlkKSA9PT0gLTE7XG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkID0gY3VyO1xuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3guY2FzY2FkZS5pbmRleE9mKCd1cCcpICE9PSAtMSkge1xuXHRcdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0XHQub24oJ2RlbGV0ZV9ub2RlLmpzdHJlZScsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHRcdC8vIGFwcGx5IHVwICh3aG9sZSBoYW5kbGVyKVxuXHRcdFx0XHRcdFx0XHR2YXIgcCA9IHRoaXMuZ2V0X25vZGUoZGF0YS5wYXJlbnQpLFxuXHRcdFx0XHRcdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRcdFx0XHRcdGksIGosIGMsIHRtcCwgdCA9IHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbjtcblx0XHRcdFx0XHRcdFx0d2hpbGUocCAmJiBwLmlkICE9PSAkLmpzdHJlZS5yb290ICYmICFwLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdKSB7XG5cdFx0XHRcdFx0XHRcdFx0YyA9IDA7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gcC5jaGlsZHJlbi5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0XHRcdGMgKz0gbVtwLmNoaWxkcmVuW2ldXS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aWYoaiA+IDAgJiYgYyA9PT0gaikge1xuXHRcdFx0XHRcdFx0XHRcdFx0cC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkLnB1c2gocC5pZCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKHAsIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYodG1wICYmIHRtcC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKS5hZGRDbGFzcyh0ID8gJ2pzdHJlZS1jbGlja2VkJyA6ICdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRwID0gdGhpcy5nZXRfbm9kZShwLnBhcmVudCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0XHQub24oJ21vdmVfbm9kZS5qc3RyZWUnLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0XHQvLyBhcHBseSB1cCAod2hvbGUgaGFuZGxlcilcblx0XHRcdFx0XHRcdFx0dmFyIGlzX211bHRpID0gZGF0YS5pc19tdWx0aSxcblx0XHRcdFx0XHRcdFx0XHRvbGRfcGFyID0gZGF0YS5vbGRfcGFyZW50LFxuXHRcdFx0XHRcdFx0XHRcdG5ld19wYXIgPSB0aGlzLmdldF9ub2RlKGRhdGEucGFyZW50KSxcblx0XHRcdFx0XHRcdFx0XHRtID0gdGhpcy5fbW9kZWwuZGF0YSxcblx0XHRcdFx0XHRcdFx0XHRwLCBjLCBpLCBqLCB0bXAsIHQgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb247XG5cdFx0XHRcdFx0XHRcdGlmKCFpc19tdWx0aSkge1xuXHRcdFx0XHRcdFx0XHRcdHAgPSB0aGlzLmdldF9ub2RlKG9sZF9wYXIpO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlKHAgJiYgcC5pZCAhPT0gJC5qc3RyZWUucm9vdCAmJiAhcC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0YyA9IDA7XG5cdFx0XHRcdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBwLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRjICs9IG1bcC5jaGlsZHJlbltpXV0uc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRpZihqID4gMCAmJiBjID09PSBqKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHAuc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkLnB1c2gocC5pZCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRtcCA9IHRoaXMuZ2V0X25vZGUocCwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKHRtcCAmJiB0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKS5hZGRDbGFzcyh0ID8gJ2pzdHJlZS1jbGlja2VkJyA6ICdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRwID0gdGhpcy5nZXRfbm9kZShwLnBhcmVudCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHAgPSBuZXdfcGFyO1xuXHRcdFx0XHRcdFx0XHR3aGlsZShwICYmIHAuaWQgIT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRcdFx0XHRjID0gMDtcblx0XHRcdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBwLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdFx0YyArPSBtW3AuY2hpbGRyZW5baV1dLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRpZihjID09PSBqKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZighcC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRwLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZC5wdXNoKHAuaWQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKHAsIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZih0bXAgJiYgdG1wLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRtcC5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgdHJ1ZSkuYWRkQ2xhc3ModCA/ICdqc3RyZWUtY2xpY2tlZCcgOiAnanN0cmVlLWNoZWNrZWQnKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKHAuc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF0pIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cC5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhWyB0ID8gJ2NvcmUnIDogJ2NoZWNrYm94JyBdLnNlbGVjdGVkID0gJC52YWthdGEuYXJyYXlfcmVtb3ZlX2l0ZW0odGhpcy5fZGF0YVsgdCA/ICdjb3JlJyA6ICdjaGVja2JveCcgXS5zZWxlY3RlZCwgcC5pZCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRtcCA9IHRoaXMuZ2V0X25vZGUocCwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKHRtcCAmJiB0bXAubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dG1wLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSkucmVtb3ZlQ2xhc3ModCA/ICdqc3RyZWUtY2xpY2tlZCcgOiAnanN0cmVlLWNoZWNrZWQnKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRwID0gdGhpcy5nZXRfbm9kZShwLnBhcmVudCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHQvKipcblx0XHQgKiBnZXQgYW4gYXJyYXkgb2YgYWxsIG5vZGVzIHdob3NlIHN0YXRlIGlzIFwidW5kZXRlcm1pbmVkXCJcblx0XHQgKiBAbmFtZSBnZXRfdW5kZXRlcm1pbmVkKFtmdWxsXSlcblx0XHQgKiBAcGFyYW0gIHtib29sZWFufSBmdWxsOiBpZiBzZXQgdG8gYHRydWVgIHRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGNvbnNpc3Qgb2YgdGhlIGZ1bGwgbm9kZSBvYmplY3RzLCBvdGhlcndpc2UgLSBvbmx5IElEcyB3aWxsIGJlIHJldHVybmVkXG5cdFx0ICogQHJldHVybiB7QXJyYXl9XG5cdFx0ICogQHBsdWdpbiBjaGVja2JveFxuXHRcdCAqL1xuXHRcdHRoaXMuZ2V0X3VuZGV0ZXJtaW5lZCA9IGZ1bmN0aW9uIChmdWxsKSB7XG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlLmluZGV4T2YoJ3VuZGV0ZXJtaW5lZCcpID09PSAtMSkge1xuXHRcdFx0XHRyZXR1cm4gW107XG5cdFx0XHR9XG5cdFx0XHR2YXIgaSwgaiwgaywgbCwgbyA9IHt9LCBtID0gdGhpcy5fbW9kZWwuZGF0YSwgdCA9IHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiwgcyA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQsIHAgPSBbXSwgdHQgPSB0aGlzLCByID0gW107XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRpZihtW3NbaV1dICYmIG1bc1tpXV0ucGFyZW50cykge1xuXHRcdFx0XHRcdGZvcihrID0gMCwgbCA9IG1bc1tpXV0ucGFyZW50cy5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRcdGlmKG9bbVtzW2ldXS5wYXJlbnRzW2tdXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYobVtzW2ldXS5wYXJlbnRzW2tdICE9PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdFx0XHRcdG9bbVtzW2ldXS5wYXJlbnRzW2tdXSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdHAucHVzaChtW3NbaV1dLnBhcmVudHNba10pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gYXR0ZW1wdCBmb3Igc2VydmVyIHNpZGUgdW5kZXRlcm1pbmVkIHN0YXRlXG5cdFx0XHR0aGlzLmVsZW1lbnQuZmluZCgnLmpzdHJlZS1jbG9zZWQnKS5ub3QoJzpoYXMoLmpzdHJlZS1jaGlsZHJlbiknKVxuXHRcdFx0XHQuZWFjaChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHRtcCA9IHR0LmdldF9ub2RlKHRoaXMpLCB0bXAyO1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdGlmKCF0bXApIHsgcmV0dXJuOyB9XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0aWYoIXRtcC5zdGF0ZS5sb2FkZWQpIHtcblx0XHRcdFx0XHRcdGlmKHRtcC5vcmlnaW5hbCAmJiB0bXAub3JpZ2luYWwuc3RhdGUgJiYgdG1wLm9yaWdpbmFsLnN0YXRlLnVuZGV0ZXJtaW5lZCAmJiB0bXAub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGlmKG9bdG1wLmlkXSA9PT0gdW5kZWZpbmVkICYmIHRtcC5pZCAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRcdFx0XHRcdG9bdG1wLmlkXSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0cC5wdXNoKHRtcC5pZCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wLnBhcmVudHMubGVuZ3RoOyBrIDwgbDsgaysrKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYob1t0bXAucGFyZW50c1trXV0gPT09IHVuZGVmaW5lZCAmJiB0bXAucGFyZW50c1trXSAhPT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b1t0bXAucGFyZW50c1trXV0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0cC5wdXNoKHRtcC5wYXJlbnRzW2tdKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSB0bXAuY2hpbGRyZW5fZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0dG1wMiA9IG1bdG1wLmNoaWxkcmVuX2RbaV1dO1xuXHRcdFx0XHRcdFx0XHRpZighdG1wMi5zdGF0ZS5sb2FkZWQgJiYgdG1wMi5vcmlnaW5hbCAmJiB0bXAyLm9yaWdpbmFsLnN0YXRlICYmIHRtcDIub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkICYmIHRtcDIub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYob1t0bXAyLmlkXSA9PT0gdW5kZWZpbmVkICYmIHRtcDIuaWQgIT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRcdFx0XHRcdG9bdG1wMi5pZF0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0cC5wdXNoKHRtcDIuaWQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRmb3IoayA9IDAsIGwgPSB0bXAyLnBhcmVudHMubGVuZ3RoOyBrIDwgbDsgaysrKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZihvW3RtcDIucGFyZW50c1trXV0gPT09IHVuZGVmaW5lZCAmJiB0bXAyLnBhcmVudHNba10gIT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0b1t0bXAyLnBhcmVudHNba11dID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cC5wdXNoKHRtcDIucGFyZW50c1trXSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdGZvciAoaSA9IDAsIGogPSBwLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRpZighbVtwW2ldXS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSkge1xuXHRcdFx0XHRcdHIucHVzaChmdWxsID8gbVtwW2ldXSA6IHBbaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcjtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHNldCB0aGUgdW5kZXRlcm1pbmVkIHN0YXRlIHdoZXJlIGFuZCBpZiBuZWNlc3NhcnkuIFVzZWQgaW50ZXJuYWxseS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqIEBuYW1lIF91bmRldGVybWluZWQoKVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLl91bmRldGVybWluZWQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpZih0aGlzLmVsZW1lbnQgPT09IG51bGwpIHsgcmV0dXJuOyB9XG5cdFx0XHR2YXIgcCA9IHRoaXMuZ2V0X3VuZGV0ZXJtaW5lZChmYWxzZSksIGksIGosIHM7XG5cblx0XHRcdHRoaXMuZWxlbWVudC5maW5kKCcuanN0cmVlLXVuZGV0ZXJtaW5lZCcpLnJlbW92ZUNsYXNzKCdqc3RyZWUtdW5kZXRlcm1pbmVkJyk7XG5cdFx0XHRmb3IgKGkgPSAwLCBqID0gcC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0cyA9IHRoaXMuZ2V0X25vZGUocFtpXSwgdHJ1ZSk7XG5cdFx0XHRcdGlmKHMgJiYgcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRzLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmNoaWxkcmVuKCcuanN0cmVlLWNoZWNrYm94JykuYWRkQ2xhc3MoJ2pzdHJlZS11bmRldGVybWluZWQnKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdFx0dGhpcy5yZWRyYXdfbm9kZSA9IGZ1bmN0aW9uKG9iaiwgZGVlcCwgaXNfY2FsbGJhY2ssIGZvcmNlX3JlbmRlcikge1xuXHRcdFx0b2JqID0gcGFyZW50LnJlZHJhd19ub2RlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0XHRpZihvYmopIHtcblx0XHRcdFx0dmFyIGksIGosIHRtcCA9IG51bGwsIGljb24gPSBudWxsO1xuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGROb2Rlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRpZihvYmouY2hpbGROb2Rlc1tpXSAmJiBvYmouY2hpbGROb2Rlc1tpXS5jbGFzc05hbWUgJiYgb2JqLmNoaWxkTm9kZXNbaV0uY2xhc3NOYW1lLmluZGV4T2YoXCJqc3RyZWUtYW5jaG9yXCIpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0dG1wID0gb2JqLmNoaWxkTm9kZXNbaV07XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYodG1wKSB7XG5cdFx0XHRcdFx0aWYoIXRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiAmJiB0aGlzLl9tb2RlbC5kYXRhW29iai5pZF0uc3RhdGUuY2hlY2tlZCkgeyB0bXAuY2xhc3NOYW1lICs9ICcganN0cmVlLWNoZWNrZWQnOyB9XG5cdFx0XHRcdFx0aWNvbiA9IF9pLmNsb25lTm9kZShmYWxzZSk7XG5cdFx0XHRcdFx0aWYodGhpcy5fbW9kZWwuZGF0YVtvYmouaWRdLnN0YXRlLmNoZWNrYm94X2Rpc2FibGVkKSB7IGljb24uY2xhc3NOYW1lICs9ICcganN0cmVlLWNoZWNrYm94LWRpc2FibGVkJzsgfVxuXHRcdFx0XHRcdHRtcC5pbnNlcnRCZWZvcmUoaWNvbiwgdG1wLmNoaWxkTm9kZXNbMF0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZighaXNfY2FsbGJhY2sgJiYgdGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlLmluZGV4T2YoJ3VuZGV0ZXJtaW5lZCcpICE9PSAtMSkge1xuXHRcdFx0XHRpZih0aGlzLl9kYXRhLmNoZWNrYm94LnV0bykgeyBjbGVhclRpbWVvdXQodGhpcy5fZGF0YS5jaGVja2JveC51dG8pOyB9XG5cdFx0XHRcdHRoaXMuX2RhdGEuY2hlY2tib3gudXRvID0gc2V0VGltZW91dCh0aGlzLl91bmRldGVybWluZWQuYmluZCh0aGlzKSwgNTApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9iajtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHNob3cgdGhlIG5vZGUgY2hlY2tib3ggaWNvbnNcblx0XHQgKiBAbmFtZSBzaG93X2NoZWNrYm94ZXMoKVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLnNob3dfY2hlY2tib3hlcyA9IGZ1bmN0aW9uICgpIHsgdGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5jaGVja2JveGVzID0gdHJ1ZTsgdGhpcy5nZXRfY29udGFpbmVyX3VsKCkucmVtb3ZlQ2xhc3MoXCJqc3RyZWUtbm8tY2hlY2tib3hlc1wiKTsgfTtcblx0XHQvKipcblx0XHQgKiBoaWRlIHRoZSBub2RlIGNoZWNrYm94IGljb25zXG5cdFx0ICogQG5hbWUgaGlkZV9jaGVja2JveGVzKClcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy5oaWRlX2NoZWNrYm94ZXMgPSBmdW5jdGlvbiAoKSB7IHRoaXMuX2RhdGEuY29yZS50aGVtZXMuY2hlY2tib3hlcyA9IGZhbHNlOyB0aGlzLmdldF9jb250YWluZXJfdWwoKS5hZGRDbGFzcyhcImpzdHJlZS1uby1jaGVja2JveGVzXCIpOyB9O1xuXHRcdC8qKlxuXHRcdCAqIHRvZ2dsZSB0aGUgbm9kZSBpY29uc1xuXHRcdCAqIEBuYW1lIHRvZ2dsZV9jaGVja2JveGVzKClcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy50b2dnbGVfY2hlY2tib3hlcyA9IGZ1bmN0aW9uICgpIHsgaWYodGhpcy5fZGF0YS5jb3JlLnRoZW1lcy5jaGVja2JveGVzKSB7IHRoaXMuaGlkZV9jaGVja2JveGVzKCk7IH0gZWxzZSB7IHRoaXMuc2hvd19jaGVja2JveGVzKCk7IH0gfTtcblx0XHQvKipcblx0XHQgKiBjaGVja3MgaWYgYSBub2RlIGlzIGluIGFuIHVuZGV0ZXJtaW5lZCBzdGF0ZVxuXHRcdCAqIEBuYW1lIGlzX3VuZGV0ZXJtaW5lZChvYmopXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9IG9ialxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59XG5cdFx0ICovXG5cdFx0dGhpcy5pc191bmRldGVybWluZWQgPSBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHR2YXIgcyA9IHRoaXMuc2V0dGluZ3MuY2hlY2tib3guY2FzY2FkZSwgaSwgaiwgdCA9IHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiwgZCA9IHRoaXMuX2RhdGFbIHQgPyAnY29yZScgOiAnY2hlY2tib3gnIF0uc2VsZWN0ZWQsIG0gPSB0aGlzLl9tb2RlbC5kYXRhO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouc3RhdGVbIHQgPyAnc2VsZWN0ZWQnIDogJ2NoZWNrZWQnIF0gPT09IHRydWUgfHwgcy5pbmRleE9mKCd1bmRldGVybWluZWQnKSA9PT0gLTEgfHwgKHMuaW5kZXhPZignZG93bicpID09PSAtMSAmJiBzLmluZGV4T2YoJ3VwJykgPT09IC0xKSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRpZighb2JqLnN0YXRlLmxvYWRlZCAmJiBvYmoub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkID09PSB0cnVlKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLmNoaWxkcmVuX2QubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKCQuaW5BcnJheShvYmouY2hpbGRyZW5fZFtpXSwgZCkgIT09IC0xIHx8ICghbVtvYmouY2hpbGRyZW5fZFtpXV0uc3RhdGUubG9hZGVkICYmIG1bb2JqLmNoaWxkcmVuX2RbaV1dLm9yaWdpbmFsLnN0YXRlLnVuZGV0ZXJtaW5lZCkpIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogZGlzYWJsZSBhIG5vZGUncyBjaGVja2JveFxuXHRcdCAqIEBuYW1lIGRpc2FibGVfY2hlY2tib3gob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiBhbiBhcnJheSBjYW4gYmUgdXNlZCB0b29cblx0XHQgKiBAdHJpZ2dlciBkaXNhYmxlX2NoZWNrYm94LmpzdHJlZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLmRpc2FibGVfY2hlY2tib3ggPSBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHR2YXIgdDEsIHQyLCBkb207XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLmRpc2FibGVfY2hlY2tib3gob2JqW3QxXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSk7XG5cdFx0XHRpZighb2JqLnN0YXRlLmNoZWNrYm94X2Rpc2FibGVkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5jaGVja2JveF9kaXNhYmxlZCA9IHRydWU7XG5cdFx0XHRcdGlmKGRvbSAmJiBkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZG9tLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmNoaWxkcmVuKCcuanN0cmVlLWNoZWNrYm94JykuYWRkQ2xhc3MoJ2pzdHJlZS1jaGVja2JveC1kaXNhYmxlZCcpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlJ3MgY2hlY2tib3ggaXMgZGlzYWJsZWRcblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIGRpc2FibGVfY2hlY2tib3guanN0cmVlXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHRcdFx0ICovXG5cdFx0XHRcdHRoaXMudHJpZ2dlcignZGlzYWJsZV9jaGVja2JveCcsIHsgJ25vZGUnIDogb2JqIH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogZW5hYmxlIGEgbm9kZSdzIGNoZWNrYm94XG5cdFx0ICogQG5hbWUgZW5hYmxlX2NoZWNrYm94KG9iailcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogYW4gYXJyYXkgY2FuIGJlIHVzZWQgdG9vXG5cdFx0ICogQHRyaWdnZXIgZW5hYmxlX2NoZWNrYm94LmpzdHJlZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLmVuYWJsZV9jaGVja2JveCA9IGZ1bmN0aW9uIChvYmopIHtcblx0XHRcdHZhciB0MSwgdDIsIGRvbTtcblx0XHRcdGlmKCQudmFrYXRhLmlzX2FycmF5KG9iaikpIHtcblx0XHRcdFx0b2JqID0gb2JqLnNsaWNlKCk7XG5cdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gb2JqLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdHRoaXMuZW5hYmxlX2NoZWNrYm94KG9ialt0MV0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0ZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0aWYob2JqLnN0YXRlLmNoZWNrYm94X2Rpc2FibGVkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5jaGVja2JveF9kaXNhYmxlZCA9IGZhbHNlO1xuXHRcdFx0XHRpZihkb20gJiYgZG9tLmxlbmd0aCkge1xuXHRcdFx0XHRcdGRvbS5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5jaGlsZHJlbignLmpzdHJlZS1jaGVja2JveCcpLnJlbW92ZUNsYXNzKCdqc3RyZWUtY2hlY2tib3gtZGlzYWJsZWQnKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gYW4gbm9kZSdzIGNoZWNrYm94IGlzIGVuYWJsZWRcblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIGVuYWJsZV9jaGVja2JveC5qc3RyZWVcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVcblx0XHRcdFx0ICogQHBsdWdpbiBjaGVja2JveFxuXHRcdFx0XHQgKi9cblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdlbmFibGVfY2hlY2tib3gnLCB7ICdub2RlJyA6IG9iaiB9KTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5hY3RpdmF0ZV9ub2RlID0gZnVuY3Rpb24gKG9iaiwgZSkge1xuXHRcdFx0aWYoJChlLnRhcmdldCkuaGFzQ2xhc3MoJ2pzdHJlZS1jaGVja2JveC1kaXNhYmxlZCcpKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiAmJiAodGhpcy5zZXR0aW5ncy5jaGVja2JveC53aG9sZV9ub2RlIHx8ICQoZS50YXJnZXQpLmhhc0NsYXNzKCdqc3RyZWUtY2hlY2tib3gnKSkpIHtcblx0XHRcdFx0ZS5jdHJsS2V5ID0gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbiB8fCAoIXRoaXMuc2V0dGluZ3MuY2hlY2tib3gud2hvbGVfbm9kZSAmJiAhJChlLnRhcmdldCkuaGFzQ2xhc3MoJ2pzdHJlZS1jaGVja2JveCcpKSkge1xuXHRcdFx0XHRyZXR1cm4gcGFyZW50LmFjdGl2YXRlX25vZGUuY2FsbCh0aGlzLCBvYmosIGUpO1xuXHRcdFx0fVxuXHRcdFx0aWYodGhpcy5pc19kaXNhYmxlZChvYmopKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGlmKHRoaXMuaXNfY2hlY2tlZChvYmopKSB7XG5cdFx0XHRcdHRoaXMudW5jaGVja19ub2RlKG9iaiwgZSk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0dGhpcy5jaGVja19ub2RlKG9iaiwgZSk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnRyaWdnZXIoJ2FjdGl2YXRlX25vZGUnLCB7ICdub2RlJyA6IHRoaXMuZ2V0X25vZGUob2JqKSB9KTtcblx0XHR9O1xuXHRcdHRoaXMuZGVsZXRlX25vZGUgPSBmdW5jdGlvbiAob2JqKSB7XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24gfHwgJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRyZXR1cm4gcGFyZW50LmRlbGV0ZV9ub2RlKG9iaik7XG5cdFx0XHR9XG5cdFx0XHR2YXIgdG1wLCBrLCBsLCBjID0gZmFsc2U7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighb2JqIHx8IG9iai5pZCA9PT0gJC5qc3RyZWUucm9vdCkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHRtcCA9IG9iai5jaGlsZHJlbl9kLmNvbmNhdChbXSk7XG5cdFx0XHR0bXAucHVzaChvYmouaWQpO1xuXHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wLmxlbmd0aDsgayA8IGw7IGsrKykge1xuXHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW3RtcFtrXV0uc3RhdGUuY2hlY2tlZCkge1xuXHRcdFx0XHRcdGMgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoYykge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkID0gJC52YWthdGEuYXJyYXlfZmlsdGVyKHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQsIGZ1bmN0aW9uICh2KSB7XG5cdFx0XHRcdFx0cmV0dXJuICQuaW5BcnJheSh2LCB0bXApID09PSAtMTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcGFyZW50LmRlbGV0ZV9ub2RlLmNhbGwodGhpcywgb2JqKTtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogQ2FzY2FkZXMgY2hlY2tlZCBzdGF0ZSB0byBhIG5vZGUgYW5kIGFsbCBpdHMgZGVzY2VuZGFudHMuIFRoaXMgZnVuY3Rpb24gZG9lcyBOT1QgYWZmZWN0IGhpZGRlbiBhbmQgZGlzYWJsZWQgbm9kZXMgKG9yIHRoZWlyIGRlc2NlbmRhbnRzKS5cblx0XHQgKiBIb3dldmVyIGlmIHRoZXNlIHVuYWZmZWN0ZWQgbm9kZXMgYXJlIGFscmVhZHkgc2VsZWN0ZWQgdGhlaXIgaWRzIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIHJldHVybmVkIGFycmF5LlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICogQG5hbWUgX2Nhc2NhZGVfbmV3X2NoZWNrZWRfc3RhdGUoaWQsIGNoZWNrZWRTdGF0ZSlcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gaWQgdGhlIG5vZGUgSURcblx0XHQgKiBAcGFyYW0ge2Jvb2x9IGNoZWNrZWRTdGF0ZSBzaG91bGQgdGhlIG5vZGVzIGJlIGNoZWNrZWQgb3Igbm90XG5cdFx0ICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBhbGwgbm9kZSBpZCdzIChpbiB0aGlzIHRyZWUgYnJhbmNoKSB0aGF0IGFyZSBjaGVja2VkLlxuXHRcdCAqL1xuXHRcdHRoaXMuX2Nhc2NhZGVfbmV3X2NoZWNrZWRfc3RhdGUgPSBmdW5jdGlvbiAoaWQsIGNoZWNrZWRTdGF0ZSkge1xuXHRcdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdFx0dmFyIHQgPSB0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb247XG5cdFx0XHR2YXIgbm9kZSA9IHRoaXMuX21vZGVsLmRhdGFbaWRdO1xuXHRcdFx0dmFyIHNlbGVjdGVkTm9kZUlkcyA9IFtdO1xuXHRcdFx0dmFyIHNlbGVjdGVkQ2hpbGRyZW5JZHMgPSBbXSwgaSwgaiwgc2VsZWN0ZWRDaGlsZElkcztcblxuXHRcdFx0aWYgKFxuXHRcdFx0XHQodGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlX3RvX2Rpc2FibGVkIHx8ICFub2RlLnN0YXRlLmRpc2FibGVkKSAmJlxuXHRcdFx0XHQodGhpcy5zZXR0aW5ncy5jaGVja2JveC5jYXNjYWRlX3RvX2hpZGRlbiB8fCAhbm9kZS5zdGF0ZS5oaWRkZW4pXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly9GaXJzdCB0cnkgYW5kIGNoZWNrL3VuY2hlY2sgdGhlIGNoaWxkcmVuXG5cdFx0XHRcdGlmIChub2RlLmNoaWxkcmVuKSB7XG5cdFx0XHRcdFx0Zm9yIChpID0gMCwgaiA9IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHR2YXIgY2hpbGRJZCA9IG5vZGUuY2hpbGRyZW5baV07XG5cdFx0XHRcdFx0XHRzZWxlY3RlZENoaWxkSWRzID0gc2VsZi5fY2FzY2FkZV9uZXdfY2hlY2tlZF9zdGF0ZShjaGlsZElkLCBjaGVja2VkU3RhdGUpO1xuXHRcdFx0XHRcdFx0c2VsZWN0ZWROb2RlSWRzID0gc2VsZWN0ZWROb2RlSWRzLmNvbmNhdChzZWxlY3RlZENoaWxkSWRzKTtcblx0XHRcdFx0XHRcdGlmIChzZWxlY3RlZENoaWxkSWRzLmluZGV4T2YoY2hpbGRJZCkgPiAtMSkge1xuXHRcdFx0XHRcdFx0XHRzZWxlY3RlZENoaWxkcmVuSWRzLnB1c2goY2hpbGRJZCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dmFyIGRvbSA9IHNlbGYuZ2V0X25vZGUobm9kZSwgdHJ1ZSk7XG5cblx0XHRcdFx0Ly9BIG5vZGUncyBzdGF0ZSBpcyB1bmRldGVybWluZWQgaWYgc29tZSBidXQgbm90IGFsbCBvZiBpdCdzIGNoaWxkcmVuIGFyZSBjaGVja2VkL3NlbGVjdGVkIC5cblx0XHRcdFx0dmFyIHVuZGV0ZXJtaW5lZCA9IHNlbGVjdGVkQ2hpbGRyZW5JZHMubGVuZ3RoID4gMCAmJiBzZWxlY3RlZENoaWxkcmVuSWRzLmxlbmd0aCA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoO1xuXG5cdFx0XHRcdGlmKG5vZGUub3JpZ2luYWwgJiYgbm9kZS5vcmlnaW5hbC5zdGF0ZSAmJiBub2RlLm9yaWdpbmFsLnN0YXRlLnVuZGV0ZXJtaW5lZCkge1xuXHRcdFx0XHRcdG5vZGUub3JpZ2luYWwuc3RhdGUudW5kZXRlcm1pbmVkID0gdW5kZXRlcm1pbmVkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9JZiBhIG5vZGUgaXMgdW5kZXRlcm1pbmVkIHRoZW4gcmVtb3ZlIHNlbGVjdGVkIGNsYXNzXG5cdFx0XHRcdGlmICh1bmRldGVybWluZWQpIHtcblx0XHRcdFx0XHRub2RlLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gZmFsc2U7XG5cdFx0XHRcdFx0ZG9tLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSkucmVtb3ZlQ2xhc3ModCA/ICdqc3RyZWUtY2xpY2tlZCcgOiAnanN0cmVlLWNoZWNrZWQnKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvL090aGVyd2lzZSwgaWYgdGhlIGNoZWNrZWRTdGF0ZSA9PT0gdHJ1ZSAoaS5lLiB0aGUgbm9kZSBpcyBiZWluZyBjaGVja2VkIG5vdykgYW5kIGFsbCBvZiB0aGUgbm9kZSdzIGNoaWxkcmVuIGFyZSBjaGVja2VkIChpZiBpdCBoYXMgYW55IGNoaWxkcmVuKSxcblx0XHRcdFx0Ly9jaGVjayB0aGUgbm9kZSBhbmQgc3R5bGUgaXQgY29ycmVjdGx5LlxuXHRcdFx0XHRlbHNlIGlmIChjaGVja2VkU3RhdGUgJiYgc2VsZWN0ZWRDaGlsZHJlbklkcy5sZW5ndGggPT09IG5vZGUuY2hpbGRyZW4ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0bm9kZS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSA9IGNoZWNrZWRTdGF0ZTtcblx0XHRcdFx0XHRzZWxlY3RlZE5vZGVJZHMucHVzaChub2RlLmlkKTtcblxuXHRcdFx0XHRcdGRvbS5jaGlsZHJlbignLmpzdHJlZS1hbmNob3InKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgdHJ1ZSkuYWRkQ2xhc3ModCA/ICdqc3RyZWUtY2xpY2tlZCcgOiAnanN0cmVlLWNoZWNrZWQnKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRub2RlLnN0YXRlWyB0ID8gJ3NlbGVjdGVkJyA6ICdjaGVja2VkJyBdID0gZmFsc2U7XG5cdFx0XHRcdFx0ZG9tLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSkucmVtb3ZlQ2xhc3ModCA/ICdqc3RyZWUtY2xpY2tlZCcgOiAnanN0cmVlLWNoZWNrZWQnKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdHNlbGVjdGVkQ2hpbGRJZHMgPSB0aGlzLmdldF9jaGVja2VkX2Rlc2NlbmRhbnRzKGlkKTtcblxuXHRcdFx0XHRpZiAobm9kZS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXSkge1xuXHRcdFx0XHRcdHNlbGVjdGVkQ2hpbGRJZHMucHVzaChub2RlLmlkKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNlbGVjdGVkTm9kZUlkcyA9IHNlbGVjdGVkTm9kZUlkcy5jb25jYXQoc2VsZWN0ZWRDaGlsZElkcyk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBzZWxlY3RlZE5vZGVJZHM7XG5cdFx0fTtcblxuXHRcdC8qKlxuXHRcdCAqIEdldHMgaWRzIG9mIG5vZGVzIHNlbGVjdGVkIGluIGJyYW5jaCAob2YgdHJlZSkgc3BlY2lmaWVkIGJ5IGlkIChkb2VzIG5vdCBpbmNsdWRlIHRoZSBub2RlIHNwZWNpZmllZCBieSBpZClcblx0XHQgKiBAbmFtZSBnZXRfY2hlY2tlZF9kZXNjZW5kYW50cyhvYmopXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGlkIHRoZSBub2RlIElEXG5cdFx0ICogQHJldHVybiB7QXJyYXl9IGFycmF5IG9mIElEc1xuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLmdldF9jaGVja2VkX2Rlc2NlbmRhbnRzID0gZnVuY3Rpb24gKGlkKSB7XG5cdFx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0XHR2YXIgdCA9IHNlbGYuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbjtcblx0XHRcdHZhciBub2RlID0gc2VsZi5fbW9kZWwuZGF0YVtpZF07XG5cblx0XHRcdHJldHVybiAkLnZha2F0YS5hcnJheV9maWx0ZXIobm9kZS5jaGlsZHJlbl9kLCBmdW5jdGlvbihfaWQpIHtcblx0XHRcdFx0cmV0dXJuIHNlbGYuX21vZGVsLmRhdGFbX2lkXS5zdGF0ZVsgdCA/ICdzZWxlY3RlZCcgOiAnY2hlY2tlZCcgXTtcblx0XHRcdH0pO1xuXHRcdH07XG5cblx0XHQvKipcblx0XHQgKiBjaGVjayBhIG5vZGUgKG9ubHkgaWYgdGllX3NlbGVjdGlvbiBpbiBjaGVja2JveCBzZXR0aW5ncyBpcyBmYWxzZSwgb3RoZXJ3aXNlIHNlbGVjdF9ub2RlIHdpbGwgYmUgY2FsbGVkIGludGVybmFsbHkpXG5cdFx0ICogQG5hbWUgY2hlY2tfbm9kZShvYmopXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIGFuIGFycmF5IGNhbiBiZSB1c2VkIHRvIGNoZWNrIG11bHRpcGxlIG5vZGVzXG5cdFx0ICogQHRyaWdnZXIgY2hlY2tfbm9kZS5qc3RyZWVcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy5jaGVja19ub2RlID0gZnVuY3Rpb24gKG9iaiwgZSkge1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uKSB7IHJldHVybiB0aGlzLnNlbGVjdF9ub2RlKG9iaiwgZmFsc2UsIHRydWUsIGUpOyB9XG5cdFx0XHR2YXIgZG9tLCB0MSwgdDIsIHRoO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkob2JqKSkge1xuXHRcdFx0XHRvYmogPSBvYmouc2xpY2UoKTtcblx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBvYmoubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5jaGVja19ub2RlKG9ialt0MV0sIGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaiB8fCBvYmouaWQgPT09ICQuanN0cmVlLnJvb3QpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0ZG9tID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpO1xuXHRcdFx0aWYoIW9iai5zdGF0ZS5jaGVja2VkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5jaGVja2VkID0gdHJ1ZTtcblx0XHRcdFx0dGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZC5wdXNoKG9iai5pZCk7XG5cdFx0XHRcdGlmKGRvbSAmJiBkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZG9tLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmFkZENsYXNzKCdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlIGlzIGNoZWNrZWQgKG9ubHkgaWYgdGllX3NlbGVjdGlvbiBpbiBjaGVja2JveCBzZXR0aW5ncyBpcyBmYWxzZSlcblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBuYW1lIGNoZWNrX25vZGUuanN0cmVlXG5cdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlXG5cdFx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IHNlbGVjdGVkIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuXHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgdGhlIGV2ZW50IChpZiBhbnkpIHRoYXQgdHJpZ2dlcmVkIHRoaXMgY2hlY2tfbm9kZVxuXHRcdFx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0XHRcdCAqL1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ2NoZWNrX25vZGUnLCB7ICdub2RlJyA6IG9iaiwgJ3NlbGVjdGVkJyA6IHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQsICdldmVudCcgOiBlIH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogdW5jaGVjayBhIG5vZGUgKG9ubHkgaWYgdGllX3NlbGVjdGlvbiBpbiBjaGVja2JveCBzZXR0aW5ncyBpcyBmYWxzZSwgb3RoZXJ3aXNlIGRlc2VsZWN0X25vZGUgd2lsbCBiZSBjYWxsZWQgaW50ZXJuYWxseSlcblx0XHQgKiBAbmFtZSB1bmNoZWNrX25vZGUob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiBhbiBhcnJheSBjYW4gYmUgdXNlZCB0byB1bmNoZWNrIG11bHRpcGxlIG5vZGVzXG5cdFx0ICogQHRyaWdnZXIgdW5jaGVja19ub2RlLmpzdHJlZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLnVuY2hlY2tfbm9kZSA9IGZ1bmN0aW9uIChvYmosIGUpIHtcblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikgeyByZXR1cm4gdGhpcy5kZXNlbGVjdF9ub2RlKG9iaiwgZmFsc2UsIGUpOyB9XG5cdFx0XHR2YXIgdDEsIHQyLCBkb207XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnVuY2hlY2tfbm9kZShvYmpbdDFdLCBlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdGRvbSA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdGlmKG9iai5zdGF0ZS5jaGVja2VkKSB7XG5cdFx0XHRcdG9iai5zdGF0ZS5jaGVja2VkID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQgPSAkLnZha2F0YS5hcnJheV9yZW1vdmVfaXRlbSh0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkLCBvYmouaWQpO1xuXHRcdFx0XHRpZihkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZG9tLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLnJlbW92ZUNsYXNzKCdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbiBub2RlIGlzIHVuY2hlY2tlZCAob25seSBpZiB0aWVfc2VsZWN0aW9uIGluIGNoZWNrYm94IHNldHRpbmdzIGlzIGZhbHNlKVxuXHRcdFx0XHQgKiBAZXZlbnRcblx0XHRcdFx0ICogQG5hbWUgdW5jaGVja19ub2RlLmpzdHJlZVxuXHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZVxuXHRcdFx0XHQgKiBAcGFyYW0ge0FycmF5fSBzZWxlY3RlZCB0aGUgY3VycmVudCBzZWxlY3Rpb25cblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IHRoZSBldmVudCAoaWYgYW55KSB0aGF0IHRyaWdnZXJlZCB0aGlzIHVuY2hlY2tfbm9kZVxuXHRcdFx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0XHRcdCAqL1xuXHRcdFx0XHR0aGlzLnRyaWdnZXIoJ3VuY2hlY2tfbm9kZScsIHsgJ25vZGUnIDogb2JqLCAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCwgJ2V2ZW50JyA6IGUgfSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRcblx0XHQvKipcblx0XHQgKiBjaGVja3MgYWxsIG5vZGVzIGluIHRoZSB0cmVlIChvbmx5IGlmIHRpZV9zZWxlY3Rpb24gaW4gY2hlY2tib3ggc2V0dGluZ3MgaXMgZmFsc2UsIG90aGVyd2lzZSBzZWxlY3RfYWxsIHdpbGwgYmUgY2FsbGVkIGludGVybmFsbHkpXG5cdFx0ICogQG5hbWUgY2hlY2tfYWxsKClcblx0XHQgKiBAdHJpZ2dlciBjaGVja19hbGwuanN0cmVlLCBjaGFuZ2VkLmpzdHJlZVxuXHRcdCAqIEBwbHVnaW4gY2hlY2tib3hcblx0XHQgKi9cblx0XHR0aGlzLmNoZWNrX2FsbCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikgeyByZXR1cm4gdGhpcy5zZWxlY3RfYWxsKCk7IH1cblx0XHRcdHZhciB0bXAgPSB0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkLmNvbmNhdChbXSksIGksIGo7XG5cdFx0XHR0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkID0gdGhpcy5fbW9kZWwuZGF0YVskLmpzdHJlZS5yb290XS5jaGlsZHJlbl9kLmNvbmNhdCgpO1xuXHRcdFx0Zm9yKGkgPSAwLCBqID0gdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0aWYodGhpcy5fbW9kZWwuZGF0YVt0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkW2ldXSkge1xuXHRcdFx0XHRcdHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZFtpXV0uc3RhdGUuY2hlY2tlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMucmVkcmF3KHRydWUpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbGwgbm9kZXMgYXJlIGNoZWNrZWQgKG9ubHkgaWYgdGllX3NlbGVjdGlvbiBpbiBjaGVja2JveCBzZXR0aW5ncyBpcyBmYWxzZSlcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgY2hlY2tfYWxsLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtBcnJheX0gc2VsZWN0ZWQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG5cdFx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignY2hlY2tfYWxsJywgeyAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCB9KTtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHVuY2hlY2sgYWxsIGNoZWNrZWQgbm9kZXMgKG9ubHkgaWYgdGllX3NlbGVjdGlvbiBpbiBjaGVja2JveCBzZXR0aW5ncyBpcyBmYWxzZSwgb3RoZXJ3aXNlIGRlc2VsZWN0X2FsbCB3aWxsIGJlIGNhbGxlZCBpbnRlcm5hbGx5KVxuXHRcdCAqIEBuYW1lIHVuY2hlY2tfYWxsKClcblx0XHQgKiBAdHJpZ2dlciB1bmNoZWNrX2FsbC5qc3RyZWVcblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy51bmNoZWNrX2FsbCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikgeyByZXR1cm4gdGhpcy5kZXNlbGVjdF9hbGwoKTsgfVxuXHRcdFx0dmFyIHRtcCA9IHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQuY29uY2F0KFtdKSwgaSwgajtcblx0XHRcdGZvcihpID0gMCwgaiA9IHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdGlmKHRoaXMuX21vZGVsLmRhdGFbdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZFtpXV0pIHtcblx0XHRcdFx0XHR0aGlzLl9tb2RlbC5kYXRhW3RoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWRbaV1dLnN0YXRlLmNoZWNrZWQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCA9IFtdO1xuXHRcdFx0dGhpcy5lbGVtZW50LmZpbmQoJy5qc3RyZWUtY2hlY2tlZCcpLnJlbW92ZUNsYXNzKCdqc3RyZWUtY2hlY2tlZCcpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgd2hlbiBhbGwgbm9kZXMgYXJlIHVuY2hlY2tlZCAob25seSBpZiB0aWVfc2VsZWN0aW9uIGluIGNoZWNrYm94IHNldHRpbmdzIGlzIGZhbHNlKVxuXHRcdFx0ICogQGV2ZW50XG5cdFx0XHQgKiBAbmFtZSB1bmNoZWNrX2FsbC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIHRoZSBwcmV2aW91cyBzZWxlY3Rpb25cblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IHNlbGVjdGVkIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuXHRcdFx0ICogQHBsdWdpbiBjaGVja2JveFxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnRyaWdnZXIoJ3VuY2hlY2tfYWxsJywgeyAnc2VsZWN0ZWQnIDogdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCwgJ25vZGUnIDogdG1wIH0pO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogY2hlY2tzIGlmIGEgbm9kZSBpcyBjaGVja2VkIChpZiB0aWVfc2VsZWN0aW9uIGlzIG9uIGluIHRoZSBzZXR0aW5ncyB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lIGFzIGlzX3NlbGVjdGVkKVxuXHRcdCAqIEBuYW1lIGlzX2NoZWNrZWQob2JqKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSAgb2JqXG5cdFx0ICogQHJldHVybiB7Qm9vbGVhbn1cblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy5pc19jaGVja2VkID0gZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uKSB7IHJldHVybiB0aGlzLmlzX3NlbGVjdGVkKG9iaik7IH1cblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0cmV0dXJuIG9iai5zdGF0ZS5jaGVja2VkO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogZ2V0IGFuIGFycmF5IG9mIGFsbCBjaGVja2VkIG5vZGVzIChpZiB0aWVfc2VsZWN0aW9uIGlzIG9uIGluIHRoZSBzZXR0aW5ncyB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lIGFzIGdldF9zZWxlY3RlZClcblx0XHQgKiBAbmFtZSBnZXRfY2hlY2tlZChbZnVsbF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9ICBmdWxsIGlmIHNldCB0byBgdHJ1ZWAgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgY29uc2lzdCBvZiB0aGUgZnVsbCBub2RlIG9iamVjdHMsIG90aGVyd2lzZSAtIG9ubHkgSURzIHdpbGwgYmUgcmV0dXJuZWRcblx0XHQgKiBAcmV0dXJuIHtBcnJheX1cblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy5nZXRfY2hlY2tlZCA9IGZ1bmN0aW9uIChmdWxsKSB7XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24pIHsgcmV0dXJuIHRoaXMuZ2V0X3NlbGVjdGVkKGZ1bGwpOyB9XG5cdFx0XHRyZXR1cm4gZnVsbCA/ICQubWFwKHRoaXMuX2RhdGEuY2hlY2tib3guc2VsZWN0ZWQsIGZ1bmN0aW9uIChpKSB7IHJldHVybiB0aGlzLmdldF9ub2RlKGkpOyB9LmJpbmQodGhpcykpIDogdGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZC5zbGljZSgpO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogZ2V0IGFuIGFycmF5IG9mIGFsbCB0b3AgbGV2ZWwgY2hlY2tlZCBub2RlcyAoaWdub3JpbmcgY2hpbGRyZW4gb2YgY2hlY2tlZCBub2RlcykgKGlmIHRpZV9zZWxlY3Rpb24gaXMgb24gaW4gdGhlIHNldHRpbmdzIHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIHNhbWUgYXMgZ2V0X3RvcF9zZWxlY3RlZClcblx0XHQgKiBAbmFtZSBnZXRfdG9wX2NoZWNrZWQoW2Z1bGxdKVxuXHRcdCAqIEBwYXJhbSAge21peGVkfSAgZnVsbCBpZiBzZXQgdG8gYHRydWVgIHRoZSByZXR1cm5lZCBhcnJheSB3aWxsIGNvbnNpc3Qgb2YgdGhlIGZ1bGwgbm9kZSBvYmplY3RzLCBvdGhlcndpc2UgLSBvbmx5IElEcyB3aWxsIGJlIHJldHVybmVkXG5cdFx0ICogQHJldHVybiB7QXJyYXl9XG5cdFx0ICogQHBsdWdpbiBjaGVja2JveFxuXHRcdCAqL1xuXHRcdHRoaXMuZ2V0X3RvcF9jaGVja2VkID0gZnVuY3Rpb24gKGZ1bGwpIHtcblx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikgeyByZXR1cm4gdGhpcy5nZXRfdG9wX3NlbGVjdGVkKGZ1bGwpOyB9XG5cdFx0XHR2YXIgdG1wID0gdGhpcy5nZXRfY2hlY2tlZCh0cnVlKSxcblx0XHRcdFx0b2JqID0ge30sIGksIGosIGssIGw7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSB0bXAubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdG9ialt0bXBbaV0uaWRdID0gdG1wW2ldO1xuXHRcdFx0fVxuXHRcdFx0Zm9yKGkgPSAwLCBqID0gdG1wLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRmb3IoayA9IDAsIGwgPSB0bXBbaV0uY2hpbGRyZW5fZC5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRpZihvYmpbdG1wW2ldLmNoaWxkcmVuX2Rba11dKSB7XG5cdFx0XHRcdFx0XHRkZWxldGUgb2JqW3RtcFtpXS5jaGlsZHJlbl9kW2tdXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRtcCA9IFtdO1xuXHRcdFx0Zm9yKGkgaW4gb2JqKSB7XG5cdFx0XHRcdGlmKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdHRtcC5wdXNoKGkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZnVsbCA/ICQubWFwKHRtcCwgZnVuY3Rpb24gKGkpIHsgcmV0dXJuIHRoaXMuZ2V0X25vZGUoaSk7IH0uYmluZCh0aGlzKSkgOiB0bXA7XG5cdFx0fTtcblx0XHQvKipcblx0XHQgKiBnZXQgYW4gYXJyYXkgb2YgYWxsIGJvdHRvbSBsZXZlbCBjaGVja2VkIG5vZGVzIChpZ25vcmluZyBzZWxlY3RlZCBwYXJlbnRzKSAoaWYgdGllX3NlbGVjdGlvbiBpcyBvbiBpbiB0aGUgc2V0dGluZ3MgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgc2FtZSBhcyBnZXRfYm90dG9tX3NlbGVjdGVkKVxuXHRcdCAqIEBuYW1lIGdldF9ib3R0b21fY2hlY2tlZChbZnVsbF0pXG5cdFx0ICogQHBhcmFtICB7bWl4ZWR9ICBmdWxsIGlmIHNldCB0byBgdHJ1ZWAgdGhlIHJldHVybmVkIGFycmF5IHdpbGwgY29uc2lzdCBvZiB0aGUgZnVsbCBub2RlIG9iamVjdHMsIG90aGVyd2lzZSAtIG9ubHkgSURzIHdpbGwgYmUgcmV0dXJuZWRcblx0XHQgKiBAcmV0dXJuIHtBcnJheX1cblx0XHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdFx0ICovXG5cdFx0dGhpcy5nZXRfYm90dG9tX2NoZWNrZWQgPSBmdW5jdGlvbiAoZnVsbCkge1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uKSB7IHJldHVybiB0aGlzLmdldF9ib3R0b21fc2VsZWN0ZWQoZnVsbCk7IH1cblx0XHRcdHZhciB0bXAgPSB0aGlzLmdldF9jaGVja2VkKHRydWUpLFxuXHRcdFx0XHRvYmogPSBbXSwgaSwgajtcblx0XHRcdGZvcihpID0gMCwgaiA9IHRtcC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0aWYoIXRtcFtpXS5jaGlsZHJlbi5sZW5ndGgpIHtcblx0XHRcdFx0XHRvYmoucHVzaCh0bXBbaV0uaWQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZnVsbCA/ICQubWFwKG9iaiwgZnVuY3Rpb24gKGkpIHsgcmV0dXJuIHRoaXMuZ2V0X25vZGUoaSk7IH0uYmluZCh0aGlzKSkgOiBvYmo7XG5cdFx0fTtcblx0XHR0aGlzLmxvYWRfbm9kZSA9IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG5cdFx0XHR2YXIgaywgbCwgaSwgaiwgYywgdG1wO1xuXHRcdFx0aWYoISQudmFrYXRhLmlzX2FycmF5KG9iaikgJiYgIXRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikge1xuXHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRcdGlmKHRtcCAmJiB0bXAuc3RhdGUubG9hZGVkKSB7XG5cdFx0XHRcdFx0Zm9yKGsgPSAwLCBsID0gdG1wLmNoaWxkcmVuX2QubGVuZ3RoOyBrIDwgbDsgaysrKSB7XG5cdFx0XHRcdFx0XHRpZih0aGlzLl9tb2RlbC5kYXRhW3RtcC5jaGlsZHJlbl9kW2tdXS5zdGF0ZS5jaGVja2VkKSB7XG5cdFx0XHRcdFx0XHRcdGMgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkID0gJC52YWthdGEuYXJyYXlfcmVtb3ZlX2l0ZW0odGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCwgdG1wLmNoaWxkcmVuX2Rba10pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBhcmVudC5sb2FkX25vZGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHR9O1xuXHRcdHRoaXMuZ2V0X3N0YXRlID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIHN0YXRlID0gcGFyZW50LmdldF9zdGF0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jaGVja2JveC50aWVfc2VsZWN0aW9uKSB7IHJldHVybiBzdGF0ZTsgfVxuXHRcdFx0c3RhdGUuY2hlY2tib3ggPSB0aGlzLl9kYXRhLmNoZWNrYm94LnNlbGVjdGVkLnNsaWNlKCk7XG5cdFx0XHRyZXR1cm4gc3RhdGU7XG5cdFx0fTtcblx0XHR0aGlzLnNldF9zdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgY2FsbGJhY2spIHtcblx0XHRcdHZhciByZXMgPSBwYXJlbnQuc2V0X3N0YXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0XHRpZihyZXMgJiYgc3RhdGUuY2hlY2tib3gpIHtcblx0XHRcdFx0aWYoIXRoaXMuc2V0dGluZ3MuY2hlY2tib3gudGllX3NlbGVjdGlvbikge1xuXHRcdFx0XHRcdHRoaXMudW5jaGVja19hbGwoKTtcblx0XHRcdFx0XHR2YXIgX3RoaXMgPSB0aGlzO1xuXHRcdFx0XHRcdCQuZWFjaChzdGF0ZS5jaGVja2JveCwgZnVuY3Rpb24gKGksIHYpIHtcblx0XHRcdFx0XHRcdF90aGlzLmNoZWNrX25vZGUodik7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGVsZXRlIHN0YXRlLmNoZWNrYm94O1xuXHRcdFx0XHR0aGlzLnNldF9zdGF0ZShzdGF0ZSwgY2FsbGJhY2spO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzO1xuXHRcdH07XG5cdFx0dGhpcy5yZWZyZXNoID0gZnVuY3Rpb24gKHNraXBfbG9hZGluZywgZm9yZ2V0X3N0YXRlKSB7XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNoZWNrYm94LnRpZV9zZWxlY3Rpb24pIHtcblx0XHRcdFx0dGhpcy5fZGF0YS5jaGVja2JveC5zZWxlY3RlZCA9IFtdO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBhcmVudC5yZWZyZXNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0fTtcblx0fTtcblxuXHQvLyBpbmNsdWRlIHRoZSBjaGVja2JveCBwbHVnaW4gYnkgZGVmYXVsdFxuXHQvLyAkLmpzdHJlZS5kZWZhdWx0cy5wbHVnaW5zLnB1c2goXCJjaGVja2JveFwiKTtcblxuXG4vKipcbiAqICMjIyBDb25kaXRpb25hbHNlbGVjdCBwbHVnaW5cbiAqXG4gKiBUaGlzIHBsdWdpbiBhbGxvd3MgZGVmaW5pbmcgYSBjYWxsYmFjayB0byBhbGxvdyBvciBkZW55IG5vZGUgc2VsZWN0aW9uIGJ5IHVzZXIgaW5wdXQgKGFjdGl2YXRlIG5vZGUgbWV0aG9kKS5cbiAqL1xuXG5cdC8qKlxuXHQgKiBhIGNhbGxiYWNrIChmdW5jdGlvbikgd2hpY2ggaXMgaW52b2tlZCBpbiB0aGUgaW5zdGFuY2UncyBzY29wZSBhbmQgcmVjZWl2ZXMgdHdvIGFyZ3VtZW50cyAtIHRoZSBub2RlIGFuZCB0aGUgZXZlbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGBhY3RpdmF0ZV9ub2RlYCBjYWxsLiBSZXR1cm5pbmcgZmFsc2UgcHJldmVudHMgd29ya2luZyB3aXRoIHRoZSBub2RlLCByZXR1cm5pbmcgdHJ1ZSBhbGxvd3MgaW52b2tpbmcgYWN0aXZhdGVfbm9kZS4gRGVmYXVsdHMgdG8gcmV0dXJuaW5nIGB0cnVlYC5cblx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuY2hlY2tib3gudmlzaWJsZVxuXHQgKiBAcGx1Z2luIGNoZWNrYm94XG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy5jb25kaXRpb25hbHNlbGVjdCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XG5cdCQuanN0cmVlLnBsdWdpbnMuY29uZGl0aW9uYWxzZWxlY3QgPSBmdW5jdGlvbiAob3B0aW9ucywgcGFyZW50KSB7XG5cdFx0Ly8gb3duIGZ1bmN0aW9uXG5cdFx0dGhpcy5hY3RpdmF0ZV9ub2RlID0gZnVuY3Rpb24gKG9iaiwgZSkge1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy5jb25kaXRpb25hbHNlbGVjdC5jYWxsKHRoaXMsIHRoaXMuZ2V0X25vZGUob2JqKSwgZSkpIHtcblx0XHRcdFx0cmV0dXJuIHBhcmVudC5hY3RpdmF0ZV9ub2RlLmNhbGwodGhpcywgb2JqLCBlKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9O1xuXG5cbi8qKlxuICogIyMjIENvbnRleHRtZW51IHBsdWdpblxuICpcbiAqIFNob3dzIGEgY29udGV4dCBtZW51IHdoZW4gYSBub2RlIGlzIHJpZ2h0LWNsaWNrZWQuXG4gKi9cblxuXHQvKipcblx0ICogc3RvcmVzIGFsbCBkZWZhdWx0cyBmb3IgdGhlIGNvbnRleHRtZW51IHBsdWdpblxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb250ZXh0bWVudVxuXHQgKiBAcGx1Z2luIGNvbnRleHRtZW51XG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy5jb250ZXh0bWVudSA9IHtcblx0XHQvKipcblx0XHQgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgbm9kZSBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiB0aGUgY29udGV4dCBtZW51IGlzIGludm9rZWQgb24gaXQuIERlZmF1bHRzIHRvIGB0cnVlYC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5jb250ZXh0bWVudS5zZWxlY3Rfbm9kZVxuXHRcdCAqIEBwbHVnaW4gY29udGV4dG1lbnVcblx0XHQgKi9cblx0XHRzZWxlY3Rfbm9kZSA6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIG1lbnUgc2hvdWxkIGJlIHNob3duIGFsaWduZWQgd2l0aCB0aGUgbm9kZS4gRGVmYXVsdHMgdG8gYHRydWVgLCBvdGhlcndpc2UgdGhlIG1vdXNlIGNvb3JkaW5hdGVzIGFyZSB1c2VkLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvbnRleHRtZW51LnNob3dfYXRfbm9kZVxuXHRcdCAqIEBwbHVnaW4gY29udGV4dG1lbnVcblx0XHQgKi9cblx0XHRzaG93X2F0X25vZGUgOiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGFuIG9iamVjdCBvZiBhY3Rpb25zLCBvciBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyBhIG5vZGUgYW5kIGEgY2FsbGJhY2sgZnVuY3Rpb24gYW5kIGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIGFuIG9iamVjdCBvZiBhY3Rpb25zIGF2YWlsYWJsZSBmb3IgdGhhdCBub2RlICh5b3UgY2FuIGFsc28gcmV0dXJuIHRoZSBpdGVtcyB0b28pLlxuXHRcdCAqXG5cdFx0ICogRWFjaCBhY3Rpb24gY29uc2lzdHMgb2YgYSBrZXkgKGEgdW5pcXVlIG5hbWUpIGFuZCBhIHZhbHVlIHdoaWNoIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyAob25seSBsYWJlbCBhbmQgYWN0aW9uIGFyZSByZXF1aXJlZCkuIE9uY2UgYSBtZW51IGl0ZW0gaXMgYWN0aXZhdGVkIHRoZSBgYWN0aW9uYCBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgd2l0aCBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIGtleXM6IGl0ZW0gLSB0aGUgY29udGV4dG1lbnUgaXRlbSBkZWZpbml0aW9uIGFzIHNlZW4gYmVsb3csIHJlZmVyZW5jZSAtIHRoZSBET00gbm9kZSB0aGF0IHdhcyB1c2VkICh0aGUgdHJlZSBub2RlKSwgZWxlbWVudCAtIHRoZSBjb250ZXh0bWVudSBET00gZWxlbWVudCwgcG9zaXRpb24gLSBhbiBvYmplY3Qgd2l0aCB4L3kgcHJvcGVydGllcyBpbmRpY2F0aW5nIHRoZSBwb3NpdGlvbiBvZiB0aGUgbWVudS5cblx0XHQgKlxuXHRcdCAqICogYHNlcGFyYXRvcl9iZWZvcmVgIC0gYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlcmUgc2hvdWxkIGJlIGEgc2VwYXJhdG9yIGJlZm9yZSB0aGlzIGl0ZW1cblx0XHQgKiAqIGBzZXBhcmF0b3JfYWZ0ZXJgIC0gYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlcmUgc2hvdWxkIGJlIGEgc2VwYXJhdG9yIGFmdGVyIHRoaXMgaXRlbVxuXHRcdCAqICogYF9kaXNhYmxlZGAgLSBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGlzIGFjdGlvbiBzaG91bGQgYmUgZGlzYWJsZWRcblx0XHQgKiAqIGBsYWJlbGAgLSBhIHN0cmluZyAtIHRoZSBuYW1lIG9mIHRoZSBhY3Rpb24gKGNvdWxkIGJlIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGEgc3RyaW5nKVxuXHRcdCAqICogYHRpdGxlYCAtIGEgc3RyaW5nIC0gYW4gb3B0aW9uYWwgdG9vbHRpcCBmb3IgdGhlIGl0ZW1cblx0XHQgKiAqIGBhY3Rpb25gIC0gYSBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBpZiB0aGlzIGl0ZW0gaXMgY2hvc2VuLCB0aGUgZnVuY3Rpb24gd2lsbCByZWNlaXZlIFxuXHRcdCAqICogYGljb25gIC0gYSBzdHJpbmcsIGNhbiBiZSBhIHBhdGggdG8gYW4gaWNvbiBvciBhIGNsYXNzTmFtZSwgaWYgdXNpbmcgYW4gaW1hZ2UgdGhhdCBpcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdXNlIGEgYC4vYCBwcmVmaXgsIG90aGVyd2lzZSBpdCB3aWxsIGJlIGRldGVjdGVkIGFzIGEgY2xhc3Ncblx0XHQgKiAqIGBzaG9ydGN1dGAgLSBrZXlDb2RlIHdoaWNoIHdpbGwgdHJpZ2dlciB0aGUgYWN0aW9uIGlmIHRoZSBtZW51IGlzIG9wZW4gKGZvciBleGFtcGxlIGAxMTNgIGZvciByZW5hbWUsIHdoaWNoIGVxdWFscyBGMilcblx0XHQgKiAqIGBzaG9ydGN1dF9sYWJlbGAgLSBzaG9ydGN1dCBsYWJlbCAobGlrZSBmb3IgZXhhbXBsZSBgRjJgIGZvciByZW5hbWUpXG5cdFx0ICogKiBgc3VibWVudWAgLSBhbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzdHJ1Y3R1cmUgYXMgJC5qc3RyZWUuZGVmYXVsdHMuY29udGV4dG1lbnUuaXRlbXMgd2hpY2ggY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgc3VibWVudSAtIGVhY2gga2V5IHdpbGwgYmUgcmVuZGVyZWQgYXMgYSBzZXBhcmF0ZSBvcHRpb24gaW4gYSBzdWJtZW51IHRoYXQgd2lsbCBhcHBlYXIgb25jZSB0aGUgY3VycmVudCBpdGVtIGlzIGhvdmVyZWRcblx0XHQgKlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmNvbnRleHRtZW51Lml0ZW1zXG5cdFx0ICogQHBsdWdpbiBjb250ZXh0bWVudVxuXHRcdCAqL1xuXHRcdGl0ZW1zIDogZnVuY3Rpb24gKG8sIGNiKSB7IC8vIENvdWxkIGJlIGFuIG9iamVjdCBkaXJlY3RseVxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XCJjcmVhdGVcIiA6IHtcblx0XHRcdFx0XHRcInNlcGFyYXRvcl9iZWZvcmVcIlx0OiBmYWxzZSxcblx0XHRcdFx0XHRcInNlcGFyYXRvcl9hZnRlclwiXHQ6IHRydWUsXG5cdFx0XHRcdFx0XCJfZGlzYWJsZWRcIlx0XHRcdDogZmFsc2UsIC8vKHRoaXMuY2hlY2soXCJjcmVhdGVfbm9kZVwiLCBkYXRhLnJlZmVyZW5jZSwge30sIFwibGFzdFwiKSksXG5cdFx0XHRcdFx0XCJsYWJlbFwiXHRcdFx0XHQ6IFwiQ3JlYXRlXCIsXG5cdFx0XHRcdFx0XCJhY3Rpb25cIlx0XHRcdDogZnVuY3Rpb24gKGRhdGEpIHtcblx0XHRcdFx0XHRcdHZhciBpbnN0ID0gJC5qc3RyZWUucmVmZXJlbmNlKGRhdGEucmVmZXJlbmNlKSxcblx0XHRcdFx0XHRcdFx0b2JqID0gaW5zdC5nZXRfbm9kZShkYXRhLnJlZmVyZW5jZSk7XG5cdFx0XHRcdFx0XHRpbnN0LmNyZWF0ZV9ub2RlKG9iaiwge30sIFwibGFzdFwiLCBmdW5jdGlvbiAobmV3X25vZGUpIHtcblx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRpbnN0LmVkaXQobmV3X25vZGUpO1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIChleCkge1xuXHRcdFx0XHRcdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyBpbnN0LmVkaXQobmV3X25vZGUpOyB9LDApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdFwicmVuYW1lXCIgOiB7XG5cdFx0XHRcdFx0XCJzZXBhcmF0b3JfYmVmb3JlXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XCJzZXBhcmF0b3JfYWZ0ZXJcIlx0OiBmYWxzZSxcblx0XHRcdFx0XHRcIl9kaXNhYmxlZFwiXHRcdFx0OiBmYWxzZSwgLy8odGhpcy5jaGVjayhcInJlbmFtZV9ub2RlXCIsIGRhdGEucmVmZXJlbmNlLCB0aGlzLmdldF9wYXJlbnQoZGF0YS5yZWZlcmVuY2UpLCBcIlwiKSksXG5cdFx0XHRcdFx0XCJsYWJlbFwiXHRcdFx0XHQ6IFwiUmVuYW1lXCIsXG5cdFx0XHRcdFx0LyohXG5cdFx0XHRcdFx0XCJzaG9ydGN1dFwiXHRcdFx0OiAxMTMsXG5cdFx0XHRcdFx0XCJzaG9ydGN1dF9sYWJlbFwiXHQ6ICdGMicsXG5cdFx0XHRcdFx0XCJpY29uXCJcdFx0XHRcdDogXCJnbHlwaGljb24gZ2x5cGhpY29uLWxlYWZcIixcblx0XHRcdFx0XHQqL1xuXHRcdFx0XHRcdFwiYWN0aW9uXCJcdFx0XHQ6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRcdFx0XHR2YXIgaW5zdCA9ICQuanN0cmVlLnJlZmVyZW5jZShkYXRhLnJlZmVyZW5jZSksXG5cdFx0XHRcdFx0XHRcdG9iaiA9IGluc3QuZ2V0X25vZGUoZGF0YS5yZWZlcmVuY2UpO1xuXHRcdFx0XHRcdFx0aW5zdC5lZGl0KG9iaik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRcInJlbW92ZVwiIDoge1xuXHRcdFx0XHRcdFwic2VwYXJhdG9yX2JlZm9yZVwiXHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFwiaWNvblwiXHRcdFx0XHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFwic2VwYXJhdG9yX2FmdGVyXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XCJfZGlzYWJsZWRcIlx0XHRcdDogZmFsc2UsIC8vKHRoaXMuY2hlY2soXCJkZWxldGVfbm9kZVwiLCBkYXRhLnJlZmVyZW5jZSwgdGhpcy5nZXRfcGFyZW50KGRhdGEucmVmZXJlbmNlKSwgXCJcIikpLFxuXHRcdFx0XHRcdFwibGFiZWxcIlx0XHRcdFx0OiBcIkRlbGV0ZVwiLFxuXHRcdFx0XHRcdFwiYWN0aW9uXCJcdFx0XHQ6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRcdFx0XHR2YXIgaW5zdCA9ICQuanN0cmVlLnJlZmVyZW5jZShkYXRhLnJlZmVyZW5jZSksXG5cdFx0XHRcdFx0XHRcdG9iaiA9IGluc3QuZ2V0X25vZGUoZGF0YS5yZWZlcmVuY2UpO1xuXHRcdFx0XHRcdFx0aWYoaW5zdC5pc19zZWxlY3RlZChvYmopKSB7XG5cdFx0XHRcdFx0XHRcdGluc3QuZGVsZXRlX25vZGUoaW5zdC5nZXRfc2VsZWN0ZWQoKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0aW5zdC5kZWxldGVfbm9kZShvYmopO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSxcblx0XHRcdFx0XCJjY3BcIiA6IHtcblx0XHRcdFx0XHRcInNlcGFyYXRvcl9iZWZvcmVcIlx0OiB0cnVlLFxuXHRcdFx0XHRcdFwiaWNvblwiXHRcdFx0XHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFwic2VwYXJhdG9yX2FmdGVyXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XCJsYWJlbFwiXHRcdFx0XHQ6IFwiRWRpdFwiLFxuXHRcdFx0XHRcdFwiYWN0aW9uXCJcdFx0XHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFwic3VibWVudVwiIDoge1xuXHRcdFx0XHRcdFx0XCJjdXRcIiA6IHtcblx0XHRcdFx0XHRcdFx0XCJzZXBhcmF0b3JfYmVmb3JlXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdFwic2VwYXJhdG9yX2FmdGVyXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdFwibGFiZWxcIlx0XHRcdFx0OiBcIkN1dFwiLFxuXHRcdFx0XHRcdFx0XHRcImFjdGlvblwiXHRcdFx0OiBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBpbnN0ID0gJC5qc3RyZWUucmVmZXJlbmNlKGRhdGEucmVmZXJlbmNlKSxcblx0XHRcdFx0XHRcdFx0XHRcdG9iaiA9IGluc3QuZ2V0X25vZGUoZGF0YS5yZWZlcmVuY2UpO1xuXHRcdFx0XHRcdFx0XHRcdGlmKGluc3QuaXNfc2VsZWN0ZWQob2JqKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aW5zdC5jdXQoaW5zdC5nZXRfdG9wX3NlbGVjdGVkKCkpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGluc3QuY3V0KG9iaik7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XCJjb3B5XCIgOiB7XG5cdFx0XHRcdFx0XHRcdFwic2VwYXJhdG9yX2JlZm9yZVwiXHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHRcImljb25cIlx0XHRcdFx0OiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0XCJzZXBhcmF0b3JfYWZ0ZXJcIlx0OiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0XCJsYWJlbFwiXHRcdFx0XHQ6IFwiQ29weVwiLFxuXHRcdFx0XHRcdFx0XHRcImFjdGlvblwiXHRcdFx0OiBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBpbnN0ID0gJC5qc3RyZWUucmVmZXJlbmNlKGRhdGEucmVmZXJlbmNlKSxcblx0XHRcdFx0XHRcdFx0XHRcdG9iaiA9IGluc3QuZ2V0X25vZGUoZGF0YS5yZWZlcmVuY2UpO1xuXHRcdFx0XHRcdFx0XHRcdGlmKGluc3QuaXNfc2VsZWN0ZWQob2JqKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aW5zdC5jb3B5KGluc3QuZ2V0X3RvcF9zZWxlY3RlZCgpKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpbnN0LmNvcHkob2JqKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcInBhc3RlXCIgOiB7XG5cdFx0XHRcdFx0XHRcdFwic2VwYXJhdG9yX2JlZm9yZVwiXHQ6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHRcImljb25cIlx0XHRcdFx0OiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0XCJfZGlzYWJsZWRcIlx0XHRcdDogZnVuY3Rpb24gKGRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gISQuanN0cmVlLnJlZmVyZW5jZShkYXRhLnJlZmVyZW5jZSkuY2FuX3Bhc3RlKCk7XG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdFwic2VwYXJhdG9yX2FmdGVyXCJcdDogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdFwibGFiZWxcIlx0XHRcdFx0OiBcIlBhc3RlXCIsXG5cdFx0XHRcdFx0XHRcdFwiYWN0aW9uXCJcdFx0XHQ6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIGluc3QgPSAkLmpzdHJlZS5yZWZlcmVuY2UoZGF0YS5yZWZlcmVuY2UpLFxuXHRcdFx0XHRcdFx0XHRcdFx0b2JqID0gaW5zdC5nZXRfbm9kZShkYXRhLnJlZmVyZW5jZSk7XG5cdFx0XHRcdFx0XHRcdFx0aW5zdC5wYXN0ZShvYmopO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0fTtcblxuXHQkLmpzdHJlZS5wbHVnaW5zLmNvbnRleHRtZW51ID0gZnVuY3Rpb24gKG9wdGlvbnMsIHBhcmVudCkge1xuXHRcdHRoaXMuYmluZCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHBhcmVudC5iaW5kLmNhbGwodGhpcyk7XG5cblx0XHRcdHZhciBsYXN0X3RzID0gMCwgY3RvID0gbnVsbCwgZXgsIGV5O1xuXHRcdFx0dGhpcy5lbGVtZW50XG5cdFx0XHRcdC5vbihcImluaXQuanN0cmVlIGxvYWRpbmcuanN0cmVlIHJlYWR5LmpzdHJlZVwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmdldF9jb250YWluZXJfdWwoKS5hZGRDbGFzcygnanN0cmVlLWNvbnRleHRtZW51Jyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJjb250ZXh0bWVudS5qc3RyZWVcIiwgXCIuanN0cmVlLWFuY2hvclwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0aWYgKGUudGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0Jykge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRsYXN0X3RzID0gZS5jdHJsS2V5ID8gK25ldyBEYXRlKCkgOiAwO1xuXHRcdFx0XHRcdFx0aWYoZGF0YSB8fCBjdG8pIHtcblx0XHRcdFx0XHRcdFx0bGFzdF90cyA9ICgrbmV3IERhdGUoKSkgKyAxMDAwMDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmKGN0bykge1xuXHRcdFx0XHRcdFx0XHRjbGVhclRpbWVvdXQoY3RvKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmKCF0aGlzLmlzX2xvYWRpbmcoZS5jdXJyZW50VGFyZ2V0KSkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNob3dfY29udGV4dG1lbnUoZS5jdXJyZW50VGFyZ2V0LCBlLnBhZ2VYLCBlLnBhZ2VZLCBlKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbihcImNsaWNrLmpzdHJlZVwiLCBcIi5qc3RyZWUtYW5jaG9yXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZih0aGlzLl9kYXRhLmNvbnRleHRtZW51LnZpc2libGUgJiYgKCFsYXN0X3RzIHx8ICgrbmV3IERhdGUoKSkgLSBsYXN0X3RzID4gMjUwKSkgeyAvLyB3b3JrIGFyb3VuZCBzYWZhcmkgJiBtYWNPUyBjdHJsK2NsaWNrXG5cdFx0XHRcdFx0XHRcdCQudmFrYXRhLmNvbnRleHQuaGlkZSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0bGFzdF90cyA9IDA7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJ0b3VjaHN0YXJ0LmpzdHJlZVwiLCBcIi5qc3RyZWUtYW5jaG9yXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZighZS5vcmlnaW5hbEV2ZW50IHx8ICFlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXMgfHwgIWUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRleCA9IGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYO1xuXHRcdFx0XHRcdFx0ZXkgPSBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WTtcblx0XHRcdFx0XHRcdGN0byA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHQkKGUuY3VycmVudFRhcmdldCkudHJpZ2dlcignY29udGV4dG1lbnUnLCB0cnVlKTtcblx0XHRcdFx0XHRcdH0sIDc1MCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0Lm9uKCd0b3VjaG1vdmUudmFrYXRhLmpzdHJlZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZihjdG8gJiYgZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlcyAmJiBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0gJiYgKE1hdGguYWJzKGV4IC0gZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFgpID4gMTAgfHwgTWF0aC5hYnMoZXkgLSBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WSkgPiAxMCkpIHtcblx0XHRcdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KGN0byk7XG5cdFx0XHRcdFx0XHRcdCQudmFrYXRhLmNvbnRleHQuaGlkZSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdC5vbigndG91Y2hlbmQudmFrYXRhLmpzdHJlZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZihjdG8pIHtcblx0XHRcdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KGN0byk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdC8qIVxuXHRcdFx0aWYoISgnb25jb250ZXh0bWVudScgaW4gZG9jdW1lbnQuYm9keSkgJiYgKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmJvZHkpKSB7XG5cdFx0XHRcdHZhciBlbCA9IG51bGwsIHRtID0gbnVsbDtcblx0XHRcdFx0dGhpcy5lbGVtZW50XG5cdFx0XHRcdFx0Lm9uKFwidG91Y2hzdGFydFwiLCBcIi5qc3RyZWUtYW5jaG9yXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRlbCA9IGUuY3VycmVudFRhcmdldDtcblx0XHRcdFx0XHRcdHRtID0gK25ldyBEYXRlKCk7XG5cdFx0XHRcdFx0XHQkKGRvY3VtZW50KS5vbmUoXCJ0b3VjaGVuZFwiLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0XHRlLnRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS5vcmlnaW5hbEV2ZW50LnRhcmdldFRvdWNoZXNbMF0ucGFnZVggLSB3aW5kb3cucGFnZVhPZmZzZXQsIGUub3JpZ2luYWxFdmVudC50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0KTtcblx0XHRcdFx0XHRcdFx0ZS5jdXJyZW50VGFyZ2V0ID0gZS50YXJnZXQ7XG5cdFx0XHRcdFx0XHRcdHRtID0gKCgrKG5ldyBEYXRlKCkpKSAtIHRtKTtcblx0XHRcdFx0XHRcdFx0aWYoZS50YXJnZXQgPT09IGVsICYmIHRtID4gNjAwICYmIHRtIDwgMTAwMCkge1xuXHRcdFx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0XHQkKGVsKS50cmlnZ2VyKCdjb250ZXh0bWVudScsIGUpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGVsID0gbnVsbDtcblx0XHRcdFx0XHRcdFx0dG0gPSBudWxsO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHQqL1xuXHRcdFx0JChkb2N1bWVudCkub24oXCJjb250ZXh0X2hpZGUudmFrYXRhLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLmNvbnRleHRtZW51LnZpc2libGUgPSBmYWxzZTtcblx0XHRcdFx0JChkYXRhLnJlZmVyZW5jZSkucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1jb250ZXh0Jyk7XG5cdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdH07XG5cdFx0dGhpcy50ZWFyZG93biA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmKHRoaXMuX2RhdGEuY29udGV4dG1lbnUudmlzaWJsZSkge1xuXHRcdFx0XHQkLnZha2F0YS5jb250ZXh0LmhpZGUoKTtcblx0XHRcdH1cblx0XHRcdCQoZG9jdW1lbnQpLm9mZihcImNvbnRleHRfaGlkZS52YWthdGEuanN0cmVlXCIpO1xuXHRcdFx0cGFyZW50LnRlYXJkb3duLmNhbGwodGhpcyk7XG5cdFx0fTtcblxuXHRcdC8qKlxuXHRcdCAqIHByZXBhcmUgYW5kIHNob3cgdGhlIGNvbnRleHQgbWVudSBmb3IgYSBub2RlXG5cdFx0ICogQG5hbWUgc2hvd19jb250ZXh0bWVudShvYmogWywgeCwgeV0pXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gb2JqIHRoZSBub2RlXG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IHggdGhlIHgtY29vcmRpbmF0ZSByZWxhdGl2ZSB0byB0aGUgZG9jdW1lbnQgdG8gc2hvdyB0aGUgbWVudSBhdFxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSB5IHRoZSB5LWNvb3JkaW5hdGUgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50IHRvIHNob3cgdGhlIG1lbnUgYXRcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZSB0aGUgZXZlbnQgaWYgYXZhaWxhYmxlIHRoYXQgdHJpZ2dlcmVkIHRoZSBjb250ZXh0bWVudVxuXHRcdCAqIEBwbHVnaW4gY29udGV4dG1lbnVcblx0XHQgKiBAdHJpZ2dlciBzaG93X2NvbnRleHRtZW51LmpzdHJlZVxuXHRcdCAqL1xuXHRcdHRoaXMuc2hvd19jb250ZXh0bWVudSA9IGZ1bmN0aW9uIChvYmosIHgsIHksIGUpIHtcblx0XHRcdG9iaiA9IHRoaXMuZ2V0X25vZGUob2JqKTtcblx0XHRcdGlmKCFvYmogfHwgb2JqLmlkID09PSAkLmpzdHJlZS5yb290KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0dmFyIHMgPSB0aGlzLnNldHRpbmdzLmNvbnRleHRtZW51LFxuXHRcdFx0XHRkID0gdGhpcy5nZXRfbm9kZShvYmosIHRydWUpLFxuXHRcdFx0XHRhID0gZC5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpLFxuXHRcdFx0XHRvID0gZmFsc2UsXG5cdFx0XHRcdGkgPSBmYWxzZTtcblx0XHRcdGlmKHMuc2hvd19hdF9ub2RlIHx8IHggPT09IHVuZGVmaW5lZCB8fCB5ID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0byA9IGEub2Zmc2V0KCk7XG5cdFx0XHRcdHggPSBvLmxlZnQ7XG5cdFx0XHRcdHkgPSBvLnRvcCArIHRoaXMuX2RhdGEuY29yZS5saV9oZWlnaHQ7XG5cdFx0XHR9XG5cdFx0XHRpZih0aGlzLnNldHRpbmdzLmNvbnRleHRtZW51LnNlbGVjdF9ub2RlICYmICF0aGlzLmlzX3NlbGVjdGVkKG9iaikpIHtcblx0XHRcdFx0dGhpcy5hY3RpdmF0ZV9ub2RlKG9iaiwgZSk7XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBzLml0ZW1zO1xuXHRcdFx0aWYoJC52YWthdGEuaXNfZnVuY3Rpb24oaSkpIHtcblx0XHRcdFx0aSA9IGkuY2FsbCh0aGlzLCBvYmosIGZ1bmN0aW9uIChpKSB7XG5cdFx0XHRcdFx0dGhpcy5fc2hvd19jb250ZXh0bWVudShvYmosIHgsIHksIGkpO1xuXHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0fVxuXHRcdFx0aWYoJC5pc1BsYWluT2JqZWN0KGkpKSB7XG5cdFx0XHRcdHRoaXMuX3Nob3dfY29udGV4dG1lbnUob2JqLCB4LCB5LCBpKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHNob3cgdGhlIHByZXBhcmVkIGNvbnRleHQgbWVudSBmb3IgYSBub2RlXG5cdFx0ICogQG5hbWUgX3Nob3dfY29udGV4dG1lbnUob2JqLCB4LCB5LCBpKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZVxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSB4IHRoZSB4LWNvb3JkaW5hdGUgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50IHRvIHNob3cgdGhlIG1lbnUgYXRcblx0XHQgKiBAcGFyYW0ge051bWJlcn0geSB0aGUgeS1jb29yZGluYXRlIHJlbGF0aXZlIHRvIHRoZSBkb2N1bWVudCB0byBzaG93IHRoZSBtZW51IGF0XG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IGkgdGhlIG9iamVjdCBvZiBpdGVtcyB0byBzaG93XG5cdFx0ICogQHBsdWdpbiBjb250ZXh0bWVudVxuXHRcdCAqIEB0cmlnZ2VyIHNob3dfY29udGV4dG1lbnUuanN0cmVlXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHR0aGlzLl9zaG93X2NvbnRleHRtZW51ID0gZnVuY3Rpb24gKG9iaiwgeCwgeSwgaSkge1xuXHRcdFx0dmFyIGQgPSB0aGlzLmdldF9ub2RlKG9iaiwgdHJ1ZSksXG5cdFx0XHRcdGEgPSBkLmNoaWxkcmVuKFwiLmpzdHJlZS1hbmNob3JcIik7XG5cdFx0XHQkKGRvY3VtZW50KS5vbmUoXCJjb250ZXh0X3Nob3cudmFrYXRhLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHR2YXIgY2xzID0gJ2pzdHJlZS1jb250ZXh0bWVudSBqc3RyZWUtJyArIHRoaXMuZ2V0X3RoZW1lKCkgKyAnLWNvbnRleHRtZW51Jztcblx0XHRcdFx0JChkYXRhLmVsZW1lbnQpLmFkZENsYXNzKGNscyk7XG5cdFx0XHRcdGEuYWRkQ2xhc3MoJ2pzdHJlZS1jb250ZXh0Jyk7XG5cdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0dGhpcy5fZGF0YS5jb250ZXh0bWVudS52aXNpYmxlID0gdHJ1ZTtcblx0XHRcdCQudmFrYXRhLmNvbnRleHQuc2hvdyhhLCB7ICd4JyA6IHgsICd5JyA6IHkgfSwgaSk7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCB3aGVuIHRoZSBjb250ZXh0bWVudSBpcyBzaG93biBmb3IgYSBub2RlXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIHNob3dfY29udGV4dG1lbnUuanN0cmVlXG5cdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZSB0aGUgbm9kZVxuXHRcdFx0ICogQHBhcmFtIHtOdW1iZXJ9IHggdGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgbWVudSByZWxhdGl2ZSB0byB0aGUgZG9jdW1lbnRcblx0XHRcdCAqIEBwYXJhbSB7TnVtYmVyfSB5IHRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIG1lbnUgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50XG5cdFx0XHQgKiBAcGx1Z2luIGNvbnRleHRtZW51XG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignc2hvd19jb250ZXh0bWVudScsIHsgXCJub2RlXCIgOiBvYmosIFwieFwiIDogeCwgXCJ5XCIgOiB5IH0pO1xuXHRcdH07XG5cdH07XG5cblx0Ly8gY29udGV4dG1lbnUgaGVscGVyXG5cdChmdW5jdGlvbiAoJCkge1xuXHRcdHZhciByaWdodF90b19sZWZ0ID0gZmFsc2UsXG5cdFx0XHR2YWthdGFfY29udGV4dCA9IHtcblx0XHRcdFx0ZWxlbWVudFx0XHQ6IGZhbHNlLFxuXHRcdFx0XHRyZWZlcmVuY2VcdDogZmFsc2UsXG5cdFx0XHRcdHBvc2l0aW9uX3hcdDogMCxcblx0XHRcdFx0cG9zaXRpb25feVx0OiAwLFxuXHRcdFx0XHRpdGVtc1x0XHQ6IFtdLFxuXHRcdFx0XHRodG1sXHRcdDogXCJcIixcblx0XHRcdFx0aXNfdmlzaWJsZVx0OiBmYWxzZVxuXHRcdFx0fTtcblxuXHRcdCQudmFrYXRhLmNvbnRleHQgPSB7XG5cdFx0XHRzZXR0aW5ncyA6IHtcblx0XHRcdFx0aGlkZV9vbm1vdXNlbGVhdmVcdDogMCxcblx0XHRcdFx0aWNvbnNcdFx0XHRcdDogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdF90cmlnZ2VyIDogZnVuY3Rpb24gKGV2ZW50X25hbWUpIHtcblx0XHRcdFx0JChkb2N1bWVudCkudHJpZ2dlckhhbmRsZXIoXCJjb250ZXh0X1wiICsgZXZlbnRfbmFtZSArIFwiLnZha2F0YVwiLCB7XG5cdFx0XHRcdFx0XCJyZWZlcmVuY2VcIlx0OiB2YWthdGFfY29udGV4dC5yZWZlcmVuY2UsXG5cdFx0XHRcdFx0XCJlbGVtZW50XCJcdDogdmFrYXRhX2NvbnRleHQuZWxlbWVudCxcblx0XHRcdFx0XHRcInBvc2l0aW9uXCJcdDoge1xuXHRcdFx0XHRcdFx0XCJ4XCIgOiB2YWthdGFfY29udGV4dC5wb3NpdGlvbl94LFxuXHRcdFx0XHRcdFx0XCJ5XCIgOiB2YWthdGFfY29udGV4dC5wb3NpdGlvbl95XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH0sXG5cdFx0XHRfZXhlY3V0ZSA6IGZ1bmN0aW9uIChpKSB7XG5cdFx0XHRcdGkgPSB2YWthdGFfY29udGV4dC5pdGVtc1tpXTtcblx0XHRcdFx0cmV0dXJuIGkgJiYgKCFpLl9kaXNhYmxlZCB8fCAoJC52YWthdGEuaXNfZnVuY3Rpb24oaS5fZGlzYWJsZWQpICYmICFpLl9kaXNhYmxlZCh7IFwiaXRlbVwiIDogaSwgXCJyZWZlcmVuY2VcIiA6IHZha2F0YV9jb250ZXh0LnJlZmVyZW5jZSwgXCJlbGVtZW50XCIgOiB2YWthdGFfY29udGV4dC5lbGVtZW50IH0pKSkgJiYgaS5hY3Rpb24gPyBpLmFjdGlvbi5jYWxsKG51bGwsIHtcblx0XHRcdFx0XHRcdFx0XCJpdGVtXCJcdFx0OiBpLFxuXHRcdFx0XHRcdFx0XHRcInJlZmVyZW5jZVwiXHQ6IHZha2F0YV9jb250ZXh0LnJlZmVyZW5jZSxcblx0XHRcdFx0XHRcdFx0XCJlbGVtZW50XCJcdDogdmFrYXRhX2NvbnRleHQuZWxlbWVudCxcblx0XHRcdFx0XHRcdFx0XCJwb3NpdGlvblwiXHQ6IHtcblx0XHRcdFx0XHRcdFx0XHRcInhcIiA6IHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3gsXG5cdFx0XHRcdFx0XHRcdFx0XCJ5XCIgOiB2YWthdGFfY29udGV4dC5wb3NpdGlvbl95XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pIDogZmFsc2U7XG5cdFx0XHR9LFxuXHRcdFx0X3BhcnNlIDogZnVuY3Rpb24gKG8sIGlzX2NhbGxiYWNrKSB7XG5cdFx0XHRcdGlmKCFvKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0XHRpZighaXNfY2FsbGJhY2spIHtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5odG1sXHRcdD0gXCJcIjtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5pdGVtc1x0PSBbXTtcblx0XHRcdFx0fVxuXHRcdFx0XHR2YXIgc3RyID0gXCJcIixcblx0XHRcdFx0XHRzZXAgPSBmYWxzZSxcblx0XHRcdFx0XHR0bXA7XG5cblx0XHRcdFx0aWYoaXNfY2FsbGJhY2spIHsgc3RyICs9IFwiPFwiK1widWw+XCI7IH1cblx0XHRcdFx0JC5lYWNoKG8sIGZ1bmN0aW9uIChpLCB2YWwpIHtcblx0XHRcdFx0XHRpZighdmFsKSB7IHJldHVybiB0cnVlOyB9XG5cdFx0XHRcdFx0dmFrYXRhX2NvbnRleHQuaXRlbXMucHVzaCh2YWwpO1xuXHRcdFx0XHRcdGlmKCFzZXAgJiYgdmFsLnNlcGFyYXRvcl9iZWZvcmUpIHtcblx0XHRcdFx0XHRcdHN0ciArPSBcIjxcIitcImxpIGNsYXNzPSd2YWthdGEtY29udGV4dC1zZXBhcmF0b3InPjxcIitcImEgaHJlZj0nIycgXCIgKyAoJC52YWthdGEuY29udGV4dC5zZXR0aW5ncy5pY29ucyA/ICcnIDogJ2NsYXNzPVwidmFrYXRhLWNvbnRleHQtbm8taWNvbnNcIicpICsgXCI+JiMxNjA7PFwiK1wiL2E+PFwiK1wiL2xpPlwiO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRzZXAgPSBmYWxzZTtcblx0XHRcdFx0XHRzdHIgKz0gXCI8XCIrXCJsaSBjbGFzcz0nXCIgKyAodmFsLl9jbGFzcyB8fCBcIlwiKSArICh2YWwuX2Rpc2FibGVkID09PSB0cnVlIHx8ICgkLnZha2F0YS5pc19mdW5jdGlvbih2YWwuX2Rpc2FibGVkKSAmJiB2YWwuX2Rpc2FibGVkKHsgXCJpdGVtXCIgOiB2YWwsIFwicmVmZXJlbmNlXCIgOiB2YWthdGFfY29udGV4dC5yZWZlcmVuY2UsIFwiZWxlbWVudFwiIDogdmFrYXRhX2NvbnRleHQuZWxlbWVudCB9KSkgPyBcIiB2YWthdGEtY29udGV4dG1lbnUtZGlzYWJsZWQgXCIgOiBcIlwiKSArIFwiJyBcIisodmFsLnNob3J0Y3V0P1wiIGRhdGEtc2hvcnRjdXQ9J1wiK3ZhbC5zaG9ydGN1dCtcIicgXCI6JycpK1wiPlwiO1xuXHRcdFx0XHRcdHN0ciArPSBcIjxcIitcImEgaHJlZj0nIycgcmVsPSdcIiArICh2YWthdGFfY29udGV4dC5pdGVtcy5sZW5ndGggLSAxKSArIFwiJyBcIiArICh2YWwudGl0bGUgPyBcInRpdGxlPSdcIiArIHZhbC50aXRsZSArIFwiJ1wiIDogXCJcIikgKyBcIj5cIjtcblx0XHRcdFx0XHRpZigkLnZha2F0YS5jb250ZXh0LnNldHRpbmdzLmljb25zKSB7XG5cdFx0XHRcdFx0XHRzdHIgKz0gXCI8XCIrXCJpIFwiO1xuXHRcdFx0XHRcdFx0aWYodmFsLmljb24pIHtcblx0XHRcdFx0XHRcdFx0aWYodmFsLmljb24uaW5kZXhPZihcIi9cIikgIT09IC0xIHx8IHZhbC5pY29uLmluZGV4T2YoXCIuXCIpICE9PSAtMSkgeyBzdHIgKz0gXCIgc3R5bGU9J2JhY2tncm91bmQ6dXJsKFxcXCJcIiArIHZhbC5pY29uICsgXCJcXFwiKSBjZW50ZXIgY2VudGVyIG5vLXJlcGVhdCcgXCI7IH1cblx0XHRcdFx0XHRcdFx0ZWxzZSB7IHN0ciArPSBcIiBjbGFzcz0nXCIgKyB2YWwuaWNvbiArIFwiJyBcIjsgfVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0c3RyICs9IFwiPjxcIitcIi9pPjxcIitcInNwYW4gY2xhc3M9J3Zha2F0YS1jb250ZXh0bWVudS1zZXAnPiYjMTYwOzxcIitcIi9zcGFuPlwiO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRzdHIgKz0gKCQudmFrYXRhLmlzX2Z1bmN0aW9uKHZhbC5sYWJlbCkgPyB2YWwubGFiZWwoeyBcIml0ZW1cIiA6IGksIFwicmVmZXJlbmNlXCIgOiB2YWthdGFfY29udGV4dC5yZWZlcmVuY2UsIFwiZWxlbWVudFwiIDogdmFrYXRhX2NvbnRleHQuZWxlbWVudCB9KSA6IHZhbC5sYWJlbCkgKyAodmFsLnNob3J0Y3V0PycgPHNwYW4gY2xhc3M9XCJ2YWthdGEtY29udGV4dG1lbnUtc2hvcnRjdXQgdmFrYXRhLWNvbnRleHRtZW51LXNob3J0Y3V0LScrdmFsLnNob3J0Y3V0KydcIj4nKyAodmFsLnNob3J0Y3V0X2xhYmVsIHx8ICcnKSArJzwvc3Bhbj4nOicnKSArIFwiPFwiK1wiL2E+XCI7XG5cdFx0XHRcdFx0aWYodmFsLnN1Ym1lbnUpIHtcblx0XHRcdFx0XHRcdHRtcCA9ICQudmFrYXRhLmNvbnRleHQuX3BhcnNlKHZhbC5zdWJtZW51LCB0cnVlKTtcblx0XHRcdFx0XHRcdGlmKHRtcCkgeyBzdHIgKz0gdG1wOyB9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHN0ciArPSBcIjxcIitcIi9saT5cIjtcblx0XHRcdFx0XHRpZih2YWwuc2VwYXJhdG9yX2FmdGVyKSB7XG5cdFx0XHRcdFx0XHRzdHIgKz0gXCI8XCIrXCJsaSBjbGFzcz0ndmFrYXRhLWNvbnRleHQtc2VwYXJhdG9yJz48XCIrXCJhIGhyZWY9JyMnIFwiICsgKCQudmFrYXRhLmNvbnRleHQuc2V0dGluZ3MuaWNvbnMgPyAnJyA6ICdjbGFzcz1cInZha2F0YS1jb250ZXh0LW5vLWljb25zXCInKSArIFwiPiYjMTYwOzxcIitcIi9hPjxcIitcIi9saT5cIjtcblx0XHRcdFx0XHRcdHNlcCA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c3RyICA9IHN0ci5yZXBsYWNlKC88bGkgY2xhc3NcXD0ndmFrYXRhLWNvbnRleHQtc2VwYXJhdG9yJ1xcPjxcXC9saVxcPiQvLFwiXCIpO1xuXHRcdFx0XHRpZihpc19jYWxsYmFjaykgeyBzdHIgKz0gXCI8L3VsPlwiOyB9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgb24gdGhlIGRvY3VtZW50IHdoZW4gdGhlIGNvbnRleHRtZW51IGlzIHBhcnNlZCAoSFRNTCBpcyBidWlsdClcblx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdCAqIEBwbHVnaW4gY29udGV4dG1lbnVcblx0XHRcdFx0ICogQG5hbWUgY29udGV4dF9wYXJzZS52YWthdGFcblx0XHRcdFx0ICogQHBhcmFtIHtqUXVlcnl9IHJlZmVyZW5jZSB0aGUgZWxlbWVudCB0aGF0IHdhcyByaWdodCBjbGlja2VkXG5cdFx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSBlbGVtZW50IHRoZSBET00gZWxlbWVudCBvZiB0aGUgbWVudSBpdHNlbGZcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IHBvc2l0aW9uIHRoZSB4ICYgeSBjb29yZGluYXRlcyBvZiB0aGUgbWVudVxuXHRcdFx0XHQgKi9cblx0XHRcdFx0aWYoIWlzX2NhbGxiYWNrKSB7IHZha2F0YV9jb250ZXh0Lmh0bWwgPSBzdHI7ICQudmFrYXRhLmNvbnRleHQuX3RyaWdnZXIoXCJwYXJzZVwiKTsgfVxuXHRcdFx0XHRyZXR1cm4gc3RyLmxlbmd0aCA+IDEwID8gc3RyIDogZmFsc2U7XG5cdFx0XHR9LFxuXHRcdFx0X3Nob3dfc3VibWVudSA6IGZ1bmN0aW9uIChvKSB7XG5cdFx0XHRcdG8gPSAkKG8pO1xuXHRcdFx0XHRpZighby5sZW5ndGggfHwgIW8uY2hpbGRyZW4oXCJ1bFwiKS5sZW5ndGgpIHsgcmV0dXJuOyB9XG5cdFx0XHRcdHZhciBlID0gby5jaGlsZHJlbihcInVsXCIpLFxuXHRcdFx0XHRcdHhsID0gby5vZmZzZXQoKS5sZWZ0LFxuXHRcdFx0XHRcdHggPSB4bCArIG8ub3V0ZXJXaWR0aCgpLFxuXHRcdFx0XHRcdHkgPSBvLm9mZnNldCgpLnRvcCxcblx0XHRcdFx0XHR3ID0gZS53aWR0aCgpLFxuXHRcdFx0XHRcdGggPSBlLmhlaWdodCgpLFxuXHRcdFx0XHRcdGR3ID0gJCh3aW5kb3cpLndpZHRoKCkgKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpLFxuXHRcdFx0XHRcdGRoID0gJCh3aW5kb3cpLmhlaWdodCgpICsgJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuXHRcdFx0XHQvLyDQvNC+0LbQtSDQtNCwINGB0LUg0YHQv9C10YHRgtC4INC1INC10LTQvdCwINC/0YDQvtCy0LXRgNC60LAgLSDQtNCw0LvQuCDQvdGP0LzQsCDQvdGP0LrQvtC5INC+0YIg0LrQu9Cw0YHQvtCy0LXRgtC1INCy0LXRh9C1INC90LDQs9C+0YDQtVxuXHRcdFx0XHRpZihyaWdodF90b19sZWZ0KSB7XG5cdFx0XHRcdFx0b1t4IC0gKHcgKyAxMCArIG8ub3V0ZXJXaWR0aCgpKSA8IDAgPyBcImFkZENsYXNzXCIgOiBcInJlbW92ZUNsYXNzXCJdKFwidmFrYXRhLWNvbnRleHQtbGVmdFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRvW3ggKyB3ID4gZHcgICYmIHhsID4gZHcgLSB4ID8gXCJhZGRDbGFzc1wiIDogXCJyZW1vdmVDbGFzc1wiXShcInZha2F0YS1jb250ZXh0LXJpZ2h0XCIpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKHkgKyBoICsgMTAgPiBkaCkge1xuXHRcdFx0XHRcdGUuY3NzKFwiYm90dG9tXCIsXCItMXB4XCIpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9pZiBkb2VzIG5vdCBmaXQgLSBzdGljayBpdCB0byB0aGUgc2lkZVxuXHRcdFx0XHRpZiAoby5oYXNDbGFzcygndmFrYXRhLWNvbnRleHQtcmlnaHQnKSkge1xuXHRcdFx0XHRcdGlmICh4bCA8IHcpIHtcblx0XHRcdFx0XHRcdGUuY3NzKFwibWFyZ2luLXJpZ2h0XCIsIHhsIC0gdyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmIChkdyAtIHggPCB3KSB7XG5cdFx0XHRcdFx0XHRlLmNzcyhcIm1hcmdpbi1sZWZ0XCIsIGR3IC0geCAtIHcpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGUuc2hvdygpO1xuXHRcdFx0fSxcblx0XHRcdHNob3cgOiBmdW5jdGlvbiAocmVmZXJlbmNlLCBwb3NpdGlvbiwgZGF0YSkge1xuXHRcdFx0XHR2YXIgbywgZSwgeCwgeSwgdywgaCwgZHcsIGRoLCBjb25kID0gdHJ1ZTtcblx0XHRcdFx0aWYodmFrYXRhX2NvbnRleHQuZWxlbWVudCAmJiB2YWthdGFfY29udGV4dC5lbGVtZW50Lmxlbmd0aCkge1xuXHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LmVsZW1lbnQud2lkdGgoJycpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHN3aXRjaChjb25kKSB7XG5cdFx0XHRcdFx0Y2FzZSAoIXBvc2l0aW9uICYmICFyZWZlcmVuY2UpOlxuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdGNhc2UgKCEhcG9zaXRpb24gJiYgISFyZWZlcmVuY2UpOlxuXHRcdFx0XHRcdFx0dmFrYXRhX2NvbnRleHQucmVmZXJlbmNlXHQ9IHJlZmVyZW5jZTtcblx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3hcdD0gcG9zaXRpb24ueDtcblx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3lcdD0gcG9zaXRpb24ueTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgKCFwb3NpdGlvbiAmJiAhIXJlZmVyZW5jZSk6XG5cdFx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5yZWZlcmVuY2VcdD0gcmVmZXJlbmNlO1xuXHRcdFx0XHRcdFx0byA9IHJlZmVyZW5jZS5vZmZzZXQoKTtcblx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3hcdD0gby5sZWZ0ICsgcmVmZXJlbmNlLm91dGVySGVpZ2h0KCk7XG5cdFx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5wb3NpdGlvbl95XHQ9IG8udG9wO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAoISFwb3NpdGlvbiAmJiAhcmVmZXJlbmNlKTpcblx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3hcdD0gcG9zaXRpb24ueDtcblx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LnBvc2l0aW9uX3lcdD0gcG9zaXRpb24ueTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKCEhcmVmZXJlbmNlICYmICFkYXRhICYmICQocmVmZXJlbmNlKS5kYXRhKCd2YWthdGFfY29udGV4dG1lbnUnKSkge1xuXHRcdFx0XHRcdGRhdGEgPSAkKHJlZmVyZW5jZSkuZGF0YSgndmFrYXRhX2NvbnRleHRtZW51Jyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoJC52YWthdGEuY29udGV4dC5fcGFyc2UoZGF0YSkpIHtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50Lmh0bWwodmFrYXRhX2NvbnRleHQuaHRtbCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYodmFrYXRhX2NvbnRleHQuaXRlbXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0dmFrYXRhX2NvbnRleHQuZWxlbWVudC5hcHBlbmRUbyhkb2N1bWVudC5ib2R5KTtcblx0XHRcdFx0XHRlID0gdmFrYXRhX2NvbnRleHQuZWxlbWVudDtcblx0XHRcdFx0XHR4ID0gdmFrYXRhX2NvbnRleHQucG9zaXRpb25feDtcblx0XHRcdFx0XHR5ID0gdmFrYXRhX2NvbnRleHQucG9zaXRpb25feTtcblx0XHRcdFx0XHR3ID0gZS53aWR0aCgpO1xuXHRcdFx0XHRcdGggPSBlLmhlaWdodCgpO1xuXHRcdFx0XHRcdGR3ID0gJCh3aW5kb3cpLndpZHRoKCkgKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpO1xuXHRcdFx0XHRcdGRoID0gJCh3aW5kb3cpLmhlaWdodCgpICsgJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuXHRcdFx0XHRcdGlmKHJpZ2h0X3RvX2xlZnQpIHtcblx0XHRcdFx0XHRcdHggLT0gKGUub3V0ZXJXaWR0aCgpIC0gJChyZWZlcmVuY2UpLm91dGVyV2lkdGgoKSk7XG5cdFx0XHRcdFx0XHRpZih4IDwgJCh3aW5kb3cpLnNjcm9sbExlZnQoKSArIDIwKSB7XG5cdFx0XHRcdFx0XHRcdHggPSAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpICsgMjA7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKHggKyB3ICsgMjAgPiBkdykge1xuXHRcdFx0XHRcdFx0eCA9IGR3IC0gKHcgKyAyMCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmKHkgKyBoICsgMjAgPiBkaCkge1xuXHRcdFx0XHRcdFx0eSA9IGRoIC0gKGggKyAyMCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dmFrYXRhX2NvbnRleHQuZWxlbWVudFxuXHRcdFx0XHRcdFx0LmNzcyh7IFwibGVmdFwiIDogeCwgXCJ0b3BcIiA6IHkgfSlcblx0XHRcdFx0XHRcdC5zaG93KClcblx0XHRcdFx0XHRcdC5maW5kKCdhJykuZmlyc3QoKS50cmlnZ2VyKCdmb2N1cycpLnBhcmVudCgpLmFkZENsYXNzKFwidmFrYXRhLWNvbnRleHQtaG92ZXJcIik7XG5cdFx0XHRcdFx0dmFrYXRhX2NvbnRleHQuaXNfdmlzaWJsZSA9IHRydWU7XG5cdFx0XHRcdFx0LyoqXG5cdFx0XHRcdFx0ICogdHJpZ2dlcmVkIG9uIHRoZSBkb2N1bWVudCB3aGVuIHRoZSBjb250ZXh0bWVudSBpcyBzaG93blxuXHRcdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHRcdCAqIEBwbHVnaW4gY29udGV4dG1lbnVcblx0XHRcdFx0XHQgKiBAbmFtZSBjb250ZXh0X3Nob3cudmFrYXRhXG5cdFx0XHRcdFx0ICogQHBhcmFtIHtqUXVlcnl9IHJlZmVyZW5jZSB0aGUgZWxlbWVudCB0aGF0IHdhcyByaWdodCBjbGlja2VkXG5cdFx0XHRcdFx0ICogQHBhcmFtIHtqUXVlcnl9IGVsZW1lbnQgdGhlIERPTSBlbGVtZW50IG9mIHRoZSBtZW51IGl0c2VsZlxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBwb3NpdGlvbiB0aGUgeCAmIHkgY29vcmRpbmF0ZXMgb2YgdGhlIG1lbnVcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHQkLnZha2F0YS5jb250ZXh0Ll90cmlnZ2VyKFwic2hvd1wiKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGhpZGUgOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmKHZha2F0YV9jb250ZXh0LmlzX3Zpc2libGUpIHtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50LmhpZGUoKS5maW5kKFwidWxcIikuaGlkZSgpLmVuZCgpLmZpbmQoJzpmb2N1cycpLnRyaWdnZXIoJ2JsdXInKS5lbmQoKS5kZXRhY2goKTtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5pc192aXNpYmxlID0gZmFsc2U7XG5cdFx0XHRcdFx0LyoqXG5cdFx0XHRcdFx0ICogdHJpZ2dlcmVkIG9uIHRoZSBkb2N1bWVudCB3aGVuIHRoZSBjb250ZXh0bWVudSBpcyBoaWRkZW5cblx0XHRcdFx0XHQgKiBAZXZlbnRcblx0XHRcdFx0XHQgKiBAcGx1Z2luIGNvbnRleHRtZW51XG5cdFx0XHRcdFx0ICogQG5hbWUgY29udGV4dF9oaWRlLnZha2F0YVxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSByZWZlcmVuY2UgdGhlIGVsZW1lbnQgdGhhdCB3YXMgcmlnaHQgY2xpY2tlZFxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSBlbGVtZW50IHRoZSBET00gZWxlbWVudCBvZiB0aGUgbWVudSBpdHNlbGZcblx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gcG9zaXRpb24gdGhlIHggJiB5IGNvb3JkaW5hdGVzIG9mIHRoZSBtZW51XG5cdFx0XHRcdFx0ICovXG5cdFx0XHRcdFx0JC52YWthdGEuY29udGV4dC5fdHJpZ2dlcihcImhpZGVcIik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHRcdCQoZnVuY3Rpb24gKCkge1xuXHRcdFx0cmlnaHRfdG9fbGVmdCA9ICQoZG9jdW1lbnQuYm9keSkuY3NzKFwiZGlyZWN0aW9uXCIpID09PSBcInJ0bFwiO1xuXHRcdFx0dmFyIHRvID0gZmFsc2U7XG5cblx0XHRcdHZha2F0YV9jb250ZXh0LmVsZW1lbnQgPSAkKFwiPHVsIGNsYXNzPSd2YWthdGEtY29udGV4dCc+PC91bD5cIik7XG5cdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50XG5cdFx0XHRcdC5vbihcIm1vdXNlZW50ZXJcIiwgXCJsaVwiLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cblx0XHRcdFx0XHRpZigkLmNvbnRhaW5zKHRoaXMsIGUucmVsYXRlZFRhcmdldCkpIHtcblx0XHRcdFx0XHRcdC8vINC/0YDQtdC80LDRhdC90LDRgtC+INC30LDRgNCw0LTQuCBkZWxlZ2F0ZSBtb3VzZWxlYXZlINC/0L4t0LTQvtC70YNcblx0XHRcdFx0XHRcdC8vICQodGhpcykuZmluZChcIi52YWthdGEtY29udGV4dC1ob3ZlclwiKS5yZW1vdmVDbGFzcyhcInZha2F0YS1jb250ZXh0LWhvdmVyXCIpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmKHRvKSB7IGNsZWFyVGltZW91dCh0byk7IH1cblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50LmZpbmQoXCIudmFrYXRhLWNvbnRleHQtaG92ZXJcIikucmVtb3ZlQ2xhc3MoXCJ2YWthdGEtY29udGV4dC1ob3ZlclwiKS5lbmQoKTtcblxuXHRcdFx0XHRcdCQodGhpcylcblx0XHRcdFx0XHRcdC5zaWJsaW5ncygpLmZpbmQoXCJ1bFwiKS5oaWRlKCkuZW5kKCkuZW5kKClcblx0XHRcdFx0XHRcdC5wYXJlbnRzVW50aWwoXCIudmFrYXRhLWNvbnRleHRcIiwgXCJsaVwiKS5hZGRCYWNrKCkuYWRkQ2xhc3MoXCJ2YWthdGEtY29udGV4dC1ob3ZlclwiKTtcblx0XHRcdFx0XHQkLnZha2F0YS5jb250ZXh0Ll9zaG93X3N1Ym1lbnUodGhpcyk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC8vINGC0LXRgdGC0L7QstC+IC0g0LTQsNC70Lgg0L3QtSDQvdCw0YLQvtCy0LDRgNCy0LA/XG5cdFx0XHRcdC5vbihcIm1vdXNlbGVhdmVcIiwgXCJsaVwiLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdGlmKCQuY29udGFpbnModGhpcywgZS5yZWxhdGVkVGFyZ2V0KSkgeyByZXR1cm47IH1cblx0XHRcdFx0XHQkKHRoaXMpLmZpbmQoXCIudmFrYXRhLWNvbnRleHQtaG92ZXJcIikuYWRkQmFjaygpLnJlbW92ZUNsYXNzKFwidmFrYXRhLWNvbnRleHQtaG92ZXJcIik7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5vbihcIm1vdXNlbGVhdmVcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHQkKHRoaXMpLmZpbmQoXCIudmFrYXRhLWNvbnRleHQtaG92ZXJcIikucmVtb3ZlQ2xhc3MoXCJ2YWthdGEtY29udGV4dC1ob3ZlclwiKTtcblx0XHRcdFx0XHRpZigkLnZha2F0YS5jb250ZXh0LnNldHRpbmdzLmhpZGVfb25tb3VzZWxlYXZlKSB7XG5cdFx0XHRcdFx0XHR0byA9IHNldFRpbWVvdXQoXG5cdFx0XHRcdFx0XHRcdChmdW5jdGlvbiAodCkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbiAoKSB7ICQudmFrYXRhLmNvbnRleHQuaGlkZSgpOyB9O1xuXHRcdFx0XHRcdFx0XHR9KHRoaXMpKSwgJC52YWthdGEuY29udGV4dC5zZXR0aW5ncy5oaWRlX29ubW91c2VsZWF2ZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQub24oXCJjbGlja1wiLCBcImFcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdC8vfSlcblx0XHRcdFx0Ly8ub24oXCJtb3VzZXVwXCIsIFwiYVwiLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdGlmKCEkKHRoaXMpLnRyaWdnZXIoJ2JsdXInKS5wYXJlbnQoKS5oYXNDbGFzcyhcInZha2F0YS1jb250ZXh0LWRpc2FibGVkXCIpICYmICQudmFrYXRhLmNvbnRleHQuX2V4ZWN1dGUoJCh0aGlzKS5hdHRyKFwicmVsXCIpKSAhPT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdCQudmFrYXRhLmNvbnRleHQuaGlkZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdFx0Lm9uKCdrZXlkb3duJywgJ2EnLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0dmFyIG8gPSBudWxsO1xuXHRcdFx0XHRcdFx0c3dpdGNoKGUud2hpY2gpIHtcblx0XHRcdFx0XHRcdFx0Y2FzZSAxMzpcblx0XHRcdFx0XHRcdFx0Y2FzZSAzMjpcblx0XHRcdFx0XHRcdFx0XHRlLnR5cGUgPSBcImNsaWNrXCI7XG5cdFx0XHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRcdCQoZS5jdXJyZW50VGFyZ2V0KS50cmlnZ2VyKGUpO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlIDM3OlxuXHRcdFx0XHRcdFx0XHRcdGlmKHZha2F0YV9jb250ZXh0LmlzX3Zpc2libGUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LmVsZW1lbnQuZmluZChcIi52YWthdGEtY29udGV4dC1ob3ZlclwiKS5sYXN0KCkuY2xvc2VzdChcImxpXCIpLmZpcnN0KCkuZmluZChcInVsXCIpLmhpZGUoKS5maW5kKFwiLnZha2F0YS1jb250ZXh0LWhvdmVyXCIpLnJlbW92ZUNsYXNzKFwidmFrYXRhLWNvbnRleHQtaG92ZXJcIikuZW5kKCkuZW5kKCkuY2hpbGRyZW4oJ2EnKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgMzg6XG5cdFx0XHRcdFx0XHRcdFx0aWYodmFrYXRhX2NvbnRleHQuaXNfdmlzaWJsZSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0byA9IHZha2F0YV9jb250ZXh0LmVsZW1lbnQuZmluZChcInVsOnZpc2libGVcIikuYWRkQmFjaygpLmxhc3QoKS5jaGlsZHJlbihcIi52YWthdGEtY29udGV4dC1ob3ZlclwiKS5yZW1vdmVDbGFzcyhcInZha2F0YS1jb250ZXh0LWhvdmVyXCIpLnByZXZBbGwoXCJsaTpub3QoLnZha2F0YS1jb250ZXh0LXNlcGFyYXRvcilcIikuZmlyc3QoKTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKCFvLmxlbmd0aCkgeyBvID0gdmFrYXRhX2NvbnRleHQuZWxlbWVudC5maW5kKFwidWw6dmlzaWJsZVwiKS5hZGRCYWNrKCkubGFzdCgpLmNoaWxkcmVuKFwibGk6bm90KC52YWthdGEtY29udGV4dC1zZXBhcmF0b3IpXCIpLmxhc3QoKTsgfVxuXHRcdFx0XHRcdFx0XHRcdFx0by5hZGRDbGFzcyhcInZha2F0YS1jb250ZXh0LWhvdmVyXCIpLmNoaWxkcmVuKCdhJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdFx0XHRcdFx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlIDM5OlxuXHRcdFx0XHRcdFx0XHRcdGlmKHZha2F0YV9jb250ZXh0LmlzX3Zpc2libGUpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHZha2F0YV9jb250ZXh0LmVsZW1lbnQuZmluZChcIi52YWthdGEtY29udGV4dC1ob3ZlclwiKS5sYXN0KCkuY2hpbGRyZW4oXCJ1bFwiKS5zaG93KCkuY2hpbGRyZW4oXCJsaTpub3QoLnZha2F0YS1jb250ZXh0LXNlcGFyYXRvcilcIikucmVtb3ZlQ2xhc3MoXCJ2YWthdGEtY29udGV4dC1ob3ZlclwiKS5maXJzdCgpLmFkZENsYXNzKFwidmFrYXRhLWNvbnRleHQtaG92ZXJcIikuY2hpbGRyZW4oJ2EnKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgNDA6XG5cdFx0XHRcdFx0XHRcdFx0aWYodmFrYXRhX2NvbnRleHQuaXNfdmlzaWJsZSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0byA9IHZha2F0YV9jb250ZXh0LmVsZW1lbnQuZmluZChcInVsOnZpc2libGVcIikuYWRkQmFjaygpLmxhc3QoKS5jaGlsZHJlbihcIi52YWthdGEtY29udGV4dC1ob3ZlclwiKS5yZW1vdmVDbGFzcyhcInZha2F0YS1jb250ZXh0LWhvdmVyXCIpLm5leHRBbGwoXCJsaTpub3QoLnZha2F0YS1jb250ZXh0LXNlcGFyYXRvcilcIikuZmlyc3QoKTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKCFvLmxlbmd0aCkgeyBvID0gdmFrYXRhX2NvbnRleHQuZWxlbWVudC5maW5kKFwidWw6dmlzaWJsZVwiKS5hZGRCYWNrKCkubGFzdCgpLmNoaWxkcmVuKFwibGk6bm90KC52YWthdGEtY29udGV4dC1zZXBhcmF0b3IpXCIpLmZpcnN0KCk7IH1cblx0XHRcdFx0XHRcdFx0XHRcdG8uYWRkQ2xhc3MoXCJ2YWthdGEtY29udGV4dC1ob3ZlclwiKS5jaGlsZHJlbignYScpLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0Y2FzZSAyNzpcblx0XHRcdFx0XHRcdFx0XHQkLnZha2F0YS5jb250ZXh0LmhpZGUoKTtcblx0XHRcdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRcdFx0Ly9jb25zb2xlLmxvZyhlLndoaWNoKTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0XHQub24oJ2tleWRvd24nLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHR2YXIgYSA9IHZha2F0YV9jb250ZXh0LmVsZW1lbnQuZmluZCgnLnZha2F0YS1jb250ZXh0bWVudS1zaG9ydGN1dC0nICsgZS53aGljaCkucGFyZW50KCk7XG5cdFx0XHRcdFx0aWYoYS5wYXJlbnQoKS5ub3QoJy52YWthdGEtY29udGV4dC1kaXNhYmxlZCcpKSB7XG5cdFx0XHRcdFx0XHRhLnRyaWdnZXIoJ2NsaWNrJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0JChkb2N1bWVudClcblx0XHRcdFx0Lm9uKFwibW91c2Vkb3duLnZha2F0YS5qc3RyZWVcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRpZih2YWthdGFfY29udGV4dC5pc192aXNpYmxlICYmIHZha2F0YV9jb250ZXh0LmVsZW1lbnRbMF0gIT09IGUudGFyZ2V0ICAmJiAhJC5jb250YWlucyh2YWthdGFfY29udGV4dC5lbGVtZW50WzBdLCBlLnRhcmdldCkpIHtcblx0XHRcdFx0XHRcdCQudmFrYXRhLmNvbnRleHQuaGlkZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdFx0Lm9uKFwiY29udGV4dF9zaG93LnZha2F0YS5qc3RyZWVcIiwgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50LmZpbmQoXCJsaTpoYXModWwpXCIpLmNoaWxkcmVuKFwiYVwiKS5hZGRDbGFzcyhcInZha2F0YS1jb250ZXh0LXBhcmVudFwiKTtcblx0XHRcdFx0XHRpZihyaWdodF90b19sZWZ0KSB7XG5cdFx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50LmFkZENsYXNzKFwidmFrYXRhLWNvbnRleHQtcnRsXCIpLmNzcyhcImRpcmVjdGlvblwiLCBcInJ0bFwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gYWxzbyBhcHBseSBhIFJUTCBjbGFzcz9cblx0XHRcdFx0XHR2YWthdGFfY29udGV4dC5lbGVtZW50LmZpbmQoXCJ1bFwiKS5oaWRlKCkuZW5kKCk7XG5cdFx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9KCQpKTtcblx0Ly8gJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2lucy5wdXNoKFwiY29udGV4dG1lbnVcIik7XG5cblxuLyoqXG4gKiAjIyMgRHJhZyduJ2Ryb3AgcGx1Z2luXG4gKlxuICogRW5hYmxlcyBkcmFnZ2luZyBhbmQgZHJvcHBpbmcgb2Ygbm9kZXMgaW4gdGhlIHRyZWUsIHJlc3VsdGluZyBpbiBhIG1vdmUgb3IgY29weSBvcGVyYXRpb25zLlxuICovXG5cblx0LyoqXG5cdCAqIHN0b3JlcyBhbGwgZGVmYXVsdHMgZm9yIHRoZSBkcmFnJ24nZHJvcCBwbHVnaW5cblx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuZG5kXG5cdCAqIEBwbHVnaW4gZG5kXG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy5kbmQgPSB7XG5cdFx0LyoqXG5cdFx0ICogYSBib29sZWFuIGluZGljYXRpbmcgaWYgYSBjb3B5IHNob3VsZCBiZSBwb3NzaWJsZSB3aGlsZSBkcmFnZ2luZyAoYnkgcHJlc3NpbnQgdGhlIG1ldGEga2V5IG9yIEN0cmwpLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuZG5kLmNvcHlcblx0XHQgKiBAcGx1Z2luIGRuZFxuXHRcdCAqL1xuXHRcdGNvcHkgOiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGEgbnVtYmVyIGluZGljYXRpbmcgaG93IGxvbmcgYSBub2RlIHNob3VsZCByZW1haW4gaG92ZXJlZCB3aGlsZSBkcmFnZ2luZyB0byBiZSBvcGVuZWQuIERlZmF1bHRzIHRvIGA1MDBgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5vcGVuX3RpbWVvdXRcblx0XHQgKiBAcGx1Z2luIGRuZFxuXHRcdCAqL1xuXHRcdG9wZW5fdGltZW91dCA6IDUwMCxcblx0XHQvKipcblx0XHQgKiBhIGZ1bmN0aW9uIGludm9rZWQgZWFjaCB0aW1lIGEgbm9kZSBpcyBhYm91dCB0byBiZSBkcmFnZ2VkLCBpbnZva2VkIGluIHRoZSB0cmVlJ3Mgc2NvcGUgYW5kIHJlY2VpdmVzIHRoZSBub2RlcyBhYm91dCB0byBiZSBkcmFnZ2VkIGFzIGFuIGFyZ3VtZW50IChhcnJheSkgYW5kIHRoZSBldmVudCB0aGF0IHN0YXJ0ZWQgdGhlIGRyYWcgLSByZXR1cm4gYGZhbHNlYCB0byBwcmV2ZW50IGRyYWdnaW5nXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuZG5kLmlzX2RyYWdnYWJsZVxuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0aXNfZHJhZ2dhYmxlIDogdHJ1ZSxcblx0XHQvKipcblx0XHQgKiBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBjaGVja3Mgc2hvdWxkIGNvbnN0YW50bHkgYmUgbWFkZSB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZyB0aGUgbm9kZSAoYXMgb3Bwb3NlZCB0byBjaGVja2luZyBvbmx5IG9uIGRyb3ApLCBkZWZhdWx0IGlzIGB0cnVlYFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5jaGVja193aGlsZV9kcmFnZ2luZ1xuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0Y2hlY2tfd2hpbGVfZHJhZ2dpbmcgOiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIG5vZGVzIGZyb20gdGhpcyB0cmVlIHNob3VsZCBvbmx5IGJlIGNvcGllZCB3aXRoIGRuZCAoYXMgb3Bwb3NlZCB0byBtb3ZlZCksIGRlZmF1bHQgaXMgYGZhbHNlYFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5hbHdheXNfY29weVxuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0YWx3YXlzX2NvcHkgOiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiB3aGVuIGRyb3BwaW5nIGEgbm9kZSBcImluc2lkZVwiLCB0aGlzIHNldHRpbmcgaW5kaWNhdGVzIHRoZSBwb3NpdGlvbiB0aGUgbm9kZSBzaG91bGQgZ28gdG8gLSBpdCBjYW4gYmUgYW4gaW50ZWdlciBvciBhIHN0cmluZzogXCJmaXJzdFwiIChzYW1lIGFzIDApIG9yIFwibGFzdFwiLCBkZWZhdWx0IGlzIGAwYFxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5pbnNpZGVfcG9zXG5cdFx0ICogQHBsdWdpbiBkbmRcblx0XHQgKi9cblx0XHRpbnNpZGVfcG9zIDogMCxcblx0XHQvKipcblx0XHQgKiB3aGVuIHN0YXJ0aW5nIHRoZSBkcmFnIG9uIGEgbm9kZSB0aGF0IGlzIHNlbGVjdGVkIHRoaXMgc2V0dGluZyBjb250cm9scyBpZiBhbGwgc2VsZWN0ZWQgbm9kZXMgYXJlIGRyYWdnZWQgb3Igb25seSB0aGUgc2luZ2xlIG5vZGUsIGRlZmF1bHQgaXMgYHRydWVgLCB3aGljaCBtZWFucyBhbGwgc2VsZWN0ZWQgbm9kZXMgYXJlIGRyYWdnZWQgd2hlbiB0aGUgZHJhZyBpcyBzdGFydGVkIG9uIGEgc2VsZWN0ZWQgbm9kZVxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5kcmFnX3NlbGVjdGlvblxuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0ZHJhZ19zZWxlY3Rpb24gOiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGNvbnRyb2xzIHdoZXRoZXIgZG5kIHdvcmtzIG9uIHRvdWNoIGRldmljZXMuIElmIGxlZnQgYXMgYm9vbGVhbiB0cnVlIGRuZCB3aWxsIHdvcmsgdGhlIHNhbWUgYXMgaW4gZGVza3RvcCBicm93c2Vycywgd2hpY2ggaW4gc29tZSBjYXNlcyBtYXkgaW1wYWlyIHNjcm9sbGluZy4gSWYgc2V0IHRvIGJvb2xlYW4gZmFsc2UgZG5kIHdpbGwgbm90IHdvcmsgb24gdG91Y2ggZGV2aWNlcy4gVGhlcmUgaXMgYSBzcGVjaWFsIHRoaXJkIG9wdGlvbiAtIHN0cmluZyBcInNlbGVjdGVkXCIgd2hpY2ggbWVhbnMgb25seSBzZWxlY3RlZCBub2RlcyBjYW4gYmUgZHJhZ2dlZCBvbiB0b3VjaCBkZXZpY2VzLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC50b3VjaFxuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0dG91Y2ggOiB0cnVlLFxuXHRcdC8qKlxuXHRcdCAqIGNvbnRyb2xzIHdoZXRoZXIgaXRlbXMgY2FuIGJlIGRyb3BwZWQgYW55d2hlcmUgb24gdGhlIG5vZGUsIG5vdCBqdXN0IG9uIHRoZSBhbmNob3IsIGJ5IGRlZmF1bHQgb25seSB0aGUgbm9kZSBhbmNob3IgaXMgYSB2YWxpZCBkcm9wIHRhcmdldC4gV29ya3MgYmVzdCB3aXRoIHRoZSB3aG9sZXJvdyBwbHVnaW4uIElmIGVuYWJsZWQgb24gbW9iaWxlIGRlcGVuZGluZyBvbiB0aGUgaW50ZXJmYWNlIGl0IG1pZ2h0IGJlIGhhcmQgZm9yIHRoZSB1c2VyIHRvIGNhbmNlbCB0aGUgZHJvcCwgc2luY2UgdGhlIHdob2xlIHRyZWUgY29udGFpbmVyIHdpbGwgYmUgYSB2YWxpZCBkcm9wIHRhcmdldC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5kbmQubGFyZ2VfZHJvcF90YXJnZXRcblx0XHQgKiBAcGx1Z2luIGRuZFxuXHRcdCAqL1xuXHRcdGxhcmdlX2Ryb3BfdGFyZ2V0IDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogY29udHJvbHMgd2hldGhlciBhIGRyYWcgY2FuIGJlIGluaXRpYXRlZCBmcm9tIGFueSBwYXJ0IG9mIHRoZSBub2RlIGFuZCBub3QganVzdCB0aGUgdGV4dC9pY29uIHBhcnQsIHdvcmtzIGJlc3Qgd2l0aCB0aGUgd2hvbGVyb3cgcGx1Z2luLiBLZWVwIGluIG1pbmQgaXQgY2FuIGNhdXNlIHByb2JsZW1zIHdpdGggdHJlZSBzY3JvbGxpbmcgb24gbW9iaWxlIGRlcGVuZGluZyBvbiB0aGUgaW50ZXJmYWNlIC0gaW4gdGhhdCBjYXNlIHNldCB0aGUgdG91Y2ggb3B0aW9uIHRvIFwic2VsZWN0ZWRcIi5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5kbmQubGFyZ2VfZHJhZ190YXJnZXRcblx0XHQgKiBAcGx1Z2luIGRuZFxuXHRcdCAqL1xuXHRcdGxhcmdlX2RyYWdfdGFyZ2V0IDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogY29udHJvbHMgd2hldGhlciB1c2UgSFRNTDUgZG5kIGFwaSBpbnN0ZWFkIG9mIGNsYXNzaWNhbC4gVGhhdCB3aWxsIGFsbG93IGJldHRlciBpbnRlZ3JhdGlvbiBvZiBkbmQgZXZlbnRzIHdpdGggb3RoZXIgSFRNTDUgY29udHJvbHMuXG5cdFx0ICogQHJlZmVyZW5jZSBodHRwOi8vY2FuaXVzZS5jb20vI2ZlYXQ9ZHJhZ25kcm9wXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuZG5kLnVzZV9odG1sNVxuXHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0ICovXG5cdFx0dXNlX2h0bWw1OiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBjb250cm9scyB3aGV0aGVyIGl0ZW1zIGNhbiBiZSBkcm9wcGVkIGFueXdoZXJlIG9uIHRoZSB0cmVlLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLmRuZC5ibGFua19zcGFjZV9kcm9wXG5cdFx0ICogQHBsdWdpbiBkbmRcblx0XHQgKi9cblx0XHRibGFua19zcGFjZV9kcm9wOiBmYWxzZVxuXHR9O1xuXHR2YXIgZHJnLCBlbG07XG5cdC8vIFRPRE86IG5vdyBjaGVjayB3b3JrcyBieSBjaGVja2luZyBmb3IgZWFjaCBub2RlIGluZGl2aWR1YWxseSwgaG93IGFib3V0IG1heF9jaGlsZHJlbiwgdW5pcXVlLCBldGM/XG5cdCQuanN0cmVlLnBsdWdpbnMuZG5kID0gZnVuY3Rpb24gKG9wdGlvbnMsIHBhcmVudCkge1xuXHRcdHRoaXMuaW5pdCA9IGZ1bmN0aW9uIChlbCwgb3B0aW9ucykge1xuXHRcdFx0cGFyZW50LmluaXQuY2FsbCh0aGlzLCBlbCwgb3B0aW9ucyk7XG5cdFx0XHR0aGlzLnNldHRpbmdzLmRuZC51c2VfaHRtbDUgPSB0aGlzLnNldHRpbmdzLmRuZC51c2VfaHRtbDUgJiYgKCdkcmFnZ2FibGUnIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKSk7XG5cdFx0fTtcblx0XHR0aGlzLmJpbmQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRwYXJlbnQuYmluZC5jYWxsKHRoaXMpO1xuXG5cdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0Lm9uKHRoaXMuc2V0dGluZ3MuZG5kLnVzZV9odG1sNSA/ICdkcmFnc3RhcnQuanN0cmVlJyA6ICdtb3VzZWRvd24uanN0cmVlIHRvdWNoc3RhcnQuanN0cmVlJywgdGhpcy5zZXR0aW5ncy5kbmQubGFyZ2VfZHJhZ190YXJnZXQgPyAnLmpzdHJlZS1ub2RlJyA6ICcuanN0cmVlLWFuY2hvcicsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZih0aGlzLnNldHRpbmdzLmRuZC5sYXJnZV9kcmFnX3RhcmdldCAmJiAkKGUudGFyZ2V0KS5jbG9zZXN0KCcuanN0cmVlLW5vZGUnKVswXSAhPT0gZS5jdXJyZW50VGFyZ2V0KSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYoZS50eXBlID09PSBcInRvdWNoc3RhcnRcIiAmJiAoIXRoaXMuc2V0dGluZ3MuZG5kLnRvdWNoIHx8ICh0aGlzLnNldHRpbmdzLmRuZC50b3VjaCA9PT0gJ3NlbGVjdGVkJyAmJiAhJChlLmN1cnJlbnRUYXJnZXQpLmNsb3Nlc3QoJy5qc3RyZWUtbm9kZScpLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpLmhhc0NsYXNzKCdqc3RyZWUtY2xpY2tlZCcpKSkpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR2YXIgb2JqID0gdGhpcy5nZXRfbm9kZShlLnRhcmdldCksXG5cdFx0XHRcdFx0XHRcdG1sdCA9IHRoaXMuaXNfc2VsZWN0ZWQob2JqKSAmJiB0aGlzLnNldHRpbmdzLmRuZC5kcmFnX3NlbGVjdGlvbiA/IHRoaXMuZ2V0X3RvcF9zZWxlY3RlZCgpLmxlbmd0aCA6IDEsXG5cdFx0XHRcdFx0XHRcdHR4dCA9IChtbHQgPiAxID8gbWx0ICsgJyAnICsgdGhpcy5nZXRfc3RyaW5nKCdub2RlcycpIDogdGhpcy5nZXRfdGV4dChlLmN1cnJlbnRUYXJnZXQpKTtcblx0XHRcdFx0XHRcdGlmKHRoaXMuc2V0dGluZ3MuY29yZS5mb3JjZV90ZXh0KSB7XG5cdFx0XHRcdFx0XHRcdHR4dCA9ICQudmFrYXRhLmh0bWwuZXNjYXBlKHR4dCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZihvYmogJiYgb2JqLmlkICYmIG9iai5pZCAhPT0gJC5qc3RyZWUucm9vdCAmJiAoZS53aGljaCA9PT0gMSB8fCBlLnR5cGUgPT09IFwidG91Y2hzdGFydFwiIHx8IGUudHlwZSA9PT0gXCJkcmFnc3RhcnRcIikgJiZcblx0XHRcdFx0XHRcdFx0KHRoaXMuc2V0dGluZ3MuZG5kLmlzX2RyYWdnYWJsZSA9PT0gdHJ1ZSB8fCAoJC52YWthdGEuaXNfZnVuY3Rpb24odGhpcy5zZXR0aW5ncy5kbmQuaXNfZHJhZ2dhYmxlKSAmJiB0aGlzLnNldHRpbmdzLmRuZC5pc19kcmFnZ2FibGUuY2FsbCh0aGlzLCAobWx0ID4gMSA/IHRoaXMuZ2V0X3RvcF9zZWxlY3RlZCh0cnVlKSA6IFtvYmpdKSwgZSkpKVxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdGRyZyA9IHsgJ2pzdHJlZScgOiB0cnVlLCAnb3JpZ2luJyA6IHRoaXMsICdvYmonIDogdGhpcy5nZXRfbm9kZShvYmosdHJ1ZSksICdub2RlcycgOiBtbHQgPiAxID8gdGhpcy5nZXRfdG9wX3NlbGVjdGVkKCkgOiBbb2JqLmlkXSB9O1xuXHRcdFx0XHRcdFx0XHRlbG0gPSBlLmN1cnJlbnRUYXJnZXQ7XG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLmRuZC51c2VfaHRtbDUpIHtcblx0XHRcdFx0XHRcdFx0XHQkLnZha2F0YS5kbmQuX3RyaWdnZXIoJ3N0YXJ0JywgZSwgeyAnaGVscGVyJzogJCgpLCAnZWxlbWVudCc6IGVsbSwgJ2RhdGEnOiBkcmcgfSk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LnRyaWdnZXIoJ21vdXNlZG93bi5qc3RyZWUnKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gJC52YWthdGEuZG5kLnN0YXJ0KGUsIGRyZywgJzxkaXYgaWQ9XCJqc3RyZWUtZG5kXCIgY2xhc3M9XCJqc3RyZWUtJyArIHRoaXMuZ2V0X3RoZW1lKCkgKyAnIGpzdHJlZS0nICsgdGhpcy5nZXRfdGhlbWUoKSArICctJyArIHRoaXMuZ2V0X3RoZW1lX3ZhcmlhbnQoKSArICcgJyArICggdGhpcy5zZXR0aW5ncy5jb3JlLnRoZW1lcy5yZXNwb25zaXZlID8gJyBqc3RyZWUtZG5kLXJlc3BvbnNpdmUnIDogJycgKSArICdcIj48aSBjbGFzcz1cImpzdHJlZS1pY29uIGpzdHJlZS1lclwiPjwvaT4nICsgdHh0ICsgJzxpbnMgY2xhc3M9XCJqc3RyZWUtY29weVwiPis8L2lucz48L2Rpdj4nKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5kbmQudXNlX2h0bWw1KSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudFxuXHRcdFx0XHRcdC5vbignZHJhZ292ZXIuanN0cmVlJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHQkLnZha2F0YS5kbmQuX3RyaWdnZXIoJ21vdmUnLCBlLCB7ICdoZWxwZXInOiAkKCksICdlbGVtZW50JzogZWxtLCAnZGF0YSc6IGRyZyB9KTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQvLy5vbignZHJhZ2VudGVyLmpzdHJlZScsIHRoaXMuc2V0dGluZ3MuZG5kLmxhcmdlX2Ryb3BfdGFyZ2V0ID8gJy5qc3RyZWUtbm9kZScgOiAnLmpzdHJlZS1hbmNob3InLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0Ly9cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdC8vXHRcdCQudmFrYXRhLmRuZC5fdHJpZ2dlcignbW92ZScsIGUsIHsgJ2hlbHBlcic6ICQoKSwgJ2VsZW1lbnQnOiBlbG0sICdkYXRhJzogZHJnIH0pO1xuXHRcdFx0XHRcdC8vXHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHQvL1x0fSwgdGhpcykpXG5cdFx0XHRcdFx0Lm9uKCdkcm9wLmpzdHJlZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0JC52YWthdGEuZG5kLl90cmlnZ2VyKCdzdG9wJywgZSwgeyAnaGVscGVyJzogJCgpLCAnZWxlbWVudCc6IGVsbSwgJ2RhdGEnOiBkcmcgfSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHR0aGlzLnJlZHJhd19ub2RlID0gZnVuY3Rpb24ob2JqLCBkZWVwLCBjYWxsYmFjaywgZm9yY2VfcmVuZGVyKSB7XG5cdFx0XHRvYmogPSBwYXJlbnQucmVkcmF3X25vZGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHRcdGlmIChvYmogJiYgdGhpcy5zZXR0aW5ncy5kbmQudXNlX2h0bWw1KSB7XG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLmRuZC5sYXJnZV9kcmFnX3RhcmdldCkge1xuXHRcdFx0XHRcdG9iai5zZXRBdHRyaWJ1dGUoJ2RyYWdnYWJsZScsIHRydWUpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHZhciBpLCBqLCB0bXAgPSBudWxsO1xuXHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IG9iai5jaGlsZE5vZGVzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0aWYob2JqLmNoaWxkTm9kZXNbaV0gJiYgb2JqLmNoaWxkTm9kZXNbaV0uY2xhc3NOYW1lICYmIG9iai5jaGlsZE5vZGVzW2ldLmNsYXNzTmFtZS5pbmRleE9mKFwianN0cmVlLWFuY2hvclwiKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdFx0dG1wID0gb2JqLmNoaWxkTm9kZXNbaV07XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZih0bXApIHtcblx0XHRcdFx0XHRcdHRtcC5zZXRBdHRyaWJ1dGUoJ2RyYWdnYWJsZScsIHRydWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9iajtcblx0XHR9O1xuXHR9O1xuXG5cdCQoZnVuY3Rpb24oKSB7XG5cdFx0Ly8gYmluZCBvbmx5IG9uY2UgZm9yIGFsbCBpbnN0YW5jZXNcblx0XHR2YXIgbGFzdG12ID0gZmFsc2UsXG5cdFx0XHRsYXN0ZXIgPSBmYWxzZSxcblx0XHRcdGxhc3RldiA9IGZhbHNlLFxuXHRcdFx0b3BlbnRvID0gZmFsc2UsXG5cdFx0XHRtYXJrZXIgPSAkKCc8ZGl2IGlkPVwianN0cmVlLW1hcmtlclwiPiYjMTYwOzwvZGl2PicpLmhpZGUoKTsgLy8uYXBwZW5kVG8oJ2JvZHknKTtcblxuXHRcdCQoZG9jdW1lbnQpXG5cdFx0XHQub24oJ2RyYWdvdmVyLnZha2F0YS5qc3RyZWUnLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRpZiAoZWxtKSB7XG5cdFx0XHRcdFx0JC52YWthdGEuZG5kLl90cmlnZ2VyKCdtb3ZlJywgZSwgeyAnaGVscGVyJzogJCgpLCAnZWxlbWVudCc6IGVsbSwgJ2RhdGEnOiBkcmcgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQub24oJ2Ryb3AudmFrYXRhLmpzdHJlZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdGlmIChlbG0pIHtcblx0XHRcdFx0XHQkLnZha2F0YS5kbmQuX3RyaWdnZXIoJ3N0b3AnLCBlLCB7ICdoZWxwZXInOiAkKCksICdlbGVtZW50JzogZWxtLCAnZGF0YSc6IGRyZyB9KTtcblx0XHRcdFx0XHRlbG0gPSBudWxsO1xuXHRcdFx0XHRcdGRyZyA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQub24oJ2RuZF9zdGFydC52YWthdGEuanN0cmVlJywgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0bGFzdG12ID0gZmFsc2U7XG5cdFx0XHRcdGxhc3RldiA9IGZhbHNlO1xuXHRcdFx0XHRpZighZGF0YSB8fCAhZGF0YS5kYXRhIHx8ICFkYXRhLmRhdGEuanN0cmVlKSB7IHJldHVybjsgfVxuXHRcdFx0XHRtYXJrZXIuYXBwZW5kVG8oZG9jdW1lbnQuYm9keSk7IC8vLnNob3coKTtcblx0XHRcdH0pXG5cdFx0XHQub24oJ2RuZF9tb3ZlLnZha2F0YS5qc3RyZWUnLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHR2YXIgaXNEaWZmZXJlbnROb2RlID0gZGF0YS5ldmVudC50YXJnZXQgIT09IGxhc3Rldi50YXJnZXQ7XG5cdFx0XHRcdGlmKG9wZW50bykge1xuXHRcdFx0XHRcdGlmICghZGF0YS5ldmVudCB8fCBkYXRhLmV2ZW50LnR5cGUgIT09ICdkcmFnb3ZlcicgfHwgaXNEaWZmZXJlbnROb2RlKSB7XG5cdFx0XHRcdFx0XHRjbGVhclRpbWVvdXQob3BlbnRvKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIWRhdGEgfHwgIWRhdGEuZGF0YSB8fCAhZGF0YS5kYXRhLmpzdHJlZSkgeyByZXR1cm47IH1cblxuXHRcdFx0XHQvLyBpZiB3ZSBhcmUgaG92ZXJpbmcgdGhlIG1hcmtlciBpbWFnZSBkbyBub3RoaW5nIChjYW4gaGFwcGVuIG9uIFwiaW5zaWRlXCIgZHJhZ3MpXG5cdFx0XHRcdGlmKGRhdGEuZXZlbnQudGFyZ2V0LmlkICYmIGRhdGEuZXZlbnQudGFyZ2V0LmlkID09PSAnanN0cmVlLW1hcmtlcicpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0bGFzdGV2ID0gZGF0YS5ldmVudDtcblxuXHRcdFx0XHR2YXIgaW5zID0gJC5qc3RyZWUucmVmZXJlbmNlKGRhdGEuZXZlbnQudGFyZ2V0KSxcblx0XHRcdFx0XHRyZWYgPSBmYWxzZSxcblx0XHRcdFx0XHRvZmYgPSBmYWxzZSxcblx0XHRcdFx0XHRyZWwgPSBmYWxzZSxcblx0XHRcdFx0XHR0bXAsIGwsIHQsIGgsIHAsIGksIG8sIG9rLCB0MSwgdDIsIG9wLCBwcywgcHIsIGlwLCB0bSwgaXNfY29weSwgcG4sIGM7XG5cdFx0XHRcdC8vIGlmIHdlIGFyZSBvdmVyIGFuIGluc3RhbmNlXG5cdFx0XHRcdGlmKGlucyAmJiBpbnMuX2RhdGEgJiYgaW5zLl9kYXRhLmRuZCkge1xuXHRcdFx0XHRcdG1hcmtlci5hdHRyKCdjbGFzcycsICdqc3RyZWUtJyArIGlucy5nZXRfdGhlbWUoKSArICggaW5zLnNldHRpbmdzLmNvcmUudGhlbWVzLnJlc3BvbnNpdmUgPyAnIGpzdHJlZS1kbmQtcmVzcG9uc2l2ZScgOiAnJyApKTtcblx0XHRcdFx0XHRpc19jb3B5ID0gZGF0YS5kYXRhLm9yaWdpbiAmJiAoZGF0YS5kYXRhLm9yaWdpbi5zZXR0aW5ncy5kbmQuYWx3YXlzX2NvcHkgfHwgKGRhdGEuZGF0YS5vcmlnaW4uc2V0dGluZ3MuZG5kLmNvcHkgJiYgKGRhdGEuZXZlbnQubWV0YUtleSB8fCBkYXRhLmV2ZW50LmN0cmxLZXkpKSk7XG5cdFx0XHRcdFx0ZGF0YS5oZWxwZXJcblx0XHRcdFx0XHRcdC5jaGlsZHJlbigpLmF0dHIoJ2NsYXNzJywgJ2pzdHJlZS0nICsgaW5zLmdldF90aGVtZSgpICsgJyBqc3RyZWUtJyArIGlucy5nZXRfdGhlbWUoKSArICctJyArIGlucy5nZXRfdGhlbWVfdmFyaWFudCgpICsgJyAnICsgKCBpbnMuc2V0dGluZ3MuY29yZS50aGVtZXMucmVzcG9uc2l2ZSA/ICcganN0cmVlLWRuZC1yZXNwb25zaXZlJyA6ICcnICkpXG5cdFx0XHRcdFx0XHQuZmluZCgnLmpzdHJlZS1jb3B5JykuZmlyc3QoKVsgaXNfY29weSA/ICdzaG93JyA6ICdoaWRlJyBdKCk7XG5cblx0XHRcdFx0XHQvLyBpZiBhcmUgaG92ZXJpbmcgdGhlIGNvbnRhaW5lciBpdHNlbGYgYWRkIGEgbmV3IHJvb3Qgbm9kZVxuXHRcdFx0XHRcdC8vY29uc29sZS5sb2coZGF0YS5ldmVudCk7XG5cdFx0XHRcdFx0aWYoIChkYXRhLmV2ZW50LnRhcmdldCA9PT0gaW5zLmVsZW1lbnRbMF0gfHwgZGF0YS5ldmVudC50YXJnZXQgPT09IGlucy5nZXRfY29udGFpbmVyX3VsKClbMF0pICYmIChpbnMuZ2V0X2NvbnRhaW5lcl91bCgpLmNoaWxkcmVuKCkubGVuZ3RoID09PSAwIHx8IGlucy5zZXR0aW5ncy5kbmQuYmxhbmtfc3BhY2VfZHJvcCkpIHtcblx0XHRcdFx0XHRcdG9rID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGZvcih0MSA9IDAsIHQyID0gZGF0YS5kYXRhLm5vZGVzLmxlbmd0aDsgdDEgPCB0MjsgdDErKykge1xuXHRcdFx0XHRcdFx0XHRvayA9IG9rICYmIGlucy5jaGVjayggKGRhdGEuZGF0YS5vcmlnaW4gJiYgKGRhdGEuZGF0YS5vcmlnaW4uc2V0dGluZ3MuZG5kLmFsd2F5c19jb3B5IHx8IChkYXRhLmRhdGEub3JpZ2luLnNldHRpbmdzLmRuZC5jb3B5ICYmIChkYXRhLmV2ZW50Lm1ldGFLZXkgfHwgZGF0YS5ldmVudC5jdHJsS2V5KSkgKSA/IFwiY29weV9ub2RlXCIgOiBcIm1vdmVfbm9kZVwiKSwgKGRhdGEuZGF0YS5vcmlnaW4gJiYgZGF0YS5kYXRhLm9yaWdpbiAhPT0gaW5zID8gZGF0YS5kYXRhLm9yaWdpbi5nZXRfbm9kZShkYXRhLmRhdGEubm9kZXNbdDFdKSA6IGRhdGEuZGF0YS5ub2Rlc1t0MV0pLCAkLmpzdHJlZS5yb290LCAnbGFzdCcsIHsgJ2RuZCcgOiB0cnVlLCAncmVmJyA6IGlucy5nZXRfbm9kZSgkLmpzdHJlZS5yb290KSwgJ3BvcycgOiAnaScsICdvcmlnaW4nIDogZGF0YS5kYXRhLm9yaWdpbiwgJ2lzX211bHRpJyA6IChkYXRhLmRhdGEub3JpZ2luICYmIGRhdGEuZGF0YS5vcmlnaW4gIT09IGlucyksICdpc19mb3JlaWduJyA6ICghZGF0YS5kYXRhLm9yaWdpbikgfSk7XG5cdFx0XHRcdFx0XHRcdGlmKCFvaykgeyBicmVhazsgfVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYob2spIHtcblx0XHRcdFx0XHRcdFx0bGFzdG12ID0geyAnaW5zJyA6IGlucywgJ3BhcicgOiAkLmpzdHJlZS5yb290LCAncG9zJyA6ICdsYXN0JyB9O1xuXHRcdFx0XHRcdFx0XHRtYXJrZXIuaGlkZSgpO1xuXHRcdFx0XHRcdFx0XHRkYXRhLmhlbHBlci5maW5kKCcuanN0cmVlLWljb24nKS5maXJzdCgpLnJlbW92ZUNsYXNzKCdqc3RyZWUtZXInKS5hZGRDbGFzcygnanN0cmVlLW9rJyk7XG5cdFx0XHRcdFx0XHRcdGlmIChkYXRhLmV2ZW50Lm9yaWdpbmFsRXZlbnQgJiYgZGF0YS5ldmVudC5vcmlnaW5hbEV2ZW50LmRhdGFUcmFuc2Zlcikge1xuXHRcdFx0XHRcdFx0XHRcdGRhdGEuZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9IGlzX2NvcHkgPyAnY29weScgOiAnbW92ZSc7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdC8vIGlmIHdlIGFyZSBob3ZlcmluZyBhIHRyZWUgbm9kZVxuXHRcdFx0XHRcdFx0cmVmID0gaW5zLnNldHRpbmdzLmRuZC5sYXJnZV9kcm9wX3RhcmdldCA/ICQoZGF0YS5ldmVudC50YXJnZXQpLmNsb3Nlc3QoJy5qc3RyZWUtbm9kZScpLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpIDogJChkYXRhLmV2ZW50LnRhcmdldCkuY2xvc2VzdCgnLmpzdHJlZS1hbmNob3InKTtcblx0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdFx0aWYocmVmICYmIHJlZi5sZW5ndGggJiYgcmVmLnBhcmVudCgpLmlzKCcuanN0cmVlLWNsb3NlZCwgLmpzdHJlZS1vcGVuLCAuanN0cmVlLWxlYWYnKSkge1xuXHRcdFx0XHRcdFx0XHRvZmYgPSByZWYub2Zmc2V0KCk7XG5cdFx0XHRcdFx0XHRcdHJlbCA9IChkYXRhLmV2ZW50LnBhZ2VZICE9PSB1bmRlZmluZWQgPyBkYXRhLmV2ZW50LnBhZ2VZIDogZGF0YS5ldmVudC5vcmlnaW5hbEV2ZW50LnBhZ2VZKSAtIG9mZi50b3A7XG5cdFx0XHRcdFx0XHRcdGggPSByZWYub3V0ZXJIZWlnaHQoKTtcblx0XHRcdFx0XHRcdFx0aWYocmVsIDwgaCAvIDMpIHtcblx0XHRcdFx0XHRcdFx0XHRvID0gWydiJywgJ2knLCAnYSddO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGVsc2UgaWYocmVsID4gaCAtIGggLyAzKSB7XG5cdFx0XHRcdFx0XHRcdFx0byA9IFsnYScsICdpJywgJ2InXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRvID0gcmVsID4gaCAvIDIgPyBbJ2knLCAnYScsICdiJ10gOiBbJ2knLCAnYicsICdhJ107XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0JC5lYWNoKG8sIGZ1bmN0aW9uIChqLCB2KSB7XG5cdFx0XHRcdFx0XHRcdFx0c3dpdGNoKHYpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNhc2UgJ2InOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRsID0gb2ZmLmxlZnQgLSA2O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0ID0gb2ZmLnRvcDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cCA9IGlucy5nZXRfcGFyZW50KHJlZik7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGkgPSByZWYucGFyZW50KCkuaW5kZXgoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YyA9ICdqc3RyZWUtYmVsb3cnO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdGNhc2UgJ2knOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpcCA9IGlucy5zZXR0aW5ncy5kbmQuaW5zaWRlX3Bvcztcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG0gPSBpbnMuZ2V0X25vZGUocmVmLnBhcmVudCgpKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0bCA9IG9mZi5sZWZ0IC0gMjtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dCA9IG9mZi50b3AgKyBoIC8gMiArIDE7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHAgPSB0bS5pZDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aSA9IGlwID09PSAnZmlyc3QnID8gMCA6IChpcCA9PT0gJ2xhc3QnID8gdG0uY2hpbGRyZW4ubGVuZ3RoIDogTWF0aC5taW4oaXAsIHRtLmNoaWxkcmVuLmxlbmd0aCkpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRjID0gJ2pzdHJlZS1pbnNpZGUnO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdGNhc2UgJ2EnOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRsID0gb2ZmLmxlZnQgLSA2O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0ID0gb2ZmLnRvcCArIGg7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHAgPSBpbnMuZ2V0X3BhcmVudChyZWYpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpID0gcmVmLnBhcmVudCgpLmluZGV4KCkgKyAxO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRjID0gJ2pzdHJlZS1hYm92ZSc7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRvayA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yKHQxID0gMCwgdDIgPSBkYXRhLmRhdGEubm9kZXMubGVuZ3RoOyB0MSA8IHQyOyB0MSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvcCA9IGRhdGEuZGF0YS5vcmlnaW4gJiYgKGRhdGEuZGF0YS5vcmlnaW4uc2V0dGluZ3MuZG5kLmFsd2F5c19jb3B5IHx8IChkYXRhLmRhdGEub3JpZ2luLnNldHRpbmdzLmRuZC5jb3B5ICYmIChkYXRhLmV2ZW50Lm1ldGFLZXkgfHwgZGF0YS5ldmVudC5jdHJsS2V5KSkpID8gXCJjb3B5X25vZGVcIiA6IFwibW92ZV9ub2RlXCI7XG5cdFx0XHRcdFx0XHRcdFx0XHRwcyA9IGk7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZihvcCA9PT0gXCJtb3ZlX25vZGVcIiAmJiB2ID09PSAnYScgJiYgKGRhdGEuZGF0YS5vcmlnaW4gJiYgZGF0YS5kYXRhLm9yaWdpbiA9PT0gaW5zKSAmJiBwID09PSBpbnMuZ2V0X3BhcmVudChkYXRhLmRhdGEubm9kZXNbdDFdKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRwciA9IGlucy5nZXRfbm9kZShwKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYocHMgPiAkLmluQXJyYXkoZGF0YS5kYXRhLm5vZGVzW3QxXSwgcHIuY2hpbGRyZW4pKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHMgLT0gMTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0b2sgPSBvayAmJiAoIChpbnMgJiYgaW5zLnNldHRpbmdzICYmIGlucy5zZXR0aW5ncy5kbmQgJiYgaW5zLnNldHRpbmdzLmRuZC5jaGVja193aGlsZV9kcmFnZ2luZyA9PT0gZmFsc2UpIHx8IGlucy5jaGVjayhvcCwgKGRhdGEuZGF0YS5vcmlnaW4gJiYgZGF0YS5kYXRhLm9yaWdpbiAhPT0gaW5zID8gZGF0YS5kYXRhLm9yaWdpbi5nZXRfbm9kZShkYXRhLmRhdGEubm9kZXNbdDFdKSA6IGRhdGEuZGF0YS5ub2Rlc1t0MV0pLCBwLCBwcywgeyAnZG5kJyA6IHRydWUsICdyZWYnIDogaW5zLmdldF9ub2RlKHJlZi5wYXJlbnQoKSksICdwb3MnIDogdiwgJ29yaWdpbicgOiBkYXRhLmRhdGEub3JpZ2luLCAnaXNfbXVsdGknIDogKGRhdGEuZGF0YS5vcmlnaW4gJiYgZGF0YS5kYXRhLm9yaWdpbiAhPT0gaW5zKSwgJ2lzX2ZvcmVpZ24nIDogKCFkYXRhLmRhdGEub3JpZ2luKSB9KSApO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYoIW9rKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmKGlucyAmJiBpbnMubGFzdF9lcnJvcikgeyBsYXN0ZXIgPSBpbnMubGFzdF9lcnJvcigpOyB9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRpZih2ID09PSAnaScgJiYgcmVmLnBhcmVudCgpLmlzKCcuanN0cmVlLWNsb3NlZCcpICYmIGlucy5zZXR0aW5ncy5kbmQub3Blbl90aW1lb3V0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIWRhdGEuZXZlbnQgfHwgZGF0YS5ldmVudC50eXBlICE9PSAnZHJhZ292ZXInIHx8IGlzRGlmZmVyZW50Tm9kZSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAob3BlbnRvKSB7IGNsZWFyVGltZW91dChvcGVudG8pOyB9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG9wZW50byA9IHNldFRpbWVvdXQoKGZ1bmN0aW9uICh4LCB6KSB7IHJldHVybiBmdW5jdGlvbiAoKSB7IHgub3Blbl9ub2RlKHopOyB9OyB9KGlucywgcmVmKSksIGlucy5zZXR0aW5ncy5kbmQub3Blbl90aW1lb3V0KTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aWYob2spIHtcblx0XHRcdFx0XHRcdFx0XHRcdHBuID0gaW5zLmdldF9ub2RlKHAsIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCFwbi5oYXNDbGFzcygnLmpzdHJlZS1kbmQtcGFyZW50JykpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0JCgnLmpzdHJlZS1kbmQtcGFyZW50JykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1kbmQtcGFyZW50Jyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHBuLmFkZENsYXNzKCdqc3RyZWUtZG5kLXBhcmVudCcpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0bGFzdG12ID0geyAnaW5zJyA6IGlucywgJ3BhcicgOiBwLCAncG9zJyA6IHYgPT09ICdpJyAmJiBpcCA9PT0gJ2xhc3QnICYmIGkgPT09IDAgJiYgIWlucy5pc19sb2FkZWQodG0pID8gJ2xhc3QnIDogaSB9O1xuXHRcdFx0XHRcdFx0XHRcdFx0bWFya2VyLmNzcyh7ICdsZWZ0JyA6IGwgKyAncHgnLCAndG9wJyA6IHQgKyAncHgnIH0pLnNob3coKTtcblx0XHRcdFx0XHRcdFx0XHRcdG1hcmtlci5yZW1vdmVDbGFzcygnanN0cmVlLWFib3ZlIGpzdHJlZS1pbnNpZGUganN0cmVlLWJlbG93JykuYWRkQ2xhc3MoYyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhLmhlbHBlci5maW5kKCcuanN0cmVlLWljb24nKS5maXJzdCgpLnJlbW92ZUNsYXNzKCdqc3RyZWUtZXInKS5hZGRDbGFzcygnanN0cmVlLW9rJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoZGF0YS5ldmVudC5vcmlnaW5hbEV2ZW50ICYmIGRhdGEuZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZGF0YS5ldmVudC5vcmlnaW5hbEV2ZW50LmRhdGFUcmFuc2Zlci5kcm9wRWZmZWN0ID0gaXNfY29weSA/ICdjb3B5JyA6ICdtb3ZlJztcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdGxhc3RlciA9IHt9O1xuXHRcdFx0XHRcdFx0XHRcdFx0byA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0aWYobyA9PT0gdHJ1ZSkgeyByZXR1cm47IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0JCgnLmpzdHJlZS1kbmQtcGFyZW50JykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1kbmQtcGFyZW50Jyk7XG5cdFx0XHRcdGxhc3RtdiA9IGZhbHNlO1xuXHRcdFx0XHRkYXRhLmhlbHBlci5maW5kKCcuanN0cmVlLWljb24nKS5yZW1vdmVDbGFzcygnanN0cmVlLW9rJykuYWRkQ2xhc3MoJ2pzdHJlZS1lcicpO1xuXHRcdFx0XHRpZiAoZGF0YS5ldmVudC5vcmlnaW5hbEV2ZW50ICYmIGRhdGEuZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIpIHtcblx0XHRcdFx0XHQvL2RhdGEuZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdub25lJztcblx0XHRcdFx0fVxuXHRcdFx0XHRtYXJrZXIuaGlkZSgpO1xuXHRcdFx0fSlcblx0XHRcdC5vbignZG5kX3Njcm9sbC52YWthdGEuanN0cmVlJywgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0aWYoIWRhdGEgfHwgIWRhdGEuZGF0YSB8fCAhZGF0YS5kYXRhLmpzdHJlZSkgeyByZXR1cm47IH1cblx0XHRcdFx0bWFya2VyLmhpZGUoKTtcblx0XHRcdFx0bGFzdG12ID0gZmFsc2U7XG5cdFx0XHRcdGxhc3RldiA9IGZhbHNlO1xuXHRcdFx0XHRkYXRhLmhlbHBlci5maW5kKCcuanN0cmVlLWljb24nKS5maXJzdCgpLnJlbW92ZUNsYXNzKCdqc3RyZWUtb2snKS5hZGRDbGFzcygnanN0cmVlLWVyJyk7XG5cdFx0XHR9KVxuXHRcdFx0Lm9uKCdkbmRfc3RvcC52YWthdGEuanN0cmVlJywgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0JCgnLmpzdHJlZS1kbmQtcGFyZW50JykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS1kbmQtcGFyZW50Jyk7XG5cdFx0XHRcdGlmKG9wZW50bykgeyBjbGVhclRpbWVvdXQob3BlbnRvKTsgfVxuXHRcdFx0XHRpZighZGF0YSB8fCAhZGF0YS5kYXRhIHx8ICFkYXRhLmRhdGEuanN0cmVlKSB7IHJldHVybjsgfVxuXHRcdFx0XHRtYXJrZXIuaGlkZSgpLmRldGFjaCgpO1xuXHRcdFx0XHR2YXIgaSwgaiwgbm9kZXMgPSBbXTtcblx0XHRcdFx0aWYobGFzdG12KSB7XG5cdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gZGF0YS5kYXRhLm5vZGVzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0bm9kZXNbaV0gPSBkYXRhLmRhdGEub3JpZ2luID8gZGF0YS5kYXRhLm9yaWdpbi5nZXRfbm9kZShkYXRhLmRhdGEubm9kZXNbaV0pIDogZGF0YS5kYXRhLm5vZGVzW2ldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRsYXN0bXYuaW5zWyBkYXRhLmRhdGEub3JpZ2luICYmIChkYXRhLmRhdGEub3JpZ2luLnNldHRpbmdzLmRuZC5hbHdheXNfY29weSB8fCAoZGF0YS5kYXRhLm9yaWdpbi5zZXR0aW5ncy5kbmQuY29weSAmJiAoZGF0YS5ldmVudC5tZXRhS2V5IHx8IGRhdGEuZXZlbnQuY3RybEtleSkpKSA/ICdjb3B5X25vZGUnIDogJ21vdmVfbm9kZScgXShub2RlcywgbGFzdG12LnBhciwgbGFzdG12LnBvcywgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZGF0YS5kYXRhLm9yaWdpbik7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0aSA9ICQoZGF0YS5ldmVudC50YXJnZXQpLmNsb3Nlc3QoJy5qc3RyZWUnKTtcblx0XHRcdFx0XHRpZihpLmxlbmd0aCAmJiBsYXN0ZXIgJiYgbGFzdGVyLmVycm9yICYmIGxhc3Rlci5lcnJvciA9PT0gJ2NoZWNrJykge1xuXHRcdFx0XHRcdFx0aSA9IGkuanN0cmVlKHRydWUpO1xuXHRcdFx0XHRcdFx0aWYoaSkge1xuXHRcdFx0XHRcdFx0XHRpLnNldHRpbmdzLmNvcmUuZXJyb3IuY2FsbCh0aGlzLCBsYXN0ZXIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRsYXN0ZXYgPSBmYWxzZTtcblx0XHRcdFx0bGFzdG12ID0gZmFsc2U7XG5cdFx0XHR9KVxuXHRcdFx0Lm9uKCdrZXl1cC5qc3RyZWUga2V5ZG93bi5qc3RyZWUnLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRkYXRhID0gJC52YWthdGEuZG5kLl9nZXQoKTtcblx0XHRcdFx0aWYoZGF0YSAmJiBkYXRhLmRhdGEgJiYgZGF0YS5kYXRhLmpzdHJlZSkge1xuXHRcdFx0XHRcdGlmIChlLnR5cGUgPT09IFwia2V5dXBcIiAmJiBlLndoaWNoID09PSAyNykge1xuXHRcdFx0XHRcdFx0aWYgKG9wZW50bykgeyBjbGVhclRpbWVvdXQob3BlbnRvKTsgfVxuXHRcdFx0XHRcdFx0bGFzdG12ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRsYXN0ZXIgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGxhc3RldiA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0b3BlbnRvID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRtYXJrZXIuaGlkZSgpLmRldGFjaCgpO1xuXHRcdFx0XHRcdFx0JC52YWthdGEuZG5kLl9jbGVhbigpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRkYXRhLmhlbHBlci5maW5kKCcuanN0cmVlLWNvcHknKS5maXJzdCgpWyBkYXRhLmRhdGEub3JpZ2luICYmIChkYXRhLmRhdGEub3JpZ2luLnNldHRpbmdzLmRuZC5hbHdheXNfY29weSB8fCAoZGF0YS5kYXRhLm9yaWdpbi5zZXR0aW5ncy5kbmQuY29weSAmJiAoZS5tZXRhS2V5IHx8IGUuY3RybEtleSkpKSA/ICdzaG93JyA6ICdoaWRlJyBdKCk7XG5cdFx0XHRcdFx0XHRpZihsYXN0ZXYpIHtcblx0XHRcdFx0XHRcdFx0bGFzdGV2Lm1ldGFLZXkgPSBlLm1ldGFLZXk7XG5cdFx0XHRcdFx0XHRcdGxhc3Rldi5jdHJsS2V5ID0gZS5jdHJsS2V5O1xuXHRcdFx0XHRcdFx0XHQkLnZha2F0YS5kbmQuX3RyaWdnZXIoJ21vdmUnLCBsYXN0ZXYpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH0pO1xuXG5cdC8vIGhlbHBlcnNcblx0KGZ1bmN0aW9uICgkKSB7XG5cdFx0JC52YWthdGEuaHRtbCA9IHtcblx0XHRcdGRpdiA6ICQoJzxkaXY+PC9kaXY+JyksXG5cdFx0XHRlc2NhcGUgOiBmdW5jdGlvbiAoc3RyKSB7XG5cdFx0XHRcdHJldHVybiAkLnZha2F0YS5odG1sLmRpdi50ZXh0KHN0cikuaHRtbCgpO1xuXHRcdFx0fSxcblx0XHRcdHN0cmlwIDogZnVuY3Rpb24gKHN0cikge1xuXHRcdFx0XHRyZXR1cm4gJC52YWthdGEuaHRtbC5kaXYuZW1wdHkoKS5hcHBlbmQoJC5wYXJzZUhUTUwoc3RyKSkudGV4dCgpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0Ly8gcHJpdmF0ZSB2YXJpYWJsZVxuXHRcdHZhciB2YWthdGFfZG5kID0ge1xuXHRcdFx0ZWxlbWVudFx0OiBmYWxzZSxcblx0XHRcdHRhcmdldFx0OiBmYWxzZSxcblx0XHRcdGlzX2Rvd25cdDogZmFsc2UsXG5cdFx0XHRpc19kcmFnXHQ6IGZhbHNlLFxuXHRcdFx0aGVscGVyXHQ6IGZhbHNlLFxuXHRcdFx0aGVscGVyX3c6IDAsXG5cdFx0XHRkYXRhXHQ6IGZhbHNlLFxuXHRcdFx0aW5pdF94XHQ6IDAsXG5cdFx0XHRpbml0X3lcdDogMCxcblx0XHRcdHNjcm9sbF9sOiAwLFxuXHRcdFx0c2Nyb2xsX3Q6IDAsXG5cdFx0XHRzY3JvbGxfZTogZmFsc2UsXG5cdFx0XHRzY3JvbGxfaTogZmFsc2UsXG5cdFx0XHRpc190b3VjaDogZmFsc2Vcblx0XHR9O1xuXHRcdCQudmFrYXRhLmRuZCA9IHtcblx0XHRcdHNldHRpbmdzIDoge1xuXHRcdFx0XHRzY3JvbGxfc3BlZWRcdFx0OiAxMCxcblx0XHRcdFx0c2Nyb2xsX3Byb3hpbWl0eVx0OiAyMCxcblx0XHRcdFx0aGVscGVyX2xlZnRcdFx0XHQ6IDUsXG5cdFx0XHRcdGhlbHBlcl90b3BcdFx0XHQ6IDEwLFxuXHRcdFx0XHR0aHJlc2hvbGRcdFx0XHQ6IDUsXG5cdFx0XHRcdHRocmVzaG9sZF90b3VjaFx0XHQ6IDEwXG5cdFx0XHR9LFxuXHRcdFx0X3RyaWdnZXIgOiBmdW5jdGlvbiAoZXZlbnRfbmFtZSwgZSwgZGF0YSkge1xuXHRcdFx0XHRpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0ZGF0YSA9ICQudmFrYXRhLmRuZC5fZ2V0KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YS5ldmVudCA9IGU7XG5cdFx0XHRcdCQoZG9jdW1lbnQpLnRyaWdnZXJIYW5kbGVyKFwiZG5kX1wiICsgZXZlbnRfbmFtZSArIFwiLnZha2F0YVwiLCBkYXRhKTtcblx0XHRcdH0sXG5cdFx0XHRfZ2V0IDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFwiZGF0YVwiXHRcdDogdmFrYXRhX2RuZC5kYXRhLFxuXHRcdFx0XHRcdFwiZWxlbWVudFwiXHQ6IHZha2F0YV9kbmQuZWxlbWVudCxcblx0XHRcdFx0XHRcImhlbHBlclwiXHQ6IHZha2F0YV9kbmQuaGVscGVyXG5cdFx0XHRcdH07XG5cdFx0XHR9LFxuXHRcdFx0X2NsZWFuIDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZih2YWthdGFfZG5kLmhlbHBlcikgeyB2YWthdGFfZG5kLmhlbHBlci5yZW1vdmUoKTsgfVxuXHRcdFx0XHRpZih2YWthdGFfZG5kLnNjcm9sbF9pKSB7IGNsZWFySW50ZXJ2YWwodmFrYXRhX2RuZC5zY3JvbGxfaSk7IHZha2F0YV9kbmQuc2Nyb2xsX2kgPSBmYWxzZTsgfVxuXHRcdFx0XHR2YWthdGFfZG5kID0ge1xuXHRcdFx0XHRcdGVsZW1lbnRcdDogZmFsc2UsXG5cdFx0XHRcdFx0dGFyZ2V0XHQ6IGZhbHNlLFxuXHRcdFx0XHRcdGlzX2Rvd25cdDogZmFsc2UsXG5cdFx0XHRcdFx0aXNfZHJhZ1x0OiBmYWxzZSxcblx0XHRcdFx0XHRoZWxwZXJcdDogZmFsc2UsXG5cdFx0XHRcdFx0aGVscGVyX3c6IDAsXG5cdFx0XHRcdFx0ZGF0YVx0OiBmYWxzZSxcblx0XHRcdFx0XHRpbml0X3hcdDogMCxcblx0XHRcdFx0XHRpbml0X3lcdDogMCxcblx0XHRcdFx0XHRzY3JvbGxfbDogMCxcblx0XHRcdFx0XHRzY3JvbGxfdDogMCxcblx0XHRcdFx0XHRzY3JvbGxfZTogZmFsc2UsXG5cdFx0XHRcdFx0c2Nyb2xsX2k6IGZhbHNlLFxuXHRcdFx0XHRcdGlzX3RvdWNoOiBmYWxzZVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRlbG0gPSBudWxsO1xuXHRcdFx0XHQkKGRvY3VtZW50KS5vZmYoXCJtb3VzZW1vdmUudmFrYXRhLmpzdHJlZSB0b3VjaG1vdmUudmFrYXRhLmpzdHJlZVwiLCAkLnZha2F0YS5kbmQuZHJhZyk7XG5cdFx0XHRcdCQoZG9jdW1lbnQpLm9mZihcIm1vdXNldXAudmFrYXRhLmpzdHJlZSB0b3VjaGVuZC52YWthdGEuanN0cmVlXCIsICQudmFrYXRhLmRuZC5zdG9wKTtcblx0XHRcdH0sXG5cdFx0XHRfc2Nyb2xsIDogZnVuY3Rpb24gKGluaXRfb25seSkge1xuXHRcdFx0XHRpZighdmFrYXRhX2RuZC5zY3JvbGxfZSB8fCAoIXZha2F0YV9kbmQuc2Nyb2xsX2wgJiYgIXZha2F0YV9kbmQuc2Nyb2xsX3QpKSB7XG5cdFx0XHRcdFx0aWYodmFrYXRhX2RuZC5zY3JvbGxfaSkgeyBjbGVhckludGVydmFsKHZha2F0YV9kbmQuc2Nyb2xsX2kpOyB2YWthdGFfZG5kLnNjcm9sbF9pID0gZmFsc2U7IH1cblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIXZha2F0YV9kbmQuc2Nyb2xsX2kpIHtcblx0XHRcdFx0XHR2YWthdGFfZG5kLnNjcm9sbF9pID0gc2V0SW50ZXJ2YWwoJC52YWthdGEuZG5kLl9zY3JvbGwsIDEwMCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKGluaXRfb25seSA9PT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRcdFx0XHR2YXIgaSA9IHZha2F0YV9kbmQuc2Nyb2xsX2Uuc2Nyb2xsVG9wKCksXG5cdFx0XHRcdFx0aiA9IHZha2F0YV9kbmQuc2Nyb2xsX2Uuc2Nyb2xsTGVmdCgpO1xuXHRcdFx0XHR2YWthdGFfZG5kLnNjcm9sbF9lLnNjcm9sbFRvcChpICsgdmFrYXRhX2RuZC5zY3JvbGxfdCAqICQudmFrYXRhLmRuZC5zZXR0aW5ncy5zY3JvbGxfc3BlZWQpO1xuXHRcdFx0XHR2YWthdGFfZG5kLnNjcm9sbF9lLnNjcm9sbExlZnQoaiArIHZha2F0YV9kbmQuc2Nyb2xsX2wgKiAkLnZha2F0YS5kbmQuc2V0dGluZ3Muc2Nyb2xsX3NwZWVkKTtcblx0XHRcdFx0aWYoaSAhPT0gdmFrYXRhX2RuZC5zY3JvbGxfZS5zY3JvbGxUb3AoKSB8fCBqICE9PSB2YWthdGFfZG5kLnNjcm9sbF9lLnNjcm9sbExlZnQoKSkge1xuXHRcdFx0XHRcdC8qKlxuXHRcdFx0XHRcdCAqIHRyaWdnZXJlZCBvbiB0aGUgZG9jdW1lbnQgd2hlbiBhIGRyYWcgY2F1c2VzIGFuIGVsZW1lbnQgdG8gc2Nyb2xsXG5cdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0ICogQHBsdWdpbiBkbmRcblx0XHRcdFx0XHQgKiBAbmFtZSBkbmRfc2Nyb2xsLnZha2F0YVxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7TWl4ZWR9IGRhdGEgYW55IGRhdGEgc3VwcGxpZWQgd2l0aCB0aGUgY2FsbCB0byAkLnZha2F0YS5kbmQuc3RhcnRcblx0XHRcdFx0XHQgKiBAcGFyYW0ge0RPTX0gZWxlbWVudCB0aGUgRE9NIGVsZW1lbnQgYmVpbmcgZHJhZ2dlZFxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSBoZWxwZXIgdGhlIGhlbHBlciBzaG93biBuZXh0IHRvIHRoZSBtb3VzZVxuXHRcdFx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSBldmVudCB0aGUgZWxlbWVudCB0aGF0IGlzIHNjcm9sbGluZ1xuXHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdCQudmFrYXRhLmRuZC5fdHJpZ2dlcihcInNjcm9sbFwiLCB2YWthdGFfZG5kLnNjcm9sbF9lKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHN0YXJ0IDogZnVuY3Rpb24gKGUsIGRhdGEsIGh0bWwpIHtcblx0XHRcdFx0aWYoZS50eXBlID09PSBcInRvdWNoc3RhcnRcIiAmJiBlLm9yaWdpbmFsRXZlbnQgJiYgZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXSkge1xuXHRcdFx0XHRcdGUucGFnZVggPSBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVg7XG5cdFx0XHRcdFx0ZS5wYWdlWSA9IGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWTtcblx0XHRcdFx0XHRlLnRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYIC0gd2luZG93LnBhZ2VYT2Zmc2V0LCBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKHZha2F0YV9kbmQuaXNfZHJhZykgeyAkLnZha2F0YS5kbmQuc3RvcCh7fSk7IH1cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRlLmN1cnJlbnRUYXJnZXQudW5zZWxlY3RhYmxlID0gXCJvblwiO1xuXHRcdFx0XHRcdGUuY3VycmVudFRhcmdldC5vbnNlbGVjdHN0YXJ0ID0gZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfTtcblx0XHRcdFx0XHRpZihlLmN1cnJlbnRUYXJnZXQuc3R5bGUpIHtcblx0XHRcdFx0XHRcdGUuY3VycmVudFRhcmdldC5zdHlsZS50b3VjaEFjdGlvbiA9IFwibm9uZVwiO1xuXHRcdFx0XHRcdFx0ZS5jdXJyZW50VGFyZ2V0LnN0eWxlLm1zVG91Y2hBY3Rpb24gPSBcIm5vbmVcIjtcblx0XHRcdFx0XHRcdGUuY3VycmVudFRhcmdldC5zdHlsZS5Nb3pVc2VyU2VsZWN0ID0gXCJub25lXCI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGNhdGNoKGlnbm9yZSkgeyB9XG5cdFx0XHRcdHZha2F0YV9kbmQuaW5pdF94XHQ9IGUucGFnZVg7XG5cdFx0XHRcdHZha2F0YV9kbmQuaW5pdF95XHQ9IGUucGFnZVk7XG5cdFx0XHRcdHZha2F0YV9kbmQuZGF0YVx0XHQ9IGRhdGE7XG5cdFx0XHRcdHZha2F0YV9kbmQuaXNfZG93blx0PSB0cnVlO1xuXHRcdFx0XHR2YWthdGFfZG5kLmVsZW1lbnRcdD0gZS5jdXJyZW50VGFyZ2V0O1xuXHRcdFx0XHR2YWthdGFfZG5kLnRhcmdldFx0PSBlLnRhcmdldDtcblx0XHRcdFx0dmFrYXRhX2RuZC5pc190b3VjaFx0PSBlLnR5cGUgPT09IFwidG91Y2hzdGFydFwiO1xuXHRcdFx0XHRpZihodG1sICE9PSBmYWxzZSkge1xuXHRcdFx0XHRcdHZha2F0YV9kbmQuaGVscGVyID0gJChcIjxkaXYgaWQ9J3Zha2F0YS1kbmQnPjwvZGl2PlwiKS5odG1sKGh0bWwpLmNzcyh7XG5cdFx0XHRcdFx0XHRcImRpc3BsYXlcIlx0XHQ6IFwiYmxvY2tcIixcblx0XHRcdFx0XHRcdFwibWFyZ2luXCJcdFx0OiBcIjBcIixcblx0XHRcdFx0XHRcdFwicGFkZGluZ1wiXHRcdDogXCIwXCIsXG5cdFx0XHRcdFx0XHRcInBvc2l0aW9uXCJcdFx0OiBcImFic29sdXRlXCIsXG5cdFx0XHRcdFx0XHRcInRvcFwiXHRcdFx0OiBcIi0yMDAwcHhcIixcblx0XHRcdFx0XHRcdFwibGluZUhlaWdodFwiXHQ6IFwiMTZweFwiLFxuXHRcdFx0XHRcdFx0XCJ6SW5kZXhcIlx0XHQ6IFwiMTAwMDBcIlxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCQoZG9jdW1lbnQpLm9uKFwibW91c2Vtb3ZlLnZha2F0YS5qc3RyZWUgdG91Y2htb3ZlLnZha2F0YS5qc3RyZWVcIiwgJC52YWthdGEuZG5kLmRyYWcpO1xuXHRcdFx0XHQkKGRvY3VtZW50KS5vbihcIm1vdXNldXAudmFrYXRhLmpzdHJlZSB0b3VjaGVuZC52YWthdGEuanN0cmVlXCIsICQudmFrYXRhLmRuZC5zdG9wKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSxcblx0XHRcdGRyYWcgOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRpZihlLnR5cGUgPT09IFwidG91Y2htb3ZlXCIgJiYgZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlcyAmJiBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0pIHtcblx0XHRcdFx0XHRlLnBhZ2VYID0gZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYO1xuXHRcdFx0XHRcdGUucGFnZVkgPSBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVk7XG5cdFx0XHRcdFx0ZS50YXJnZXQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCwgZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZighdmFrYXRhX2RuZC5pc19kb3duKSB7IHJldHVybjsgfVxuXHRcdFx0XHRpZighdmFrYXRhX2RuZC5pc19kcmFnKSB7XG5cdFx0XHRcdFx0aWYoXG5cdFx0XHRcdFx0XHRNYXRoLmFicyhlLnBhZ2VYIC0gdmFrYXRhX2RuZC5pbml0X3gpID4gKHZha2F0YV9kbmQuaXNfdG91Y2ggPyAkLnZha2F0YS5kbmQuc2V0dGluZ3MudGhyZXNob2xkX3RvdWNoIDogJC52YWthdGEuZG5kLnNldHRpbmdzLnRocmVzaG9sZCkgfHxcblx0XHRcdFx0XHRcdE1hdGguYWJzKGUucGFnZVkgLSB2YWthdGFfZG5kLmluaXRfeSkgPiAodmFrYXRhX2RuZC5pc190b3VjaCA/ICQudmFrYXRhLmRuZC5zZXR0aW5ncy50aHJlc2hvbGRfdG91Y2ggOiAkLnZha2F0YS5kbmQuc2V0dGluZ3MudGhyZXNob2xkKVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0aWYodmFrYXRhX2RuZC5oZWxwZXIpIHtcblx0XHRcdFx0XHRcdFx0dmFrYXRhX2RuZC5oZWxwZXIuYXBwZW5kVG8oZG9jdW1lbnQuYm9keSk7XG5cdFx0XHRcdFx0XHRcdHZha2F0YV9kbmQuaGVscGVyX3cgPSB2YWthdGFfZG5kLmhlbHBlci5vdXRlcldpZHRoKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR2YWthdGFfZG5kLmlzX2RyYWcgPSB0cnVlO1xuXHRcdFx0XHRcdFx0JCh2YWthdGFfZG5kLnRhcmdldCkub25lKCdjbGljay52YWthdGEnLCBmYWxzZSk7XG5cdFx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHRcdCAqIHRyaWdnZXJlZCBvbiB0aGUgZG9jdW1lbnQgd2hlbiBhIGRyYWcgc3RhcnRzXG5cdFx0XHRcdFx0XHQgKiBAZXZlbnRcblx0XHRcdFx0XHRcdCAqIEBwbHVnaW4gZG5kXG5cdFx0XHRcdFx0XHQgKiBAbmFtZSBkbmRfc3RhcnQudmFrYXRhXG5cdFx0XHRcdFx0XHQgKiBAcGFyYW0ge01peGVkfSBkYXRhIGFueSBkYXRhIHN1cHBsaWVkIHdpdGggdGhlIGNhbGwgdG8gJC52YWthdGEuZG5kLnN0YXJ0XG5cdFx0XHRcdFx0XHQgKiBAcGFyYW0ge0RPTX0gZWxlbWVudCB0aGUgRE9NIGVsZW1lbnQgYmVpbmcgZHJhZ2dlZFxuXHRcdFx0XHRcdFx0ICogQHBhcmFtIHtqUXVlcnl9IGhlbHBlciB0aGUgaGVscGVyIHNob3duIG5leHQgdG8gdGhlIG1vdXNlXG5cdFx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgdGhlIGV2ZW50IHRoYXQgY2F1c2VkIHRoZSBzdGFydCAocHJvYmFibHkgbW91c2Vtb3ZlKVxuXHRcdFx0XHRcdFx0ICovXG5cdFx0XHRcdFx0XHQkLnZha2F0YS5kbmQuX3RyaWdnZXIoXCJzdGFydFwiLCBlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7IHJldHVybjsgfVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dmFyIGQgID0gZmFsc2UsIHcgID0gZmFsc2UsXG5cdFx0XHRcdFx0ZGggPSBmYWxzZSwgd2ggPSBmYWxzZSxcblx0XHRcdFx0XHRkdyA9IGZhbHNlLCB3dyA9IGZhbHNlLFxuXHRcdFx0XHRcdGR0ID0gZmFsc2UsIGRsID0gZmFsc2UsXG5cdFx0XHRcdFx0aHQgPSBmYWxzZSwgaGwgPSBmYWxzZTtcblxuXHRcdFx0XHR2YWthdGFfZG5kLnNjcm9sbF90ID0gMDtcblx0XHRcdFx0dmFrYXRhX2RuZC5zY3JvbGxfbCA9IDA7XG5cdFx0XHRcdHZha2F0YV9kbmQuc2Nyb2xsX2UgPSBmYWxzZTtcblx0XHRcdFx0JCgkKGUudGFyZ2V0KS5wYXJlbnRzVW50aWwoXCJib2R5XCIpLmFkZEJhY2soKS5nZXQoKS5yZXZlcnNlKCkpXG5cdFx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm5cdHRoaXMub3duZXJEb2N1bWVudCAmJiAoL15hdXRvfHNjcm9sbCQvKS50ZXN0KCQodGhpcykuY3NzKFwib3ZlcmZsb3dcIikpICYmXG5cdFx0XHRcdFx0XHRcdFx0KHRoaXMuc2Nyb2xsSGVpZ2h0ID4gdGhpcy5vZmZzZXRIZWlnaHQgfHwgdGhpcy5zY3JvbGxXaWR0aCA+IHRoaXMub2Zmc2V0V2lkdGgpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmVhY2goZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0dmFyIHQgPSAkKHRoaXMpLCBvID0gdC5vZmZzZXQoKTtcblx0XHRcdFx0XHRcdGlmKHRoaXMuc2Nyb2xsSGVpZ2h0ID4gdGhpcy5vZmZzZXRIZWlnaHQpIHtcblx0XHRcdFx0XHRcdFx0aWYoby50b3AgKyB0LmhlaWdodCgpIC0gZS5wYWdlWSA8ICQudmFrYXRhLmRuZC5zZXR0aW5ncy5zY3JvbGxfcHJveGltaXR5KVx0eyB2YWthdGFfZG5kLnNjcm9sbF90ID0gMTsgfVxuXHRcdFx0XHRcdFx0XHRpZihlLnBhZ2VZIC0gby50b3AgPCAkLnZha2F0YS5kbmQuc2V0dGluZ3Muc2Nyb2xsX3Byb3hpbWl0eSlcdFx0XHRcdHsgdmFrYXRhX2RuZC5zY3JvbGxfdCA9IC0xOyB9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZih0aGlzLnNjcm9sbFdpZHRoID4gdGhpcy5vZmZzZXRXaWR0aCkge1xuXHRcdFx0XHRcdFx0XHRpZihvLmxlZnQgKyB0LndpZHRoKCkgLSBlLnBhZ2VYIDwgJC52YWthdGEuZG5kLnNldHRpbmdzLnNjcm9sbF9wcm94aW1pdHkpXHR7IHZha2F0YV9kbmQuc2Nyb2xsX2wgPSAxOyB9XG5cdFx0XHRcdFx0XHRcdGlmKGUucGFnZVggLSBvLmxlZnQgPCAkLnZha2F0YS5kbmQuc2V0dGluZ3Muc2Nyb2xsX3Byb3hpbWl0eSlcdFx0XHRcdHsgdmFrYXRhX2RuZC5zY3JvbGxfbCA9IC0xOyB9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZih2YWthdGFfZG5kLnNjcm9sbF90IHx8IHZha2F0YV9kbmQuc2Nyb2xsX2wpIHtcblx0XHRcdFx0XHRcdFx0dmFrYXRhX2RuZC5zY3JvbGxfZSA9ICQodGhpcyk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRpZighdmFrYXRhX2RuZC5zY3JvbGxfZSkge1xuXHRcdFx0XHRcdGQgID0gJChkb2N1bWVudCk7IHcgPSAkKHdpbmRvdyk7XG5cdFx0XHRcdFx0ZGggPSBkLmhlaWdodCgpOyB3aCA9IHcuaGVpZ2h0KCk7XG5cdFx0XHRcdFx0ZHcgPSBkLndpZHRoKCk7IHd3ID0gdy53aWR0aCgpO1xuXHRcdFx0XHRcdGR0ID0gZC5zY3JvbGxUb3AoKTsgZGwgPSBkLnNjcm9sbExlZnQoKTtcblx0XHRcdFx0XHRpZihkaCA+IHdoICYmIGUucGFnZVkgLSBkdCA8ICQudmFrYXRhLmRuZC5zZXR0aW5ncy5zY3JvbGxfcHJveGltaXR5KVx0XHR7IHZha2F0YV9kbmQuc2Nyb2xsX3QgPSAtMTsgIH1cblx0XHRcdFx0XHRpZihkaCA+IHdoICYmIHdoIC0gKGUucGFnZVkgLSBkdCkgPCAkLnZha2F0YS5kbmQuc2V0dGluZ3Muc2Nyb2xsX3Byb3hpbWl0eSlcdHsgdmFrYXRhX2RuZC5zY3JvbGxfdCA9IDE7IH1cblx0XHRcdFx0XHRpZihkdyA+IHd3ICYmIGUucGFnZVggLSBkbCA8ICQudmFrYXRhLmRuZC5zZXR0aW5ncy5zY3JvbGxfcHJveGltaXR5KVx0XHR7IHZha2F0YV9kbmQuc2Nyb2xsX2wgPSAtMTsgfVxuXHRcdFx0XHRcdGlmKGR3ID4gd3cgJiYgd3cgLSAoZS5wYWdlWCAtIGRsKSA8ICQudmFrYXRhLmRuZC5zZXR0aW5ncy5zY3JvbGxfcHJveGltaXR5KVx0eyB2YWthdGFfZG5kLnNjcm9sbF9sID0gMTsgfVxuXHRcdFx0XHRcdGlmKHZha2F0YV9kbmQuc2Nyb2xsX3QgfHwgdmFrYXRhX2RuZC5zY3JvbGxfbCkge1xuXHRcdFx0XHRcdFx0dmFrYXRhX2RuZC5zY3JvbGxfZSA9IGQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKHZha2F0YV9kbmQuc2Nyb2xsX2UpIHsgJC52YWthdGEuZG5kLl9zY3JvbGwodHJ1ZSk7IH1cblxuXHRcdFx0XHRpZih2YWthdGFfZG5kLmhlbHBlcikge1xuXHRcdFx0XHRcdGh0ID0gcGFyc2VJbnQoZS5wYWdlWSArICQudmFrYXRhLmRuZC5zZXR0aW5ncy5oZWxwZXJfdG9wLCAxMCk7XG5cdFx0XHRcdFx0aGwgPSBwYXJzZUludChlLnBhZ2VYICsgJC52YWthdGEuZG5kLnNldHRpbmdzLmhlbHBlcl9sZWZ0LCAxMCk7XG5cdFx0XHRcdFx0aWYoZGggJiYgaHQgKyAyNSA+IGRoKSB7IGh0ID0gZGggLSA1MDsgfVxuXHRcdFx0XHRcdGlmKGR3ICYmIGhsICsgdmFrYXRhX2RuZC5oZWxwZXJfdyA+IGR3KSB7IGhsID0gZHcgLSAodmFrYXRhX2RuZC5oZWxwZXJfdyArIDIpOyB9XG5cdFx0XHRcdFx0dmFrYXRhX2RuZC5oZWxwZXIuY3NzKHtcblx0XHRcdFx0XHRcdGxlZnRcdDogaGwgKyBcInB4XCIsXG5cdFx0XHRcdFx0XHR0b3BcdFx0OiBodCArIFwicHhcIlxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiB0cmlnZ2VyZWQgb24gdGhlIGRvY3VtZW50IHdoZW4gYSBkcmFnIGlzIGluIHByb2dyZXNzXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAcGx1Z2luIGRuZFxuXHRcdFx0XHQgKiBAbmFtZSBkbmRfbW92ZS52YWthdGFcblx0XHRcdFx0ICogQHBhcmFtIHtNaXhlZH0gZGF0YSBhbnkgZGF0YSBzdXBwbGllZCB3aXRoIHRoZSBjYWxsIHRvICQudmFrYXRhLmRuZC5zdGFydFxuXHRcdFx0XHQgKiBAcGFyYW0ge0RPTX0gZWxlbWVudCB0aGUgRE9NIGVsZW1lbnQgYmVpbmcgZHJhZ2dlZFxuXHRcdFx0XHQgKiBAcGFyYW0ge2pRdWVyeX0gaGVscGVyIHRoZSBoZWxwZXIgc2hvd24gbmV4dCB0byB0aGUgbW91c2Vcblx0XHRcdFx0ICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IHRoZSBldmVudCB0aGF0IGNhdXNlZCB0aGlzIHRvIHRyaWdnZXIgKG1vc3QgbGlrZWx5IG1vdXNlbW92ZSlcblx0XHRcdFx0ICovXG5cdFx0XHRcdCQudmFrYXRhLmRuZC5fdHJpZ2dlcihcIm1vdmVcIiwgZSk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0sXG5cdFx0XHRzdG9wIDogZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0aWYoZS50eXBlID09PSBcInRvdWNoZW5kXCIgJiYgZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlcyAmJiBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0pIHtcblx0XHRcdFx0XHRlLnBhZ2VYID0gZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYO1xuXHRcdFx0XHRcdGUucGFnZVkgPSBlLm9yaWdpbmFsRXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVk7XG5cdFx0XHRcdFx0ZS50YXJnZXQgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGUub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCwgZS5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZih2YWthdGFfZG5kLmlzX2RyYWcpIHtcblx0XHRcdFx0XHQvKipcblx0XHRcdFx0XHQgKiB0cmlnZ2VyZWQgb24gdGhlIGRvY3VtZW50IHdoZW4gYSBkcmFnIHN0b3BzICh0aGUgZHJhZ2dlZCBlbGVtZW50IGlzIGRyb3BwZWQpXG5cdFx0XHRcdFx0ICogQGV2ZW50XG5cdFx0XHRcdFx0ICogQHBsdWdpbiBkbmRcblx0XHRcdFx0XHQgKiBAbmFtZSBkbmRfc3RvcC52YWthdGFcblx0XHRcdFx0XHQgKiBAcGFyYW0ge01peGVkfSBkYXRhIGFueSBkYXRhIHN1cHBsaWVkIHdpdGggdGhlIGNhbGwgdG8gJC52YWthdGEuZG5kLnN0YXJ0XG5cdFx0XHRcdFx0ICogQHBhcmFtIHtET019IGVsZW1lbnQgdGhlIERPTSBlbGVtZW50IGJlaW5nIGRyYWdnZWRcblx0XHRcdFx0XHQgKiBAcGFyYW0ge2pRdWVyeX0gaGVscGVyIHRoZSBoZWxwZXIgc2hvd24gbmV4dCB0byB0aGUgbW91c2Vcblx0XHRcdFx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgdGhlIGV2ZW50IHRoYXQgY2F1c2VkIHRoZSBzdG9wXG5cdFx0XHRcdFx0ICovXG5cdFx0XHRcdFx0aWYgKGUudGFyZ2V0ICE9PSB2YWthdGFfZG5kLnRhcmdldCkge1xuXHRcdFx0XHRcdFx0JCh2YWthdGFfZG5kLnRhcmdldCkub2ZmKCdjbGljay52YWthdGEnKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0JC52YWthdGEuZG5kLl90cmlnZ2VyKFwic3RvcFwiLCBlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRpZihlLnR5cGUgPT09IFwidG91Y2hlbmRcIiAmJiBlLnRhcmdldCA9PT0gdmFrYXRhX2RuZC50YXJnZXQpIHtcblx0XHRcdFx0XHRcdHZhciB0byA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyAkKGUudGFyZ2V0KS50cmlnZ2VyKCdjbGljaycpOyB9LCAxMDApO1xuXHRcdFx0XHRcdFx0JChlLnRhcmdldCkub25lKCdjbGljaycsIGZ1bmN0aW9uKCkgeyBpZih0bykgeyBjbGVhclRpbWVvdXQodG8pOyB9IH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHQkLnZha2F0YS5kbmQuX2NsZWFuKCk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9O1xuXHR9KCQpKTtcblxuXHQvLyBpbmNsdWRlIHRoZSBkbmQgcGx1Z2luIGJ5IGRlZmF1bHRcblx0Ly8gJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2lucy5wdXNoKFwiZG5kXCIpO1xuXG5cbi8qKlxuICogIyMjIE1hc3Nsb2FkIHBsdWdpblxuICpcbiAqIEFkZHMgbWFzc2xvYWQgZnVuY3Rpb25hbGl0eSB0byBqc1RyZWUsIHNvIHRoYXQgbXVsdGlwbGUgbm9kZXMgY2FuIGJlIGxvYWRlZCBpbiBhIHNpbmdsZSByZXF1ZXN0IChvbmx5IHVzZWZ1bCB3aXRoIGxhenkgbG9hZGluZykuXG4gKi9cblxuXHQvKipcblx0ICogbWFzc2xvYWQgY29uZmlndXJhdGlvblxuXHQgKlxuXHQgKiBJdCBpcyBwb3NzaWJsZSB0byBzZXQgdGhpcyB0byBhIHN0YW5kYXJkIGpRdWVyeS1saWtlIEFKQVggY29uZmlnLlxuXHQgKiBJbiBhZGRpdGlvbiB0byB0aGUgc3RhbmRhcmQgalF1ZXJ5IGFqYXggb3B0aW9ucyBoZXJlIHlvdSBjYW4gc3VwcGx5IGZ1bmN0aW9ucyBmb3IgYGRhdGFgIGFuZCBgdXJsYCwgdGhlIGZ1bmN0aW9ucyB3aWxsIGJlIHJ1biBpbiB0aGUgY3VycmVudCBpbnN0YW5jZSdzIHNjb3BlIGFuZCBhIHBhcmFtIHdpbGwgYmUgcGFzc2VkIGluZGljYXRpbmcgd2hpY2ggbm9kZSBJRHMgbmVlZCB0byBiZSBsb2FkZWQsIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhvc2UgZnVuY3Rpb25zIHdpbGwgYmUgdXNlZC5cblx0ICpcblx0ICogWW91IGNhbiBhbHNvIHNldCB0aGlzIHRvIGEgZnVuY3Rpb24sIHRoYXQgZnVuY3Rpb24gd2lsbCByZWNlaXZlIHRoZSBub2RlIElEcyBiZWluZyBsb2FkZWQgYXMgYXJndW1lbnQgYW5kIGEgc2Vjb25kIHBhcmFtIHdoaWNoIGlzIGEgZnVuY3Rpb24gKGNhbGxiYWNrKSB3aGljaCBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhlIHJlc3VsdC5cblx0ICpcblx0ICogQm90aCB0aGUgQUpBWCBhbmQgdGhlIGZ1bmN0aW9uIGFwcHJvYWNoIHJlbHkgb24gdGhlIHNhbWUgcmV0dXJuIHZhbHVlIC0gYW4gb2JqZWN0IHdoZXJlIHRoZSBrZXlzIGFyZSB0aGUgbm9kZSBJRHMsIGFuZCB0aGUgdmFsdWUgaXMgdGhlIGNoaWxkcmVuIG9mIHRoYXQgbm9kZSBhcyBhbiBhcnJheS5cblx0ICpcblx0ICpcdHtcblx0ICpcdFx0XCJpZDFcIiA6IFt7IFwidGV4dFwiIDogXCJDaGlsZCBvZiBJRDFcIiwgXCJpZFwiIDogXCJjMVwiIH0sIHsgXCJ0ZXh0XCIgOiBcIkFub3RoZXIgY2hpbGQgb2YgSUQxXCIsIFwiaWRcIiA6IFwiYzJcIiB9XSxcblx0ICpcdFx0XCJpZDJcIiA6IFt7IFwidGV4dFwiIDogXCJDaGlsZCBvZiBJRDJcIiwgXCJpZFwiIDogXCJjM1wiIH1dXG5cdCAqXHR9XG5cdCAqIFxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5tYXNzbG9hZFxuXHQgKiBAcGx1Z2luIG1hc3Nsb2FkXG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy5tYXNzbG9hZCA9IG51bGw7XG5cdCQuanN0cmVlLnBsdWdpbnMubWFzc2xvYWQgPSBmdW5jdGlvbiAob3B0aW9ucywgcGFyZW50KSB7XG5cdFx0dGhpcy5pbml0ID0gZnVuY3Rpb24gKGVsLCBvcHRpb25zKSB7XG5cdFx0XHR0aGlzLl9kYXRhLm1hc3Nsb2FkID0ge307XG5cdFx0XHRwYXJlbnQuaW5pdC5jYWxsKHRoaXMsIGVsLCBvcHRpb25zKTtcblx0XHR9O1xuXHRcdHRoaXMuX2xvYWRfbm9kZXMgPSBmdW5jdGlvbiAobm9kZXMsIGNhbGxiYWNrLCBpc19jYWxsYmFjaywgZm9yY2VfcmVsb2FkKSB7XG5cdFx0XHR2YXIgcyA9IHRoaXMuc2V0dGluZ3MubWFzc2xvYWQsXHRcdFx0XHRcblx0XHRcdFx0dG9Mb2FkID0gW10sXG5cdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRpLCBqLCBkb207XG5cdFx0XHRpZiAoIWlzX2NhbGxiYWNrKSB7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IG5vZGVzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdGlmKCFtW25vZGVzW2ldXSB8fCAoICghbVtub2Rlc1tpXV0uc3RhdGUubG9hZGVkICYmICFtW25vZGVzW2ldXS5zdGF0ZS5mYWlsZWQpIHx8IGZvcmNlX3JlbG9hZCkgKSB7XG5cdFx0XHRcdFx0XHR0b0xvYWQucHVzaChub2Rlc1tpXSk7XG5cdFx0XHRcdFx0XHRkb20gPSB0aGlzLmdldF9ub2RlKG5vZGVzW2ldLCB0cnVlKTtcblx0XHRcdFx0XHRcdGlmIChkb20gJiYgZG9tLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRkb20uYWRkQ2xhc3MoXCJqc3RyZWUtbG9hZGluZ1wiKS5hdHRyKCdhcmlhLWJ1c3knLHRydWUpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLl9kYXRhLm1hc3Nsb2FkID0ge307XG5cdFx0XHRcdGlmICh0b0xvYWQubGVuZ3RoKSB7XG5cdFx0XHRcdFx0aWYoJC52YWthdGEuaXNfZnVuY3Rpb24ocykpIHtcblx0XHRcdFx0XHRcdHJldHVybiBzLmNhbGwodGhpcywgdG9Mb2FkLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0XHRcdFx0XHR2YXIgaSwgajtcblx0XHRcdFx0XHRcdFx0aWYoZGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdGZvcihpIGluIGRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKGRhdGEuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5tYXNzbG9hZFtpXSA9IGRhdGFbaV07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGZvcihpID0gMCwgaiA9IG5vZGVzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRcdGRvbSA9IHRoaXMuZ2V0X25vZGUobm9kZXNbaV0sIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdGlmIChkb20gJiYgZG9tLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZG9tLnJlbW92ZUNsYXNzKFwianN0cmVlLWxvYWRpbmdcIikuYXR0cignYXJpYS1idXN5JyxmYWxzZSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHBhcmVudC5fbG9hZF9ub2Rlcy5jYWxsKHRoaXMsIG5vZGVzLCBjYWxsYmFjaywgaXNfY2FsbGJhY2ssIGZvcmNlX3JlbG9hZCk7XG5cdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZih0eXBlb2YgcyA9PT0gJ29iamVjdCcgJiYgcyAmJiBzLnVybCkge1xuXHRcdFx0XHRcdFx0cyA9ICQuZXh0ZW5kKHRydWUsIHt9LCBzKTtcblx0XHRcdFx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKHMudXJsKSkge1xuXHRcdFx0XHRcdFx0XHRzLnVybCA9IHMudXJsLmNhbGwodGhpcywgdG9Mb2FkKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKHMuZGF0YSkpIHtcblx0XHRcdFx0XHRcdFx0cy5kYXRhID0gcy5kYXRhLmNhbGwodGhpcywgdG9Mb2FkKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiAkLmFqYXgocylcblx0XHRcdFx0XHRcdFx0LmRvbmUoZnVuY3Rpb24gKGRhdGEsdCx4KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR2YXIgaSwgajtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKGRhdGEpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgaW4gZGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmKGRhdGEuaGFzT3duUHJvcGVydHkoaSkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEubWFzc2xvYWRbaV0gPSBkYXRhW2ldO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gbm9kZXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGRvbSA9IHRoaXMuZ2V0X25vZGUobm9kZXNbaV0sIHRydWUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoZG9tICYmIGRvbS5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkb20ucmVtb3ZlQ2xhc3MoXCJqc3RyZWUtbG9hZGluZ1wiKS5hdHRyKCdhcmlhLWJ1c3knLGZhbHNlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50Ll9sb2FkX25vZGVzLmNhbGwodGhpcywgbm9kZXMsIGNhbGxiYWNrLCBpc19jYWxsYmFjaywgZm9yY2VfcmVsb2FkKTtcblx0XHRcdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdFx0XHRcdC5mYWlsKGZ1bmN0aW9uIChmKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwYXJlbnQuX2xvYWRfbm9kZXMuY2FsbCh0aGlzLCBub2RlcywgY2FsbGJhY2ssIGlzX2NhbGxiYWNrLCBmb3JjZV9yZWxvYWQpO1xuXHRcdFx0XHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcGFyZW50Ll9sb2FkX25vZGVzLmNhbGwodGhpcywgbm9kZXMsIGNhbGxiYWNrLCBpc19jYWxsYmFjaywgZm9yY2VfcmVsb2FkKTtcblx0XHR9O1xuXHRcdHRoaXMuX2xvYWRfbm9kZSA9IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG5cdFx0XHR2YXIgZGF0YSA9IHRoaXMuX2RhdGEubWFzc2xvYWRbb2JqLmlkXSxcblx0XHRcdFx0cnNsdCA9IG51bGwsIGRvbTtcblx0XHRcdGlmKGRhdGEpIHtcblx0XHRcdFx0cnNsdCA9IHRoaXNbdHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnID8gJ19hcHBlbmRfaHRtbF9kYXRhJyA6ICdfYXBwZW5kX2pzb25fZGF0YSddKFxuXHRcdFx0XHRcdG9iaixcblx0XHRcdFx0XHR0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycgPyAkKCQucGFyc2VIVE1MKGRhdGEpKS5maWx0ZXIoZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5ub2RlVHlwZSAhPT0gMzsgfSkgOiBkYXRhLFxuXHRcdFx0XHRcdGZ1bmN0aW9uIChzdGF0dXMpIHsgY2FsbGJhY2suY2FsbCh0aGlzLCBzdGF0dXMpOyB9XG5cdFx0XHRcdCk7XG5cdFx0XHRcdGRvbSA9IHRoaXMuZ2V0X25vZGUob2JqLmlkLCB0cnVlKTtcblx0XHRcdFx0aWYgKGRvbSAmJiBkb20ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZG9tLnJlbW92ZUNsYXNzKFwianN0cmVlLWxvYWRpbmdcIikuYXR0cignYXJpYS1idXN5JyxmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGVsZXRlIHRoaXMuX2RhdGEubWFzc2xvYWRbb2JqLmlkXTtcblx0XHRcdFx0cmV0dXJuIHJzbHQ7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcGFyZW50Ll9sb2FkX25vZGUuY2FsbCh0aGlzLCBvYmosIGNhbGxiYWNrKTtcblx0XHR9O1xuXHR9O1xuXG5cbi8qKlxuICogIyMjIFNlYXJjaCBwbHVnaW5cbiAqXG4gKiBBZGRzIHNlYXJjaCBmdW5jdGlvbmFsaXR5IHRvIGpzVHJlZS5cbiAqL1xuXG5cdC8qKlxuXHQgKiBzdG9yZXMgYWxsIGRlZmF1bHRzIGZvciB0aGUgc2VhcmNoIHBsdWdpblxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zZWFyY2hcblx0ICogQHBsdWdpbiBzZWFyY2hcblx0ICovXG5cdCQuanN0cmVlLmRlZmF1bHRzLnNlYXJjaCA9IHtcblx0XHQvKipcblx0XHQgKiBhIGpRdWVyeS1saWtlIEFKQVggY29uZmlnLCB3aGljaCBqc3RyZWUgdXNlcyBpZiBhIHNlcnZlciBzaG91bGQgYmUgcXVlcmllZCBmb3IgcmVzdWx0cy5cblx0XHQgKlxuXHRcdCAqIEEgYHN0cmAgKHdoaWNoIGlzIHRoZSBzZWFyY2ggc3RyaW5nKSBwYXJhbWV0ZXIgd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSByZXF1ZXN0LCBhbiBvcHRpb25hbCBgaW5zaWRlYCBwYXJhbWV0ZXIgd2lsbCBiZSBhZGRlZCBpZiB0aGUgc2VhcmNoIGlzIGxpbWl0ZWQgdG8gYSBub2RlIGlkLiBUaGUgZXhwZWN0ZWQgcmVzdWx0IGlzIGEgSlNPTiBhcnJheSB3aXRoIG5vZGVzIHRoYXQgbmVlZCB0byBiZSBvcGVuZWQgc28gdGhhdCBtYXRjaGluZyBub2RlcyB3aWxsIGJlIHJldmVhbGVkLlxuXHRcdCAqIExlYXZlIHRoaXMgc2V0dGluZyBhcyBgZmFsc2VgIHRvIG5vdCBxdWVyeSB0aGUgc2VydmVyLiBZb3UgY2FuIGFsc28gc2V0IHRoaXMgdG8gYSBmdW5jdGlvbiwgd2hpY2ggd2lsbCBiZSBpbnZva2VkIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlIGFuZCByZWNlaXZlIDMgcGFyYW1ldGVycyAtIHRoZSBzZWFyY2ggc3RyaW5nLCB0aGUgY2FsbGJhY2sgdG8gY2FsbCB3aXRoIHRoZSBhcnJheSBvZiBub2RlcyB0byBsb2FkLCBhbmQgdGhlIG9wdGlvbmFsIG5vZGUgSUQgdG8gbGltaXQgdGhlIHNlYXJjaCB0b1xuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnNlYXJjaC5hamF4XG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRhamF4IDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogSW5kaWNhdGVzIGlmIHRoZSBzZWFyY2ggc2hvdWxkIGJlIGZ1enp5IG9yIG5vdCAoc2hvdWxkIGBjaG5kM2AgbWF0Y2ggYGNoaWxkIG5vZGUgM2ApLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuc2VhcmNoLmZ1enp5XG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRmdXp6eSA6IGZhbHNlLFxuXHRcdC8qKlxuXHRcdCAqIEluZGljYXRlcyBpZiB0aGUgc2VhcmNoIHNob3VsZCBiZSBjYXNlIHNlbnNpdGl2ZS4gRGVmYXVsdCBpcyBgZmFsc2VgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnNlYXJjaC5jYXNlX3NlbnNpdGl2ZVxuXHRcdCAqIEBwbHVnaW4gc2VhcmNoXG5cdFx0ICovXG5cdFx0Y2FzZV9zZW5zaXRpdmUgOiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBJbmRpY2F0ZXMgaWYgdGhlIHRyZWUgc2hvdWxkIGJlIGZpbHRlcmVkIChieSBkZWZhdWx0KSB0byBzaG93IG9ubHkgbWF0Y2hpbmcgbm9kZXMgKGtlZXAgaW4gbWluZCB0aGlzIGNhbiBiZSBhIGhlYXZ5IG9uIGxhcmdlIHRyZWVzIGluIG9sZCBicm93c2VycykuXG5cdFx0ICogVGhpcyBzZXR0aW5nIGNhbiBiZSBjaGFuZ2VkIGF0IHJ1bnRpbWUgd2hlbiBjYWxsaW5nIHRoZSBzZWFyY2ggbWV0aG9kLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuc2VhcmNoLnNob3dfb25seV9tYXRjaGVzXG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRzaG93X29ubHlfbWF0Y2hlcyA6IGZhbHNlLFxuXHRcdC8qKlxuXHRcdCAqIEluZGljYXRlcyBpZiB0aGUgY2hpbGRyZW4gb2YgbWF0Y2hlZCBlbGVtZW50IGFyZSBzaG93biAod2hlbiBzaG93X29ubHlfbWF0Y2hlcyBpcyB0cnVlKVxuXHRcdCAqIFRoaXMgc2V0dGluZyBjYW4gYmUgY2hhbmdlZCBhdCBydW50aW1lIHdoZW4gY2FsbGluZyB0aGUgc2VhcmNoIG1ldGhvZC4gRGVmYXVsdCBpcyBgZmFsc2VgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnNlYXJjaC5zaG93X29ubHlfbWF0Y2hlc19jaGlsZHJlblxuXHRcdCAqIEBwbHVnaW4gc2VhcmNoXG5cdFx0ICovXG5cdFx0c2hvd19vbmx5X21hdGNoZXNfY2hpbGRyZW4gOiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBJbmRpY2F0ZXMgaWYgYWxsIG5vZGVzIG9wZW5lZCB0byByZXZlYWwgdGhlIHNlYXJjaCByZXN1bHQsIHNob3VsZCBiZSBjbG9zZWQgd2hlbiB0aGUgc2VhcmNoIGlzIGNsZWFyZWQgb3IgYSBuZXcgc2VhcmNoIGlzIHBlcmZvcm1lZC4gRGVmYXVsdCBpcyBgdHJ1ZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuc2VhcmNoLmNsb3NlX29wZW5lZF9vbmNsZWFyXG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRjbG9zZV9vcGVuZWRfb25jbGVhciA6IHRydWUsXG5cdFx0LyoqXG5cdFx0ICogSW5kaWNhdGVzIGlmIG9ubHkgbGVhZiBub2RlcyBzaG91bGQgYmUgaW5jbHVkZWQgaW4gc2VhcmNoIHJlc3VsdHMuIERlZmF1bHQgaXMgYGZhbHNlYC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zZWFyY2guc2VhcmNoX2xlYXZlc19vbmx5XG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRzZWFyY2hfbGVhdmVzX29ubHkgOiBmYWxzZSxcblx0XHQvKipcblx0XHQgKiBJZiBzZXQgdG8gYSBmdW5jdGlvbiBpdCB3aWwgYmUgY2FsbGVkIGluIHRoZSBpbnN0YW5jZSdzIHNjb3BlIHdpdGggdHdvIGFyZ3VtZW50cyAtIHNlYXJjaCBzdHJpbmcgYW5kIG5vZGUgKHdoZXJlIG5vZGUgd2lsbCBiZSBldmVyeSBub2RlIGluIHRoZSBzdHJ1Y3R1cmUsIHNvIHVzZSB3aXRoIGNhdXRpb24pLlxuXHRcdCAqIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIGEgdHJ1dGh5IHZhbHVlIHRoZSBub2RlIHdpbGwgYmUgY29uc2lkZXJlZCBhIG1hdGNoIChpdCBtaWdodCBub3QgYmUgZGlzcGxheWVkIGlmIHNlYXJjaF9vbmx5X2xlYXZlcyBpcyBzZXQgdG8gdHJ1ZSBhbmQgdGhlIG5vZGUgaXMgbm90IGEgbGVhZikuIERlZmF1bHQgaXMgYGZhbHNlYC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zZWFyY2guc2VhcmNoX2NhbGxiYWNrXG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKi9cblx0XHRzZWFyY2hfY2FsbGJhY2sgOiBmYWxzZVxuXHR9O1xuXG5cdCQuanN0cmVlLnBsdWdpbnMuc2VhcmNoID0gZnVuY3Rpb24gKG9wdGlvbnMsIHBhcmVudCkge1xuXHRcdHRoaXMuYmluZCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHBhcmVudC5iaW5kLmNhbGwodGhpcyk7XG5cblx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLnN0ciA9IFwiXCI7XG5cdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5kb20gPSAkKCk7XG5cdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5yZXMgPSBbXTtcblx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLm9wbiA9IFtdO1xuXHRcdFx0dGhpcy5fZGF0YS5zZWFyY2guc29tID0gZmFsc2U7XG5cdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5zbWMgPSBmYWxzZTtcblx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmhkbiA9IFtdO1xuXG5cdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0Lm9uKFwic2VhcmNoLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0aWYodGhpcy5fZGF0YS5zZWFyY2guc29tICYmIGRhdGEucmVzLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHR2YXIgbSA9IHRoaXMuX21vZGVsLmRhdGEsIGksIGosIHAgPSBbXSwgaywgbDtcblx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gZGF0YS5yZXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYobVtkYXRhLnJlc1tpXV0gJiYgIW1bZGF0YS5yZXNbaV1dLnN0YXRlLmhpZGRlbikge1xuXHRcdFx0XHRcdFx0XHRcdFx0cC5wdXNoKGRhdGEucmVzW2ldKTtcblx0XHRcdFx0XHRcdFx0XHRcdHAgPSBwLmNvbmNhdChtW2RhdGEucmVzW2ldXS5wYXJlbnRzKTtcblx0XHRcdFx0XHRcdFx0XHRcdGlmKHRoaXMuX2RhdGEuc2VhcmNoLnNtYykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRmb3IgKGsgPSAwLCBsID0gbVtkYXRhLnJlc1tpXV0uY2hpbGRyZW5fZC5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAobVttW2RhdGEucmVzW2ldXS5jaGlsZHJlbl9kW2tdXSAmJiAhbVttW2RhdGEucmVzW2ldXS5jaGlsZHJlbl9kW2tdXS5zdGF0ZS5oaWRkZW4pIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHAucHVzaChtW2RhdGEucmVzW2ldXS5jaGlsZHJlbl9kW2tdKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cCA9ICQudmFrYXRhLmFycmF5X3JlbW92ZV9pdGVtKCQudmFrYXRhLmFycmF5X3VuaXF1ZShwKSwgJC5qc3RyZWUucm9vdCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmhkbiA9IHRoaXMuaGlkZV9hbGwodHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuc2hvd19ub2RlKHAsIHRydWUpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLnJlZHJhdyh0cnVlKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbihcImNsZWFyX3NlYXJjaC5qc3RyZWVcIiwgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0XHRcdGlmKHRoaXMuX2RhdGEuc2VhcmNoLnNvbSAmJiBkYXRhLnJlcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5zaG93X25vZGUodGhpcy5fZGF0YS5zZWFyY2guaGRuLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0dGhpcy5yZWRyYXcodHJ1ZSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHVzZWQgdG8gc2VhcmNoIHRoZSB0cmVlIG5vZGVzIGZvciBhIGdpdmVuIHN0cmluZ1xuXHRcdCAqIEBuYW1lIHNlYXJjaChzdHIgWywgc2tpcF9hc3luY10pXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IHN0ciB0aGUgc2VhcmNoIHN0cmluZ1xuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gc2tpcF9hc3luYyBpZiBzZXQgdG8gdHJ1ZSBzZXJ2ZXIgd2lsbCBub3QgYmUgcXVlcmllZCBldmVuIGlmIGNvbmZpZ3VyZWRcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3dfb25seV9tYXRjaGVzIGlmIHNldCB0byB0cnVlIG9ubHkgbWF0Y2hpbmcgbm9kZXMgd2lsbCBiZSBzaG93biAoa2VlcCBpbiBtaW5kIHRoaXMgY2FuIGJlIHZlcnkgc2xvdyBvbiBsYXJnZSB0cmVlcyBvciBvbGQgYnJvd3NlcnMpXG5cdFx0ICogQHBhcmFtIHttaXhlZH0gaW5zaWRlIGFuIG9wdGlvbmFsIG5vZGUgdG8gd2hvc2UgY2hpbGRyZW4gdG8gbGltaXQgdGhlIHNlYXJjaFxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gYXBwZW5kIGlmIHNldCB0byB0cnVlIHRoZSByZXN1bHRzIG9mIHRoaXMgc2VhcmNoIGFyZSBhcHBlbmRlZCB0byB0aGUgcHJldmlvdXMgc2VhcmNoXG5cdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHQgKiBAdHJpZ2dlciBzZWFyY2guanN0cmVlXG5cdFx0ICovXG5cdFx0dGhpcy5zZWFyY2ggPSBmdW5jdGlvbiAoc3RyLCBza2lwX2FzeW5jLCBzaG93X29ubHlfbWF0Y2hlcywgaW5zaWRlLCBhcHBlbmQsIHNob3dfb25seV9tYXRjaGVzX2NoaWxkcmVuKSB7XG5cdFx0XHRpZihzdHIgPT09IGZhbHNlIHx8ICQudmFrYXRhLnRyaW0oc3RyLnRvU3RyaW5nKCkpID09PSBcIlwiKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmNsZWFyX3NlYXJjaCgpO1xuXHRcdFx0fVxuXHRcdFx0aW5zaWRlID0gdGhpcy5nZXRfbm9kZShpbnNpZGUpO1xuXHRcdFx0aW5zaWRlID0gaW5zaWRlICYmIGluc2lkZS5pZCA/IGluc2lkZS5pZCA6IG51bGw7XG5cdFx0XHRzdHIgPSBzdHIudG9TdHJpbmcoKTtcblx0XHRcdHZhciBzID0gdGhpcy5zZXR0aW5ncy5zZWFyY2gsXG5cdFx0XHRcdGEgPSBzLmFqYXggPyBzLmFqYXggOiBmYWxzZSxcblx0XHRcdFx0bSA9IHRoaXMuX21vZGVsLmRhdGEsXG5cdFx0XHRcdGYgPSBudWxsLFxuXHRcdFx0XHRyID0gW10sXG5cdFx0XHRcdHAgPSBbXSwgaSwgajtcblx0XHRcdGlmKHRoaXMuX2RhdGEuc2VhcmNoLnJlcy5sZW5ndGggJiYgIWFwcGVuZCkge1xuXHRcdFx0XHR0aGlzLmNsZWFyX3NlYXJjaCgpO1xuXHRcdFx0fVxuXHRcdFx0aWYoc2hvd19vbmx5X21hdGNoZXMgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRzaG93X29ubHlfbWF0Y2hlcyA9IHMuc2hvd19vbmx5X21hdGNoZXM7XG5cdFx0XHR9XG5cdFx0XHRpZihzaG93X29ubHlfbWF0Y2hlc19jaGlsZHJlbiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHNob3dfb25seV9tYXRjaGVzX2NoaWxkcmVuID0gcy5zaG93X29ubHlfbWF0Y2hlc19jaGlsZHJlbjtcblx0XHRcdH1cblx0XHRcdGlmKCFza2lwX2FzeW5jICYmIGEgIT09IGZhbHNlKSB7XG5cdFx0XHRcdGlmKCQudmFrYXRhLmlzX2Z1bmN0aW9uKGEpKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGEuY2FsbCh0aGlzLCBzdHIsIGZ1bmN0aW9uIChkKSB7XG5cdFx0XHRcdFx0XHRcdGlmKGQgJiYgZC5kKSB7IGQgPSBkLmQ7IH1cblx0XHRcdFx0XHRcdFx0dGhpcy5fbG9hZF9ub2RlcyghJC52YWthdGEuaXNfYXJyYXkoZCkgPyBbXSA6ICQudmFrYXRhLmFycmF5X3VuaXF1ZShkKSwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2VhcmNoKHN0ciwgdHJ1ZSwgc2hvd19vbmx5X21hdGNoZXMsIGluc2lkZSwgYXBwZW5kLCBzaG93X29ubHlfbWF0Y2hlc19jaGlsZHJlbik7XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpLCBpbnNpZGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdGEgPSAkLmV4dGVuZCh7fSwgYSk7XG5cdFx0XHRcdFx0aWYoIWEuZGF0YSkgeyBhLmRhdGEgPSB7fTsgfVxuXHRcdFx0XHRcdGEuZGF0YS5zdHIgPSBzdHI7XG5cdFx0XHRcdFx0aWYoaW5zaWRlKSB7XG5cdFx0XHRcdFx0XHRhLmRhdGEuaW5zaWRlID0gaW5zaWRlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodGhpcy5fZGF0YS5zZWFyY2gubGFzdFJlcXVlc3QpIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmxhc3RSZXF1ZXN0LmFib3J0KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmxhc3RSZXF1ZXN0ID0gJC5hamF4KGEpXG5cdFx0XHRcdFx0XHQuZmFpbChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2FqYXgnLCAncGx1Z2luJyA6ICdzZWFyY2gnLCAnaWQnIDogJ3NlYXJjaF8wMScsICdyZWFzb24nIDogJ0NvdWxkIG5vdCBsb2FkIHNlYXJjaCBwYXJlbnRzJywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoYSkgfTtcblx0XHRcdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5jb3JlLmVycm9yLmNhbGwodGhpcywgdGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IpO1xuXHRcdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHRcdFx0LmRvbmUoZnVuY3Rpb24gKGQpIHtcblx0XHRcdFx0XHRcdFx0aWYoZCAmJiBkLmQpIHsgZCA9IGQuZDsgfVxuXHRcdFx0XHRcdFx0XHR0aGlzLl9sb2FkX25vZGVzKCEkLnZha2F0YS5pc19hcnJheShkKSA/IFtdIDogJC52YWthdGEuYXJyYXlfdW5pcXVlKGQpLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5zZWFyY2goc3RyLCB0cnVlLCBzaG93X29ubHlfbWF0Y2hlcywgaW5zaWRlLCBhcHBlbmQsIHNob3dfb25seV9tYXRjaGVzX2NoaWxkcmVuKTtcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9kYXRhLnNlYXJjaC5sYXN0UmVxdWVzdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYoIWFwcGVuZCkge1xuXHRcdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5zdHIgPSBzdHI7XG5cdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmRvbSA9ICQoKTtcblx0XHRcdFx0dGhpcy5fZGF0YS5zZWFyY2gucmVzID0gW107XG5cdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLm9wbiA9IFtdO1xuXHRcdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5zb20gPSBzaG93X29ubHlfbWF0Y2hlcztcblx0XHRcdFx0dGhpcy5fZGF0YS5zZWFyY2guc21jID0gc2hvd19vbmx5X21hdGNoZXNfY2hpbGRyZW47XG5cdFx0XHR9XG5cblx0XHRcdGYgPSBuZXcgJC52YWthdGEuc2VhcmNoKHN0ciwgdHJ1ZSwgeyBjYXNlU2Vuc2l0aXZlIDogcy5jYXNlX3NlbnNpdGl2ZSwgZnV6enkgOiBzLmZ1enp5IH0pO1xuXHRcdFx0JC5lYWNoKG1baW5zaWRlID8gaW5zaWRlIDogJC5qc3RyZWUucm9vdF0uY2hpbGRyZW5fZCwgZnVuY3Rpb24gKGlpLCBpKSB7XG5cdFx0XHRcdHZhciB2ID0gbVtpXTtcblx0XHRcdFx0aWYodi50ZXh0ICYmICF2LnN0YXRlLmhpZGRlbiAmJiAoIXMuc2VhcmNoX2xlYXZlc19vbmx5IHx8ICh2LnN0YXRlLmxvYWRlZCAmJiB2LmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkpICYmICggKHMuc2VhcmNoX2NhbGxiYWNrICYmIHMuc2VhcmNoX2NhbGxiYWNrLmNhbGwodGhpcywgc3RyLCB2KSkgfHwgKCFzLnNlYXJjaF9jYWxsYmFjayAmJiBmLnNlYXJjaCh2LnRleHQpLmlzTWF0Y2gpICkgKSB7XG5cdFx0XHRcdFx0ci5wdXNoKGkpO1xuXHRcdFx0XHRcdHAgPSBwLmNvbmNhdCh2LnBhcmVudHMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdGlmKHIubGVuZ3RoKSB7XG5cdFx0XHRcdHAgPSAkLnZha2F0YS5hcnJheV91bmlxdWUocCk7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IHAubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0aWYocFtpXSAhPT0gJC5qc3RyZWUucm9vdCAmJiBtW3BbaV1dICYmIHRoaXMub3Blbl9ub2RlKHBbaV0sIG51bGwsIDApID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5vcG4ucHVzaChwW2ldKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIWFwcGVuZCkge1xuXHRcdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmRvbSA9ICQodGhpcy5lbGVtZW50WzBdLnF1ZXJ5U2VsZWN0b3JBbGwoJyMnICsgJC5tYXAociwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFwiMDEyMzQ1Njc4OVwiLmluZGV4T2YodlswXSkgIT09IC0xID8gJ1xcXFwzJyArIHZbMF0gKyAnICcgKyB2LnN1YnN0cigxKS5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpIDogdi5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpOyB9KS5qb2luKCcsICMnKSkpO1xuXHRcdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLnJlcyA9IHI7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fZGF0YS5zZWFyY2guZG9tID0gdGhpcy5fZGF0YS5zZWFyY2guZG9tLmFkZCgkKHRoaXMuZWxlbWVudFswXS5xdWVyeVNlbGVjdG9yQWxsKCcjJyArICQubWFwKHIsIGZ1bmN0aW9uICh2KSB7IHJldHVybiBcIjAxMjM0NTY3ODlcIi5pbmRleE9mKHZbMF0pICE9PSAtMSA/ICdcXFxcMycgKyB2WzBdICsgJyAnICsgdi5zdWJzdHIoMSkucmVwbGFjZSgkLmpzdHJlZS5pZHJlZ2V4LCdcXFxcJCYnKSA6IHYucmVwbGFjZSgkLmpzdHJlZS5pZHJlZ2V4LCdcXFxcJCYnKTsgfSkuam9pbignLCAjJykpKSk7XG5cdFx0XHRcdFx0dGhpcy5fZGF0YS5zZWFyY2gucmVzID0gJC52YWthdGEuYXJyYXlfdW5pcXVlKHRoaXMuX2RhdGEuc2VhcmNoLnJlcy5jb25jYXQocikpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmRvbS5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpLmFkZENsYXNzKCdqc3RyZWUtc2VhcmNoJyk7XG5cdFx0XHR9XG5cdFx0XHQvKipcblx0XHRcdCAqIHRyaWdnZXJlZCBhZnRlciBzZWFyY2ggaXMgY29tcGxldGVcblx0XHRcdCAqIEBldmVudFxuXHRcdFx0ICogQG5hbWUgc2VhcmNoLmpzdHJlZVxuXHRcdFx0ICogQHBhcmFtIHtqUXVlcnl9IG5vZGVzIGEgalF1ZXJ5IGNvbGxlY3Rpb24gb2YgbWF0Y2hpbmcgbm9kZXNcblx0XHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgdGhlIHNlYXJjaCBzdHJpbmdcblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IHJlcyBhIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyByZXByZXNlaW5nIHRoZSBtYXRjaGluZyBub2Rlc1xuXHRcdFx0ICogQHBsdWdpbiBzZWFyY2hcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy50cmlnZ2VyKCdzZWFyY2gnLCB7IG5vZGVzIDogdGhpcy5fZGF0YS5zZWFyY2guZG9tLCBzdHIgOiBzdHIsIHJlcyA6IHRoaXMuX2RhdGEuc2VhcmNoLnJlcywgc2hvd19vbmx5X21hdGNoZXMgOiBzaG93X29ubHlfbWF0Y2hlcyB9KTtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHVzZWQgdG8gY2xlYXIgdGhlIGxhc3Qgc2VhcmNoIChyZW1vdmVzIGNsYXNzZXMgYW5kIHNob3dzIGFsbCBub2RlcyBpZiBmaWx0ZXJpbmcgaXMgb24pXG5cdFx0ICogQG5hbWUgY2xlYXJfc2VhcmNoKClcblx0XHQgKiBAcGx1Z2luIHNlYXJjaFxuXHRcdCAqIEB0cmlnZ2VyIGNsZWFyX3NlYXJjaC5qc3RyZWVcblx0XHQgKi9cblx0XHR0aGlzLmNsZWFyX3NlYXJjaCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmKHRoaXMuc2V0dGluZ3Muc2VhcmNoLmNsb3NlX29wZW5lZF9vbmNsZWFyKSB7XG5cdFx0XHRcdHRoaXMuY2xvc2Vfbm9kZSh0aGlzLl9kYXRhLnNlYXJjaC5vcG4sIDApO1xuXHRcdFx0fVxuXHRcdFx0LyoqXG5cdFx0XHQgKiB0cmlnZ2VyZWQgYWZ0ZXIgc2VhcmNoIGlzIGNvbXBsZXRlXG5cdFx0XHQgKiBAZXZlbnRcblx0XHRcdCAqIEBuYW1lIGNsZWFyX3NlYXJjaC5qc3RyZWVcblx0XHRcdCAqIEBwYXJhbSB7alF1ZXJ5fSBub2RlcyBhIGpRdWVyeSBjb2xsZWN0aW9uIG9mIG1hdGNoaW5nIG5vZGVzICh0aGUgcmVzdWx0IGZyb20gdGhlIGxhc3Qgc2VhcmNoKVxuXHRcdFx0ICogQHBhcmFtIHtTdHJpbmd9IHN0ciB0aGUgc2VhcmNoIHN0cmluZyAodGhlIGxhc3Qgc2VhcmNoIHN0cmluZylcblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IHJlcyBhIGNvbGxlY3Rpb24gb2Ygb2JqZWN0cyByZXByZXNlaW5nIHRoZSBtYXRjaGluZyBub2RlcyAodGhlIHJlc3VsdCBmcm9tIHRoZSBsYXN0IHNlYXJjaClcblx0XHRcdCAqIEBwbHVnaW4gc2VhcmNoXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMudHJpZ2dlcignY2xlYXJfc2VhcmNoJywgeyAnbm9kZXMnIDogdGhpcy5fZGF0YS5zZWFyY2guZG9tLCBzdHIgOiB0aGlzLl9kYXRhLnNlYXJjaC5zdHIsIHJlcyA6IHRoaXMuX2RhdGEuc2VhcmNoLnJlcyB9KTtcblx0XHRcdGlmKHRoaXMuX2RhdGEuc2VhcmNoLnJlcy5sZW5ndGgpIHtcblx0XHRcdFx0dGhpcy5fZGF0YS5zZWFyY2guZG9tID0gJCh0aGlzLmVsZW1lbnRbMF0ucXVlcnlTZWxlY3RvckFsbCgnIycgKyAkLm1hcCh0aGlzLl9kYXRhLnNlYXJjaC5yZXMsIGZ1bmN0aW9uICh2KSB7XG5cdFx0XHRcdFx0cmV0dXJuIFwiMDEyMzQ1Njc4OVwiLmluZGV4T2YodlswXSkgIT09IC0xID8gJ1xcXFwzJyArIHZbMF0gKyAnICcgKyB2LnN1YnN0cigxKS5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpIDogdi5yZXBsYWNlKCQuanN0cmVlLmlkcmVnZXgsJ1xcXFwkJicpO1xuXHRcdFx0XHR9KS5qb2luKCcsICMnKSkpO1xuXHRcdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5kb20uY2hpbGRyZW4oXCIuanN0cmVlLWFuY2hvclwiKS5yZW1vdmVDbGFzcyhcImpzdHJlZS1zZWFyY2hcIik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5zdHIgPSBcIlwiO1xuXHRcdFx0dGhpcy5fZGF0YS5zZWFyY2gucmVzID0gW107XG5cdFx0XHR0aGlzLl9kYXRhLnNlYXJjaC5vcG4gPSBbXTtcblx0XHRcdHRoaXMuX2RhdGEuc2VhcmNoLmRvbSA9ICQoKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5yZWRyYXdfbm9kZSA9IGZ1bmN0aW9uKG9iaiwgZGVlcCwgY2FsbGJhY2ssIGZvcmNlX3JlbmRlcikge1xuXHRcdFx0b2JqID0gcGFyZW50LnJlZHJhd19ub2RlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0XHRpZihvYmopIHtcblx0XHRcdFx0aWYoJC5pbkFycmF5KG9iai5pZCwgdGhpcy5fZGF0YS5zZWFyY2gucmVzKSAhPT0gLTEpIHtcblx0XHRcdFx0XHR2YXIgaSwgaiwgdG1wID0gbnVsbDtcblx0XHRcdFx0XHRmb3IoaSA9IDAsIGogPSBvYmouY2hpbGROb2Rlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdGlmKG9iai5jaGlsZE5vZGVzW2ldICYmIG9iai5jaGlsZE5vZGVzW2ldLmNsYXNzTmFtZSAmJiBvYmouY2hpbGROb2Rlc1tpXS5jbGFzc05hbWUuaW5kZXhPZihcImpzdHJlZS1hbmNob3JcIikgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHRcdHRtcCA9IG9iai5jaGlsZE5vZGVzW2ldO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYodG1wKSB7XG5cdFx0XHRcdFx0XHR0bXAuY2xhc3NOYW1lICs9ICcganN0cmVlLXNlYXJjaCc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gb2JqO1xuXHRcdH07XG5cdH07XG5cblx0Ly8gaGVscGVyc1xuXHQoZnVuY3Rpb24gKCQpIHtcblx0XHQvLyBmcm9tIGh0dHA6Ly9raXJvLm1lL3Byb2plY3RzL2Z1c2UuaHRtbFxuXHRcdCQudmFrYXRhLnNlYXJjaCA9IGZ1bmN0aW9uKHBhdHRlcm4sIHR4dCwgb3B0aW9ucykge1xuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdFx0XHRvcHRpb25zID0gJC5leHRlbmQoe30sICQudmFrYXRhLnNlYXJjaC5kZWZhdWx0cywgb3B0aW9ucyk7XG5cdFx0XHRpZihvcHRpb25zLmZ1enp5ICE9PSBmYWxzZSkge1xuXHRcdFx0XHRvcHRpb25zLmZ1enp5ID0gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdHBhdHRlcm4gPSBvcHRpb25zLmNhc2VTZW5zaXRpdmUgPyBwYXR0ZXJuIDogcGF0dGVybi50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0dmFyIE1BVENIX0xPQ0FUSU9OXHQ9IG9wdGlvbnMubG9jYXRpb24sXG5cdFx0XHRcdE1BVENIX0RJU1RBTkNFXHQ9IG9wdGlvbnMuZGlzdGFuY2UsXG5cdFx0XHRcdE1BVENIX1RIUkVTSE9MRFx0PSBvcHRpb25zLnRocmVzaG9sZCxcblx0XHRcdFx0cGF0dGVybkxlbiA9IHBhdHRlcm4ubGVuZ3RoLFxuXHRcdFx0XHRtYXRjaG1hc2ssIHBhdHRlcm5fYWxwaGFiZXQsIG1hdGNoX2JpdGFwU2NvcmUsIHNlYXJjaDtcblx0XHRcdGlmKHBhdHRlcm5MZW4gPiAzMikge1xuXHRcdFx0XHRvcHRpb25zLmZ1enp5ID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRpZihvcHRpb25zLmZ1enp5KSB7XG5cdFx0XHRcdG1hdGNobWFzayA9IDEgPDwgKHBhdHRlcm5MZW4gLSAxKTtcblx0XHRcdFx0cGF0dGVybl9hbHBoYWJldCA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIG1hc2sgPSB7fSxcblx0XHRcdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBwYXR0ZXJuTGVuOyBpKyspIHtcblx0XHRcdFx0XHRcdG1hc2tbcGF0dGVybi5jaGFyQXQoaSldID0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IHBhdHRlcm5MZW47IGkrKykge1xuXHRcdFx0XHRcdFx0bWFza1twYXR0ZXJuLmNoYXJBdChpKV0gfD0gMSA8PCAocGF0dGVybkxlbiAtIGkgLSAxKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG1hc2s7XG5cdFx0XHRcdH0oKSk7XG5cdFx0XHRcdG1hdGNoX2JpdGFwU2NvcmUgPSBmdW5jdGlvbiAoZSwgeCkge1xuXHRcdFx0XHRcdHZhciBhY2N1cmFjeSA9IGUgLyBwYXR0ZXJuTGVuLFxuXHRcdFx0XHRcdFx0cHJveGltaXR5ID0gTWF0aC5hYnMoTUFUQ0hfTE9DQVRJT04gLSB4KTtcblx0XHRcdFx0XHRpZighTUFUQ0hfRElTVEFOQ0UpIHtcblx0XHRcdFx0XHRcdHJldHVybiBwcm94aW1pdHkgPyAxLjAgOiBhY2N1cmFjeTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIGFjY3VyYWN5ICsgKHByb3hpbWl0eSAvIE1BVENIX0RJU1RBTkNFKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHNlYXJjaCA9IGZ1bmN0aW9uICh0ZXh0KSB7XG5cdFx0XHRcdHRleHQgPSBvcHRpb25zLmNhc2VTZW5zaXRpdmUgPyB0ZXh0LnRvU3RyaW5nKCkgOiB0ZXh0LnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0aWYocGF0dGVybiA9PT0gdGV4dCB8fCB0ZXh0LmluZGV4T2YocGF0dGVybikgIT09IC0xKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGlzTWF0Y2g6IHRydWUsXG5cdFx0XHRcdFx0XHRzY29yZTogMFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIW9wdGlvbnMuZnV6enkpIHtcblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0aXNNYXRjaDogZmFsc2UsXG5cdFx0XHRcdFx0XHRzY29yZTogMVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdFx0dmFyIGksIGosXG5cdFx0XHRcdFx0dGV4dExlbiA9IHRleHQubGVuZ3RoLFxuXHRcdFx0XHRcdHNjb3JlVGhyZXNob2xkID0gTUFUQ0hfVEhSRVNIT0xELFxuXHRcdFx0XHRcdGJlc3RMb2MgPSB0ZXh0LmluZGV4T2YocGF0dGVybiwgTUFUQ0hfTE9DQVRJT04pLFxuXHRcdFx0XHRcdGJpbk1pbiwgYmluTWlkLFxuXHRcdFx0XHRcdGJpbk1heCA9IHBhdHRlcm5MZW4gKyB0ZXh0TGVuLFxuXHRcdFx0XHRcdGxhc3RSZCwgc3RhcnQsIGZpbmlzaCwgcmQsIGNoYXJNYXRjaCxcblx0XHRcdFx0XHRzY29yZSA9IDEsXG5cdFx0XHRcdFx0bG9jYXRpb25zID0gW107XG5cdFx0XHRcdGlmIChiZXN0TG9jICE9PSAtMSkge1xuXHRcdFx0XHRcdHNjb3JlVGhyZXNob2xkID0gTWF0aC5taW4obWF0Y2hfYml0YXBTY29yZSgwLCBiZXN0TG9jKSwgc2NvcmVUaHJlc2hvbGQpO1xuXHRcdFx0XHRcdGJlc3RMb2MgPSB0ZXh0Lmxhc3RJbmRleE9mKHBhdHRlcm4sIE1BVENIX0xPQ0FUSU9OICsgcGF0dGVybkxlbik7XG5cdFx0XHRcdFx0aWYgKGJlc3RMb2MgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHRzY29yZVRocmVzaG9sZCA9IE1hdGgubWluKG1hdGNoX2JpdGFwU2NvcmUoMCwgYmVzdExvYyksIHNjb3JlVGhyZXNob2xkKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0YmVzdExvYyA9IC0xO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgcGF0dGVybkxlbjsgaSsrKSB7XG5cdFx0XHRcdFx0YmluTWluID0gMDtcblx0XHRcdFx0XHRiaW5NaWQgPSBiaW5NYXg7XG5cdFx0XHRcdFx0d2hpbGUgKGJpbk1pbiA8IGJpbk1pZCkge1xuXHRcdFx0XHRcdFx0aWYgKG1hdGNoX2JpdGFwU2NvcmUoaSwgTUFUQ0hfTE9DQVRJT04gKyBiaW5NaWQpIDw9IHNjb3JlVGhyZXNob2xkKSB7XG5cdFx0XHRcdFx0XHRcdGJpbk1pbiA9IGJpbk1pZDtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGJpbk1heCA9IGJpbk1pZDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJpbk1pZCA9IE1hdGguZmxvb3IoKGJpbk1heCAtIGJpbk1pbikgLyAyICsgYmluTWluKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YmluTWF4ID0gYmluTWlkO1xuXHRcdFx0XHRcdHN0YXJ0ID0gTWF0aC5tYXgoMSwgTUFUQ0hfTE9DQVRJT04gLSBiaW5NaWQgKyAxKTtcblx0XHRcdFx0XHRmaW5pc2ggPSBNYXRoLm1pbihNQVRDSF9MT0NBVElPTiArIGJpbk1pZCwgdGV4dExlbikgKyBwYXR0ZXJuTGVuO1xuXHRcdFx0XHRcdHJkID0gbmV3IEFycmF5KGZpbmlzaCArIDIpO1xuXHRcdFx0XHRcdHJkW2ZpbmlzaCArIDFdID0gKDEgPDwgaSkgLSAxO1xuXHRcdFx0XHRcdGZvciAoaiA9IGZpbmlzaDsgaiA+PSBzdGFydDsgai0tKSB7XG5cdFx0XHRcdFx0XHRjaGFyTWF0Y2ggPSBwYXR0ZXJuX2FscGhhYmV0W3RleHQuY2hhckF0KGogLSAxKV07XG5cdFx0XHRcdFx0XHRpZiAoaSA9PT0gMCkge1xuXHRcdFx0XHRcdFx0XHRyZFtqXSA9ICgocmRbaiArIDFdIDw8IDEpIHwgMSkgJiBjaGFyTWF0Y2g7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZFtqXSA9ICgocmRbaiArIDFdIDw8IDEpIHwgMSkgJiBjaGFyTWF0Y2ggfCAoKChsYXN0UmRbaiArIDFdIHwgbGFzdFJkW2pdKSA8PCAxKSB8IDEpIHwgbGFzdFJkW2ogKyAxXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChyZFtqXSAmIG1hdGNobWFzaykge1xuXHRcdFx0XHRcdFx0XHRzY29yZSA9IG1hdGNoX2JpdGFwU2NvcmUoaSwgaiAtIDEpO1xuXHRcdFx0XHRcdFx0XHRpZiAoc2NvcmUgPD0gc2NvcmVUaHJlc2hvbGQpIHtcblx0XHRcdFx0XHRcdFx0XHRzY29yZVRocmVzaG9sZCA9IHNjb3JlO1xuXHRcdFx0XHRcdFx0XHRcdGJlc3RMb2MgPSBqIC0gMTtcblx0XHRcdFx0XHRcdFx0XHRsb2NhdGlvbnMucHVzaChiZXN0TG9jKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoYmVzdExvYyA+IE1BVENIX0xPQ0FUSU9OKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRzdGFydCA9IE1hdGgubWF4KDEsIDIgKiBNQVRDSF9MT0NBVElPTiAtIGJlc3RMb2MpO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKG1hdGNoX2JpdGFwU2NvcmUoaSArIDEsIE1BVENIX0xPQ0FUSU9OKSA+IHNjb3JlVGhyZXNob2xkKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bGFzdFJkID0gcmQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRpc01hdGNoOiBiZXN0TG9jID49IDAsXG5cdFx0XHRcdFx0c2NvcmU6IHNjb3JlXG5cdFx0XHRcdH07XG5cdFx0XHR9O1xuXHRcdFx0cmV0dXJuIHR4dCA9PT0gdHJ1ZSA/IHsgJ3NlYXJjaCcgOiBzZWFyY2ggfSA6IHNlYXJjaCh0eHQpO1xuXHRcdH07XG5cdFx0JC52YWthdGEuc2VhcmNoLmRlZmF1bHRzID0ge1xuXHRcdFx0bG9jYXRpb24gOiAwLFxuXHRcdFx0ZGlzdGFuY2UgOiAxMDAsXG5cdFx0XHR0aHJlc2hvbGQgOiAwLjYsXG5cdFx0XHRmdXp6eSA6IGZhbHNlLFxuXHRcdFx0Y2FzZVNlbnNpdGl2ZSA6IGZhbHNlXG5cdFx0fTtcblx0fSgkKSk7XG5cblx0Ly8gaW5jbHVkZSB0aGUgc2VhcmNoIHBsdWdpbiBieSBkZWZhdWx0XG5cdC8vICQuanN0cmVlLmRlZmF1bHRzLnBsdWdpbnMucHVzaChcInNlYXJjaFwiKTtcblxuXG4vKipcbiAqICMjIyBTb3J0IHBsdWdpblxuICpcbiAqIEF1dG9tYXRpY2FsbHkgc29ydHMgYWxsIHNpYmxpbmdzIGluIHRoZSB0cmVlIGFjY29yZGluZyB0byBhIHNvcnRpbmcgZnVuY3Rpb24uXG4gKi9cblxuXHQvKipcblx0ICogdGhlIHNldHRpbmdzIGZ1bmN0aW9uIHVzZWQgdG8gc29ydCB0aGUgbm9kZXMuXG5cdCAqIEl0IGlzIGV4ZWN1dGVkIGluIHRoZSB0cmVlJ3MgY29udGV4dCwgYWNjZXB0cyB0d28gbm9kZXMgYXMgYXJndW1lbnRzIGFuZCBzaG91bGQgcmV0dXJuIGAxYCBvciBgLTFgLlxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zb3J0XG5cdCAqIEBwbHVnaW4gc29ydFxuXHQgKi9cblx0JC5qc3RyZWUuZGVmYXVsdHMuc29ydCA9IGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0Ly9yZXR1cm4gdGhpcy5nZXRfdHlwZShhKSA9PT0gdGhpcy5nZXRfdHlwZShiKSA/ICh0aGlzLmdldF90ZXh0KGEpID4gdGhpcy5nZXRfdGV4dChiKSA/IDEgOiAtMSkgOiB0aGlzLmdldF90eXBlKGEpID49IHRoaXMuZ2V0X3R5cGUoYik7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0X3RleHQoYSkgPiB0aGlzLmdldF90ZXh0KGIpID8gMSA6IC0xO1xuXHR9O1xuXHQkLmpzdHJlZS5wbHVnaW5zLnNvcnQgPSBmdW5jdGlvbiAob3B0aW9ucywgcGFyZW50KSB7XG5cdFx0dGhpcy5iaW5kID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cGFyZW50LmJpbmQuY2FsbCh0aGlzKTtcblx0XHRcdHRoaXMuZWxlbWVudFxuXHRcdFx0XHQub24oXCJtb2RlbC5qc3RyZWVcIiwgZnVuY3Rpb24gKGUsIGRhdGEpIHtcblx0XHRcdFx0XHRcdHRoaXMuc29ydChkYXRhLnBhcmVudCwgdHJ1ZSk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJyZW5hbWVfbm9kZS5qc3RyZWUgY3JlYXRlX25vZGUuanN0cmVlXCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnNvcnQoZGF0YS5wYXJlbnQgfHwgZGF0YS5ub2RlLnBhcmVudCwgZmFsc2UpO1xuXHRcdFx0XHRcdFx0dGhpcy5yZWRyYXdfbm9kZShkYXRhLnBhcmVudCB8fCBkYXRhLm5vZGUucGFyZW50LCB0cnVlKTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbihcIm1vdmVfbm9kZS5qc3RyZWUgY29weV9ub2RlLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0dGhpcy5zb3J0KGRhdGEucGFyZW50LCBmYWxzZSk7XG5cdFx0XHRcdFx0XHR0aGlzLnJlZHJhd19ub2RlKGRhdGEucGFyZW50LCB0cnVlKTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogdXNlZCB0byBzb3J0IGEgbm9kZSdzIGNoaWxkcmVuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAbmFtZSBzb3J0KG9iaiBbLCBkZWVwXSlcblx0XHQgKiBAcGFyYW0gIHttaXhlZH0gb2JqIHRoZSBub2RlXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBkZWVwIGlmIHNldCB0byBgdHJ1ZWAgbm9kZXMgYXJlIHNvcnRlZCByZWN1cnNpdmVseS5cblx0XHQgKiBAcGx1Z2luIHNvcnRcblx0XHQgKiBAdHJpZ2dlciBzZWFyY2guanN0cmVlXG5cdFx0ICovXG5cdFx0dGhpcy5zb3J0ID0gZnVuY3Rpb24gKG9iaiwgZGVlcCkge1xuXHRcdFx0dmFyIGksIGo7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZihvYmogJiYgb2JqLmNoaWxkcmVuICYmIG9iai5jaGlsZHJlbi5sZW5ndGgpIHtcblx0XHRcdFx0b2JqLmNoaWxkcmVuLnNvcnQodGhpcy5zZXR0aW5ncy5zb3J0LmJpbmQodGhpcykpO1xuXHRcdFx0XHRpZihkZWVwKSB7XG5cdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLmNoaWxkcmVuX2QubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnNvcnQob2JqLmNoaWxkcmVuX2RbaV0sIGZhbHNlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9O1xuXG5cdC8vIGluY2x1ZGUgdGhlIHNvcnQgcGx1Z2luIGJ5IGRlZmF1bHRcblx0Ly8gJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2lucy5wdXNoKFwic29ydFwiKTtcblxuLyoqXG4gKiAjIyMgU3RhdGUgcGx1Z2luXG4gKlxuICogU2F2ZXMgdGhlIHN0YXRlIG9mIHRoZSB0cmVlIChzZWxlY3RlZCBub2Rlcywgb3BlbmVkIG5vZGVzKSBvbiB0aGUgdXNlcidzIGNvbXB1dGVyIHVzaW5nIGF2YWlsYWJsZSBvcHRpb25zIChsb2NhbFN0b3JhZ2UsIGNvb2tpZXMsIGV0YylcbiAqL1xuXG5cdHZhciB0byA9IGZhbHNlO1xuXHQvKipcblx0ICogc3RvcmVzIGFsbCBkZWZhdWx0cyBmb3IgdGhlIHN0YXRlIHBsdWdpblxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zdGF0ZVxuXHQgKiBAcGx1Z2luIHN0YXRlXG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy5zdGF0ZSA9IHtcblx0XHQvKipcblx0XHQgKiBBIHN0cmluZyBmb3IgdGhlIGtleSB0byB1c2Ugd2hlbiBzYXZpbmcgdGhlIGN1cnJlbnQgdHJlZSAoY2hhbmdlIGlmIHVzaW5nIG11bHRpcGxlIHRyZWVzIGluIHlvdXIgcHJvamVjdCkuIERlZmF1bHRzIHRvIGBqc3RyZWVgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnN0YXRlLmtleVxuXHRcdCAqIEBwbHVnaW4gc3RhdGVcblx0XHQgKi9cblx0XHRrZXlcdFx0OiAnanN0cmVlJyxcblx0XHQvKipcblx0XHQgKiBBIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGV2ZW50cyB0aGF0IHRyaWdnZXIgYSBzdGF0ZSBzYXZlLiBEZWZhdWx0cyB0byBgY2hhbmdlZC5qc3RyZWUgb3Blbl9ub2RlLmpzdHJlZSBjbG9zZV9ub2RlLmpzdHJlZWAuXG5cdFx0ICogQG5hbWUgJC5qc3RyZWUuZGVmYXVsdHMuc3RhdGUuZXZlbnRzXG5cdFx0ICogQHBsdWdpbiBzdGF0ZVxuXHRcdCAqL1xuXHRcdGV2ZW50c1x0OiAnY2hhbmdlZC5qc3RyZWUgb3Blbl9ub2RlLmpzdHJlZSBjbG9zZV9ub2RlLmpzdHJlZSBjaGVja19ub2RlLmpzdHJlZSB1bmNoZWNrX25vZGUuanN0cmVlJyxcblx0XHQvKipcblx0XHQgKiBUaW1lIGluIG1pbGxpc2Vjb25kcyBhZnRlciB3aGljaCB0aGUgc3RhdGUgd2lsbCBleHBpcmUuIERlZmF1bHRzIHRvICdmYWxzZScgbWVhbmluZyAtIG5vIGV4cGlyZS5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zdGF0ZS50dGxcblx0XHQgKiBAcGx1Z2luIHN0YXRlXG5cdFx0ICovXG5cdFx0dHRsXHRcdDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgcHJpb3IgdG8gcmVzdG9yaW5nIHN0YXRlIHdpdGggb25lIGFyZ3VtZW50IC0gdGhlIHN0YXRlIG9iamVjdC4gQ2FuIGJlIHVzZWQgdG8gY2xlYXIgdW53YW50ZWQgcGFydHMgb2YgdGhlIHN0YXRlLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnN0YXRlLmZpbHRlclxuXHRcdCAqIEBwbHVnaW4gc3RhdGVcblx0XHQgKi9cblx0XHRmaWx0ZXJcdDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogU2hvdWxkIGxvYWRlZCBub2RlcyBiZSByZXN0b3JlZCAoc2V0dGluZyB0aGlzIHRvIHRydWUgbWVhbnMgdGhhdCBpdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSB3aG9sZSB0cmVlIHdpbGwgYmUgbG9hZGVkIGZvciBzb21lIHVzZXJzIC0gdXNlIHdpdGggY2F1dGlvbikuIERlZmF1bHRzIHRvIGBmYWxzZWBcblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy5zdGF0ZS5wcmVzZXJ2ZV9sb2FkZWRcblx0XHQgKiBAcGx1Z2luIHN0YXRlXG5cdFx0ICovXG5cdFx0cHJlc2VydmVfbG9hZGVkIDogZmFsc2Vcblx0fTtcblx0JC5qc3RyZWUucGx1Z2lucy5zdGF0ZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBwYXJlbnQpIHtcblx0XHR0aGlzLmJpbmQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRwYXJlbnQuYmluZC5jYWxsKHRoaXMpO1xuXHRcdFx0dmFyIGJpbmQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHRoaXMuZWxlbWVudC5vbih0aGlzLnNldHRpbmdzLnN0YXRlLmV2ZW50cywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGlmKHRvKSB7IGNsZWFyVGltZW91dCh0byk7IH1cblx0XHRcdFx0XHR0byA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyB0aGlzLnNhdmVfc3RhdGUoKTsgfS5iaW5kKHRoaXMpLCAxMDApO1xuXHRcdFx0XHR9LmJpbmQodGhpcykpO1xuXHRcdFx0XHQvKipcblx0XHRcdFx0ICogdHJpZ2dlcmVkIHdoZW4gdGhlIHN0YXRlIHBsdWdpbiBpcyBmaW5pc2hlZCByZXN0b3JpbmcgdGhlIHN0YXRlIChhbmQgaW1tZWRpYXRlbHkgYWZ0ZXIgcmVhZHkgaWYgdGhlcmUgaXMgbm8gc3RhdGUgdG8gcmVzdG9yZSkuXG5cdFx0XHRcdCAqIEBldmVudFxuXHRcdFx0XHQgKiBAbmFtZSBzdGF0ZV9yZWFkeS5qc3RyZWVcblx0XHRcdFx0ICogQHBsdWdpbiBzdGF0ZVxuXHRcdFx0XHQgKi9cblx0XHRcdFx0dGhpcy50cmlnZ2VyKCdzdGF0ZV9yZWFkeScpO1xuXHRcdFx0fS5iaW5kKHRoaXMpO1xuXHRcdFx0dGhpcy5lbGVtZW50XG5cdFx0XHRcdC5vbihcInJlYWR5LmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50Lm9uZShcInJlc3RvcmVfc3RhdGUuanN0cmVlXCIsIGJpbmQpO1xuXHRcdFx0XHRcdFx0aWYoIXRoaXMucmVzdG9yZV9zdGF0ZSgpKSB7IGJpbmQoKTsgfVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0fTtcblx0XHQvKipcblx0XHQgKiBzYXZlIHRoZSBzdGF0ZVxuXHRcdCAqIEBuYW1lIHNhdmVfc3RhdGUoKVxuXHRcdCAqIEBwbHVnaW4gc3RhdGVcblx0XHQgKi9cblx0XHR0aGlzLnNhdmVfc3RhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgdG0gPSB0aGlzLmdldF9zdGF0ZSgpO1xuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLnN0YXRlLnByZXNlcnZlX2xvYWRlZCkge1xuXHRcdFx0XHRkZWxldGUgdG0uY29yZS5sb2FkZWQ7XG5cdFx0XHR9XG5cdFx0XHR2YXIgc3QgPSB7ICdzdGF0ZScgOiB0bSwgJ3R0bCcgOiB0aGlzLnNldHRpbmdzLnN0YXRlLnR0bCwgJ3NlYycgOiArKG5ldyBEYXRlKCkpIH07XG5cdFx0XHQkLnZha2F0YS5zdG9yYWdlLnNldCh0aGlzLnNldHRpbmdzLnN0YXRlLmtleSwgSlNPTi5zdHJpbmdpZnkoc3QpKTtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHJlc3RvcmUgdGhlIHN0YXRlIGZyb20gdGhlIHVzZXIncyBjb21wdXRlclxuXHRcdCAqIEBuYW1lIHJlc3RvcmVfc3RhdGUoKVxuXHRcdCAqIEBwbHVnaW4gc3RhdGVcblx0XHQgKi9cblx0XHR0aGlzLnJlc3RvcmVfc3RhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgayA9ICQudmFrYXRhLnN0b3JhZ2UuZ2V0KHRoaXMuc2V0dGluZ3Muc3RhdGUua2V5KTtcblx0XHRcdGlmKCEhaykgeyB0cnkgeyBrID0gSlNPTi5wYXJzZShrKTsgfSBjYXRjaChleCkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXHRcdFx0aWYoISFrICYmIGsudHRsICYmIGsuc2VjICYmICsobmV3IERhdGUoKSkgLSBrLnNlYyA+IGsudHRsKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0aWYoISFrICYmIGsuc3RhdGUpIHsgayA9IGsuc3RhdGU7IH1cblx0XHRcdGlmKCEhayAmJiAkLnZha2F0YS5pc19mdW5jdGlvbih0aGlzLnNldHRpbmdzLnN0YXRlLmZpbHRlcikpIHsgayA9IHRoaXMuc2V0dGluZ3Muc3RhdGUuZmlsdGVyLmNhbGwodGhpcywgayk7IH1cblx0XHRcdGlmKCEhaykge1xuXHRcdFx0XHRpZiAoIXRoaXMuc2V0dGluZ3Muc3RhdGUucHJlc2VydmVfbG9hZGVkKSB7XG5cdFx0XHRcdFx0ZGVsZXRlIGsuY29yZS5sb2FkZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5lbGVtZW50Lm9uZShcInNldF9zdGF0ZS5qc3RyZWVcIiwgZnVuY3Rpb24gKGUsIGRhdGEpIHsgZGF0YS5pbnN0YW5jZS50cmlnZ2VyKCdyZXN0b3JlX3N0YXRlJywgeyAnc3RhdGUnIDogJC5leHRlbmQodHJ1ZSwge30sIGspIH0pOyB9KTtcblx0XHRcdFx0dGhpcy5zZXRfc3RhdGUoayk7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cdFx0LyoqXG5cdFx0ICogY2xlYXIgdGhlIHN0YXRlIG9uIHRoZSB1c2VyJ3MgY29tcHV0ZXJcblx0XHQgKiBAbmFtZSBjbGVhcl9zdGF0ZSgpXG5cdFx0ICogQHBsdWdpbiBzdGF0ZVxuXHRcdCAqL1xuXHRcdHRoaXMuY2xlYXJfc3RhdGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gJC52YWthdGEuc3RvcmFnZS5kZWwodGhpcy5zZXR0aW5ncy5zdGF0ZS5rZXkpO1xuXHRcdH07XG5cdH07XG5cblx0KGZ1bmN0aW9uICgkLCB1bmRlZmluZWQpIHtcblx0XHQkLnZha2F0YS5zdG9yYWdlID0ge1xuXHRcdFx0Ly8gc2ltcGx5IHNwZWNpZnlpbmcgdGhlIGZ1bmN0aW9ucyBpbiBGRiB0aHJvd3MgYW4gZXJyb3Jcblx0XHRcdHNldCA6IGZ1bmN0aW9uIChrZXksIHZhbCkgeyByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgdmFsKTsgfSxcblx0XHRcdGdldCA6IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShrZXkpOyB9LFxuXHRcdFx0ZGVsIDogZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7IH1cblx0XHR9O1xuXHR9KCQpKTtcblxuXHQvLyBpbmNsdWRlIHRoZSBzdGF0ZSBwbHVnaW4gYnkgZGVmYXVsdFxuXHQvLyAkLmpzdHJlZS5kZWZhdWx0cy5wbHVnaW5zLnB1c2goXCJzdGF0ZVwiKTtcblxuLyoqXG4gKiAjIyMgVHlwZXMgcGx1Z2luXG4gKlxuICogTWFrZXMgaXQgcG9zc2libGUgdG8gYWRkIHByZWRlZmluZWQgdHlwZXMgZm9yIGdyb3VwcyBvZiBub2Rlcywgd2hpY2ggbWFrZSBpdCBwb3NzaWJsZSB0byBlYXNpbHkgY29udHJvbCBuZXN0aW5nIHJ1bGVzIGFuZCBpY29uIGZvciBlYWNoIGdyb3VwLlxuICovXG5cblx0LyoqXG5cdCAqIEFuIG9iamVjdCBzdG9yaW5nIGFsbCB0eXBlcyBhcyBrZXkgdmFsdWUgcGFpcnMsIHdoZXJlIHRoZSBrZXkgaXMgdGhlIHR5cGUgbmFtZSBhbmQgdGhlIHZhbHVlIGlzIGFuIG9iamVjdCB0aGF0IGNvdWxkIGNvbnRhaW4gZm9sbG93aW5nIGtleXMgKGFsbCBvcHRpb25hbCkuXG5cdCAqXG5cdCAqICogYG1heF9jaGlsZHJlbmAgdGhlIG1heGltdW0gbnVtYmVyIG9mIGltbWVkaWF0ZSBjaGlsZHJlbiB0aGlzIG5vZGUgdHlwZSBjYW4gaGF2ZS4gRG8gbm90IHNwZWNpZnkgb3Igc2V0IHRvIGAtMWAgZm9yIHVubGltaXRlZC5cblx0ICogKiBgbWF4X2RlcHRoYCB0aGUgbWF4aW11bSBudW1iZXIgb2YgbmVzdGluZyB0aGlzIG5vZGUgdHlwZSBjYW4gaGF2ZS4gQSB2YWx1ZSBvZiBgMWAgd291bGQgbWVhbiB0aGF0IHRoZSBub2RlIGNhbiBoYXZlIGNoaWxkcmVuLCBidXQgbm8gZ3JhbmRjaGlsZHJlbi4gRG8gbm90IHNwZWNpZnkgb3Igc2V0IHRvIGAtMWAgZm9yIHVubGltaXRlZC5cblx0ICogKiBgdmFsaWRfY2hpbGRyZW5gIGFuIGFycmF5IG9mIG5vZGUgdHlwZSBzdHJpbmdzLCB0aGF0IG5vZGVzIG9mIHRoaXMgdHlwZSBjYW4gaGF2ZSBhcyBjaGlsZHJlbi4gRG8gbm90IHNwZWNpZnkgb3Igc2V0IHRvIGAtMWAgZm9yIG5vIGxpbWl0cy5cblx0ICogKiBgaWNvbmAgYSBzdHJpbmcgLSBjYW4gYmUgYSBwYXRoIHRvIGFuIGljb24gb3IgYSBjbGFzc05hbWUsIGlmIHVzaW5nIGFuIGltYWdlIHRoYXQgaXMgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5IHVzZSBhIGAuL2AgcHJlZml4LCBvdGhlcndpc2UgaXQgd2lsbCBiZSBkZXRlY3RlZCBhcyBhIGNsYXNzLiBPbWl0IHRvIHVzZSB0aGUgZGVmYXVsdCBpY29uIGZyb20geW91ciB0aGVtZS5cblx0ICogKiBgbGlfYXR0cmAgYW4gb2JqZWN0IG9mIHZhbHVlcyB3aGljaCB3aWxsIGJlIHVzZWQgdG8gYWRkIEhUTUwgYXR0cmlidXRlcyBvbiB0aGUgcmVzdWx0aW5nIExJIERPTSBub2RlIChtZXJnZWQgd2l0aCB0aGUgbm9kZSdzIG93biBkYXRhKVxuXHQgKiAqIGBhX2F0dHJgIGFuIG9iamVjdCBvZiB2YWx1ZXMgd2hpY2ggd2lsbCBiZSB1c2VkIHRvIGFkZCBIVE1MIGF0dHJpYnV0ZXMgb24gdGhlIHJlc3VsdGluZyBBIERPTSBub2RlIChtZXJnZWQgd2l0aCB0aGUgbm9kZSdzIG93biBkYXRhKVxuXHQgKlxuXHQgKiBUaGVyZSBhcmUgdHdvIHByZWRlZmluZWQgdHlwZXM6XG5cdCAqXG5cdCAqICogYCNgIHJlcHJlc2VudHMgdGhlIHJvb3Qgb2YgdGhlIHRyZWUsIGZvciBleGFtcGxlIGBtYXhfY2hpbGRyZW5gIHdvdWxkIGNvbnRyb2wgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJvb3Qgbm9kZXMuXG5cdCAqICogYGRlZmF1bHRgIHJlcHJlc2VudHMgdGhlIGRlZmF1bHQgbm9kZSAtIGFueSBzZXR0aW5ncyBoZXJlIHdpbGwgYmUgYXBwbGllZCB0byBhbGwgbm9kZXMgdGhhdCBkbyBub3QgaGF2ZSBhIHR5cGUgc3BlY2lmaWVkLlxuXHQgKlxuXHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy50eXBlc1xuXHQgKiBAcGx1Z2luIHR5cGVzXG5cdCAqL1xuXHQkLmpzdHJlZS5kZWZhdWx0cy50eXBlcyA9IHtcblx0XHQnZGVmYXVsdCcgOiB7fVxuXHR9O1xuXHQkLmpzdHJlZS5kZWZhdWx0cy50eXBlc1skLmpzdHJlZS5yb290XSA9IHt9O1xuXG5cdCQuanN0cmVlLnBsdWdpbnMudHlwZXMgPSBmdW5jdGlvbiAob3B0aW9ucywgcGFyZW50KSB7XG5cdFx0dGhpcy5pbml0ID0gZnVuY3Rpb24gKGVsLCBvcHRpb25zKSB7XG5cdFx0XHR2YXIgaSwgajtcblx0XHRcdGlmKG9wdGlvbnMgJiYgb3B0aW9ucy50eXBlcyAmJiBvcHRpb25zLnR5cGVzWydkZWZhdWx0J10pIHtcblx0XHRcdFx0Zm9yKGkgaW4gb3B0aW9ucy50eXBlcykge1xuXHRcdFx0XHRcdGlmKGkgIT09IFwiZGVmYXVsdFwiICYmIGkgIT09ICQuanN0cmVlLnJvb3QgJiYgb3B0aW9ucy50eXBlcy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuXHRcdFx0XHRcdFx0Zm9yKGogaW4gb3B0aW9ucy50eXBlc1snZGVmYXVsdCddKSB7XG5cdFx0XHRcdFx0XHRcdGlmKG9wdGlvbnMudHlwZXNbJ2RlZmF1bHQnXS5oYXNPd25Qcm9wZXJ0eShqKSAmJiBvcHRpb25zLnR5cGVzW2ldW2pdID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRvcHRpb25zLnR5cGVzW2ldW2pdID0gb3B0aW9ucy50eXBlc1snZGVmYXVsdCddW2pdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRwYXJlbnQuaW5pdC5jYWxsKHRoaXMsIGVsLCBvcHRpb25zKTtcblx0XHRcdHRoaXMuX21vZGVsLmRhdGFbJC5qc3RyZWUucm9vdF0udHlwZSA9ICQuanN0cmVlLnJvb3Q7XG5cdFx0fTtcblx0XHR0aGlzLnJlZnJlc2ggPSBmdW5jdGlvbiAoc2tpcF9sb2FkaW5nLCBmb3JnZXRfc3RhdGUpIHtcblx0XHRcdHBhcmVudC5yZWZyZXNoLmNhbGwodGhpcywgc2tpcF9sb2FkaW5nLCBmb3JnZXRfc3RhdGUpO1xuXHRcdFx0dGhpcy5fbW9kZWwuZGF0YVskLmpzdHJlZS5yb290XS50eXBlID0gJC5qc3RyZWUucm9vdDtcblx0XHR9O1xuXHRcdHRoaXMuYmluZCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRoaXMuZWxlbWVudFxuXHRcdFx0XHQub24oJ21vZGVsLmpzdHJlZScsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHR2YXIgbSA9IHRoaXMuX21vZGVsLmRhdGEsXG5cdFx0XHRcdFx0XHRcdGRwYyA9IGRhdGEubm9kZXMsXG5cdFx0XHRcdFx0XHRcdHQgPSB0aGlzLnNldHRpbmdzLnR5cGVzLFxuXHRcdFx0XHRcdFx0XHRpLCBqLCBjID0gJ2RlZmF1bHQnLCBrO1xuXHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gZHBjLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRjID0gJ2RlZmF1bHQnO1xuXHRcdFx0XHRcdFx0XHRpZihtW2RwY1tpXV0ub3JpZ2luYWwgJiYgbVtkcGNbaV1dLm9yaWdpbmFsLnR5cGUgJiYgdFttW2RwY1tpXV0ub3JpZ2luYWwudHlwZV0pIHtcblx0XHRcdFx0XHRcdFx0XHRjID0gbVtkcGNbaV1dLm9yaWdpbmFsLnR5cGU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYobVtkcGNbaV1dLmRhdGEgJiYgbVtkcGNbaV1dLmRhdGEuanN0cmVlICYmIG1bZHBjW2ldXS5kYXRhLmpzdHJlZS50eXBlICYmIHRbbVtkcGNbaV1dLmRhdGEuanN0cmVlLnR5cGVdKSB7XG5cdFx0XHRcdFx0XHRcdFx0YyA9IG1bZHBjW2ldXS5kYXRhLmpzdHJlZS50eXBlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdG1bZHBjW2ldXS50eXBlID0gYztcblx0XHRcdFx0XHRcdFx0aWYobVtkcGNbaV1dLmljb24gPT09IHRydWUgJiYgdFtjXS5pY29uICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRtW2RwY1tpXV0uaWNvbiA9IHRbY10uaWNvbjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZih0W2NdLmxpX2F0dHIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdFtjXS5saV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRcdFx0XHRcdGZvciAoayBpbiB0W2NdLmxpX2F0dHIpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICh0W2NdLmxpX2F0dHIuaGFzT3duUHJvcGVydHkoaykpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKGsgPT09ICdpZCcpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRlbHNlIGlmIChtW2RwY1tpXV0ubGlfYXR0cltrXSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bVtkcGNbaV1dLmxpX2F0dHJba10gPSB0W2NdLmxpX2F0dHJba107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0ZWxzZSBpZiAoayA9PT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1bZHBjW2ldXS5saV9hdHRyWydjbGFzcyddID0gdFtjXS5saV9hdHRyWydjbGFzcyddICsgJyAnICsgbVtkcGNbaV1dLmxpX2F0dHJbJ2NsYXNzJ107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0aWYodFtjXS5hX2F0dHIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdFtjXS5hX2F0dHIgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yIChrIGluIHRbY10uYV9hdHRyKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAodFtjXS5hX2F0dHIuaGFzT3duUHJvcGVydHkoaykpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKGsgPT09ICdpZCcpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRlbHNlIGlmIChtW2RwY1tpXV0uYV9hdHRyW2tdID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtW2RwY1tpXV0uYV9hdHRyW2tdID0gdFtjXS5hX2F0dHJba107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0ZWxzZSBpZiAoayA9PT0gJ2hyZWYnICYmIG1bZHBjW2ldXS5hX2F0dHJba10gPT09ICcjJykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1bZHBjW2ldXS5hX2F0dHJbJ2hyZWYnXSA9IHRbY10uYV9hdHRyWydocmVmJ107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0ZWxzZSBpZiAoayA9PT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1bZHBjW2ldXS5hX2F0dHJbJ2NsYXNzJ10gPSB0W2NdLmFfYXR0clsnY2xhc3MnXSArICcgJyArIG1bZHBjW2ldXS5hX2F0dHJbJ2NsYXNzJ107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1bJC5qc3RyZWUucm9vdF0udHlwZSA9ICQuanN0cmVlLnJvb3Q7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKTtcblx0XHRcdHBhcmVudC5iaW5kLmNhbGwodGhpcyk7XG5cdFx0fTtcblx0XHR0aGlzLmdldF9qc29uID0gZnVuY3Rpb24gKG9iaiwgb3B0aW9ucywgZmxhdCkge1xuXHRcdFx0dmFyIGksIGosXG5cdFx0XHRcdG0gPSB0aGlzLl9tb2RlbC5kYXRhLFxuXHRcdFx0XHRvcHQgPSBvcHRpb25zID8gJC5leHRlbmQodHJ1ZSwge30sIG9wdGlvbnMsIHtub19pZDpmYWxzZX0pIDoge30sXG5cdFx0XHRcdHRtcCA9IHBhcmVudC5nZXRfanNvbi5jYWxsKHRoaXMsIG9iaiwgb3B0LCBmbGF0KTtcblx0XHRcdGlmKHRtcCA9PT0gZmFsc2UpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheSh0bXApKSB7XG5cdFx0XHRcdGZvcihpID0gMCwgaiA9IHRtcC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHR0bXBbaV0udHlwZSA9IHRtcFtpXS5pZCAmJiBtW3RtcFtpXS5pZF0gJiYgbVt0bXBbaV0uaWRdLnR5cGUgPyBtW3RtcFtpXS5pZF0udHlwZSA6IFwiZGVmYXVsdFwiO1xuXHRcdFx0XHRcdGlmKG9wdGlvbnMgJiYgb3B0aW9ucy5ub19pZCkge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIHRtcFtpXS5pZDtcblx0XHRcdFx0XHRcdGlmKHRtcFtpXS5saV9hdHRyICYmIHRtcFtpXS5saV9hdHRyLmlkKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSB0bXBbaV0ubGlfYXR0ci5pZDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmKHRtcFtpXS5hX2F0dHIgJiYgdG1wW2ldLmFfYXR0ci5pZCkge1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgdG1wW2ldLmFfYXR0ci5pZDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHR0bXAudHlwZSA9IHRtcC5pZCAmJiBtW3RtcC5pZF0gJiYgbVt0bXAuaWRdLnR5cGUgPyBtW3RtcC5pZF0udHlwZSA6IFwiZGVmYXVsdFwiO1xuXHRcdFx0XHRpZihvcHRpb25zICYmIG9wdGlvbnMubm9faWQpIHtcblx0XHRcdFx0XHR0bXAgPSB0aGlzLl9kZWxldGVfaWRzKHRtcCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0bXA7XG5cdFx0fTtcblx0XHR0aGlzLl9kZWxldGVfaWRzID0gZnVuY3Rpb24gKHRtcCkge1xuXHRcdFx0aWYoJC52YWthdGEuaXNfYXJyYXkodG1wKSkge1xuXHRcdFx0XHRmb3IodmFyIGkgPSAwLCBqID0gdG1wLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuXHRcdFx0XHRcdHRtcFtpXSA9IHRoaXMuX2RlbGV0ZV9pZHModG1wW2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0fVxuXHRcdFx0ZGVsZXRlIHRtcC5pZDtcblx0XHRcdGlmKHRtcC5saV9hdHRyICYmIHRtcC5saV9hdHRyLmlkKSB7XG5cdFx0XHRcdGRlbGV0ZSB0bXAubGlfYXR0ci5pZDtcblx0XHRcdH1cblx0XHRcdGlmKHRtcC5hX2F0dHIgJiYgdG1wLmFfYXR0ci5pZCkge1xuXHRcdFx0XHRkZWxldGUgdG1wLmFfYXR0ci5pZDtcblx0XHRcdH1cblx0XHRcdGlmKHRtcC5jaGlsZHJlbiAmJiAkLnZha2F0YS5pc19hcnJheSh0bXAuY2hpbGRyZW4pKSB7XG5cdFx0XHRcdHRtcC5jaGlsZHJlbiA9IHRoaXMuX2RlbGV0ZV9pZHModG1wLmNoaWxkcmVuKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0bXA7XG5cdFx0fTtcblx0XHR0aGlzLmNoZWNrID0gZnVuY3Rpb24gKGNoaywgb2JqLCBwYXIsIHBvcywgbW9yZSkge1xuXHRcdFx0aWYocGFyZW50LmNoZWNrLmNhbGwodGhpcywgY2hrLCBvYmosIHBhciwgcG9zLCBtb3JlKSA9PT0gZmFsc2UpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRvYmogPSBvYmogJiYgb2JqLmlkID8gb2JqIDogdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cGFyID0gcGFyICYmIHBhci5pZCA/IHBhciA6IHRoaXMuZ2V0X25vZGUocGFyKTtcblx0XHRcdHZhciBtID0gb2JqICYmIG9iai5pZCA/IChtb3JlICYmIG1vcmUub3JpZ2luID8gbW9yZS5vcmlnaW4gOiAkLmpzdHJlZS5yZWZlcmVuY2Uob2JqLmlkKSkgOiBudWxsLCB0bXAsIGQsIGksIGo7XG5cdFx0XHRtID0gbSAmJiBtLl9tb2RlbCAmJiBtLl9tb2RlbC5kYXRhID8gbS5fbW9kZWwuZGF0YSA6IG51bGw7XG5cdFx0XHRzd2l0Y2goY2hrKSB7XG5cdFx0XHRcdGNhc2UgXCJjcmVhdGVfbm9kZVwiOlxuXHRcdFx0XHRjYXNlIFwibW92ZV9ub2RlXCI6XG5cdFx0XHRcdGNhc2UgXCJjb3B5X25vZGVcIjpcblx0XHRcdFx0XHRpZihjaGsgIT09ICdtb3ZlX25vZGUnIHx8ICQuaW5BcnJheShvYmouaWQsIHBhci5jaGlsZHJlbikgPT09IC0xKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSB0aGlzLmdldF9ydWxlcyhwYXIpO1xuXHRcdFx0XHRcdFx0aWYodG1wLm1heF9jaGlsZHJlbiAhPT0gdW5kZWZpbmVkICYmIHRtcC5tYXhfY2hpbGRyZW4gIT09IC0xICYmIHRtcC5tYXhfY2hpbGRyZW4gPT09IHBhci5jaGlsZHJlbi5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IgPSB7ICdlcnJvcicgOiAnY2hlY2snLCAncGx1Z2luJyA6ICd0eXBlcycsICdpZCcgOiAndHlwZXNfMDEnLCAncmVhc29uJyA6ICdtYXhfY2hpbGRyZW4gcHJldmVudHMgZnVuY3Rpb246ICcgKyBjaGssICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2NoaycgOiBjaGssICdwb3MnIDogcG9zLCAnb2JqJyA6IG9iaiAmJiBvYmouaWQgPyBvYmouaWQgOiBmYWxzZSwgJ3BhcicgOiBwYXIgJiYgcGFyLmlkID8gcGFyLmlkIDogZmFsc2UgfSkgfTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYodG1wLnZhbGlkX2NoaWxkcmVuICE9PSB1bmRlZmluZWQgJiYgdG1wLnZhbGlkX2NoaWxkcmVuICE9PSAtMSAmJiAkLmluQXJyYXkoKG9iai50eXBlIHx8ICdkZWZhdWx0JyksIHRtcC52YWxpZF9jaGlsZHJlbikgPT09IC0xKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2NoZWNrJywgJ3BsdWdpbicgOiAndHlwZXMnLCAnaWQnIDogJ3R5cGVzXzAyJywgJ3JlYXNvbicgOiAndmFsaWRfY2hpbGRyZW4gcHJldmVudHMgZnVuY3Rpb246ICcgKyBjaGssICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2NoaycgOiBjaGssICdwb3MnIDogcG9zLCAnb2JqJyA6IG9iaiAmJiBvYmouaWQgPyBvYmouaWQgOiBmYWxzZSwgJ3BhcicgOiBwYXIgJiYgcGFyLmlkID8gcGFyLmlkIDogZmFsc2UgfSkgfTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYobSAmJiBvYmouY2hpbGRyZW5fZCAmJiBvYmoucGFyZW50cykge1xuXHRcdFx0XHRcdFx0XHRkID0gMDtcblx0XHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gb2JqLmNoaWxkcmVuX2QubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdFx0ZCA9IE1hdGgubWF4KGQsIG1bb2JqLmNoaWxkcmVuX2RbaV1dLnBhcmVudHMubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRkID0gZCAtIG9iai5wYXJlbnRzLmxlbmd0aCArIDE7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZihkIDw9IDAgfHwgZCA9PT0gdW5kZWZpbmVkKSB7IGQgPSAxOyB9XG5cdFx0XHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0XHRcdGlmKHRtcC5tYXhfZGVwdGggIT09IHVuZGVmaW5lZCAmJiB0bXAubWF4X2RlcHRoICE9PSAtMSAmJiB0bXAubWF4X2RlcHRoIDwgZCkge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2NoZWNrJywgJ3BsdWdpbicgOiAndHlwZXMnLCAnaWQnIDogJ3R5cGVzXzAzJywgJ3JlYXNvbicgOiAnbWF4X2RlcHRoIHByZXZlbnRzIGZ1bmN0aW9uOiAnICsgY2hrLCAnZGF0YScgOiBKU09OLnN0cmluZ2lmeSh7ICdjaGsnIDogY2hrLCAncG9zJyA6IHBvcywgJ29iaicgOiBvYmogJiYgb2JqLmlkID8gb2JqLmlkIDogZmFsc2UsICdwYXInIDogcGFyICYmIHBhci5pZCA/IHBhci5pZCA6IGZhbHNlIH0pIH07XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHBhciA9IHRoaXMuZ2V0X25vZGUocGFyLnBhcmVudCk7XG5cdFx0XHRcdFx0XHRcdHRtcCA9IHRoaXMuZ2V0X3J1bGVzKHBhcik7XG5cdFx0XHRcdFx0XHRcdGQrKztcblx0XHRcdFx0XHRcdH0gd2hpbGUocGFyKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHVzZWQgdG8gcmV0cmlldmUgdGhlIHR5cGUgc2V0dGluZ3Mgb2JqZWN0IGZvciBhIG5vZGVcblx0XHQgKiBAbmFtZSBnZXRfcnVsZXMob2JqKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBmaW5kIHRoZSBydWxlcyBmb3Jcblx0XHQgKiBAcmV0dXJuIHtPYmplY3R9XG5cdFx0ICogQHBsdWdpbiB0eXBlc1xuXHRcdCAqL1xuXHRcdHRoaXMuZ2V0X3J1bGVzID0gZnVuY3Rpb24gKG9iaikge1xuXHRcdFx0b2JqID0gdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0aWYoIW9iaikgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRcdHZhciB0bXAgPSB0aGlzLmdldF90eXBlKG9iaiwgdHJ1ZSk7XG5cdFx0XHRpZih0bXAubWF4X2RlcHRoID09PSB1bmRlZmluZWQpIHsgdG1wLm1heF9kZXB0aCA9IC0xOyB9XG5cdFx0XHRpZih0bXAubWF4X2NoaWxkcmVuID09PSB1bmRlZmluZWQpIHsgdG1wLm1heF9jaGlsZHJlbiA9IC0xOyB9XG5cdFx0XHRpZih0bXAudmFsaWRfY2hpbGRyZW4gPT09IHVuZGVmaW5lZCkgeyB0bXAudmFsaWRfY2hpbGRyZW4gPSAtMTsgfVxuXHRcdFx0cmV0dXJuIHRtcDtcblx0XHR9O1xuXHRcdC8qKlxuXHRcdCAqIHVzZWQgdG8gcmV0cmlldmUgdGhlIHR5cGUgc3RyaW5nIG9yIHNldHRpbmdzIG9iamVjdCBmb3IgYSBub2RlXG5cdFx0ICogQG5hbWUgZ2V0X3R5cGUob2JqIFssIHJ1bGVzXSlcblx0XHQgKiBAcGFyYW0ge21peGVkfSBvYmogdGhlIG5vZGUgdG8gZmluZCB0aGUgcnVsZXMgZm9yXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBydWxlcyBpZiBzZXQgdG8gYHRydWVgIGluc3RlYWQgb2YgYSBzdHJpbmcgdGhlIHNldHRpbmdzIG9iamVjdCB3aWxsIGJlIHJldHVybmVkXG5cdFx0ICogQHJldHVybiB7U3RyaW5nfE9iamVjdH1cblx0XHQgKiBAcGx1Z2luIHR5cGVzXG5cdFx0ICovXG5cdFx0dGhpcy5nZXRfdHlwZSA9IGZ1bmN0aW9uIChvYmosIHJ1bGVzKSB7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRyZXR1cm4gKCFvYmopID8gZmFsc2UgOiAoIHJ1bGVzID8gJC5leHRlbmQoeyAndHlwZScgOiBvYmoudHlwZSB9LCB0aGlzLnNldHRpbmdzLnR5cGVzW29iai50eXBlXSkgOiBvYmoudHlwZSk7XG5cdFx0fTtcblx0XHQvKipcblx0XHQgKiB1c2VkIHRvIGNoYW5nZSBhIG5vZGUncyB0eXBlXG5cdFx0ICogQG5hbWUgc2V0X3R5cGUob2JqLCB0eXBlKVxuXHRcdCAqIEBwYXJhbSB7bWl4ZWR9IG9iaiB0aGUgbm9kZSB0byBjaGFuZ2Vcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSB0aGUgbmV3IHR5cGVcblx0XHQgKiBAcGx1Z2luIHR5cGVzXG5cdFx0ICovXG5cdFx0dGhpcy5zZXRfdHlwZSA9IGZ1bmN0aW9uIChvYmosIHR5cGUpIHtcblx0XHRcdHZhciBtID0gdGhpcy5fbW9kZWwuZGF0YSwgdCwgdDEsIHQyLCBvbGRfdHlwZSwgb2xkX2ljb24sIGssIGQsIGE7XG5cdFx0XHRpZigkLnZha2F0YS5pc19hcnJheShvYmopKSB7XG5cdFx0XHRcdG9iaiA9IG9iai5zbGljZSgpO1xuXHRcdFx0XHRmb3IodDEgPSAwLCB0MiA9IG9iai5sZW5ndGg7IHQxIDwgdDI7IHQxKyspIHtcblx0XHRcdFx0XHR0aGlzLnNldF90eXBlKG9ialt0MV0sIHR5cGUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0dCA9IHRoaXMuc2V0dGluZ3MudHlwZXM7XG5cdFx0XHRvYmogPSB0aGlzLmdldF9ub2RlKG9iaik7XG5cdFx0XHRpZighdFt0eXBlXSB8fCAhb2JqKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdFx0ZCA9IHRoaXMuZ2V0X25vZGUob2JqLCB0cnVlKTtcblx0XHRcdGlmIChkICYmIGQubGVuZ3RoKSB7XG5cdFx0XHRcdGEgPSBkLmNoaWxkcmVuKCcuanN0cmVlLWFuY2hvcicpO1xuXHRcdFx0fVxuXHRcdFx0b2xkX3R5cGUgPSBvYmoudHlwZTtcblx0XHRcdG9sZF9pY29uID0gdGhpcy5nZXRfaWNvbihvYmopO1xuXHRcdFx0b2JqLnR5cGUgPSB0eXBlO1xuXHRcdFx0aWYob2xkX2ljb24gPT09IHRydWUgfHwgIXRbb2xkX3R5cGVdIHx8ICh0W29sZF90eXBlXS5pY29uICE9PSB1bmRlZmluZWQgJiYgb2xkX2ljb24gPT09IHRbb2xkX3R5cGVdLmljb24pKSB7XG5cdFx0XHRcdHRoaXMuc2V0X2ljb24ob2JqLCB0W3R5cGVdLmljb24gIT09IHVuZGVmaW5lZCA/IHRbdHlwZV0uaWNvbiA6IHRydWUpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyByZW1vdmUgb2xkIHR5cGUgcHJvcHNcblx0XHRcdGlmKHRbb2xkX3R5cGVdICYmIHRbb2xkX3R5cGVdLmxpX2F0dHIgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdFtvbGRfdHlwZV0ubGlfYXR0ciA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Zm9yIChrIGluIHRbb2xkX3R5cGVdLmxpX2F0dHIpIHtcblx0XHRcdFx0XHRpZiAodFtvbGRfdHlwZV0ubGlfYXR0ci5oYXNPd25Qcm9wZXJ0eShrKSkge1xuXHRcdFx0XHRcdFx0aWYgKGsgPT09ICdpZCcpIHtcblx0XHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlbHNlIGlmIChrID09PSAnY2xhc3MnKSB7XG5cdFx0XHRcdFx0XHRcdG1bb2JqLmlkXS5saV9hdHRyWydjbGFzcyddID0gKG1bb2JqLmlkXS5saV9hdHRyWydjbGFzcyddIHx8ICcnKS5yZXBsYWNlKHRbb2xkX3R5cGVdLmxpX2F0dHJba10sICcnKTtcblx0XHRcdFx0XHRcdFx0aWYgKGQpIHsgZC5yZW1vdmVDbGFzcyh0W29sZF90eXBlXS5saV9hdHRyW2tdKTsgfVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSBpZiAobVtvYmouaWRdLmxpX2F0dHJba10gPT09IHRbb2xkX3R5cGVdLmxpX2F0dHJba10pIHtcblx0XHRcdFx0XHRcdFx0bVtvYmouaWRdLmxpX2F0dHJba10gPSBudWxsO1xuXHRcdFx0XHRcdFx0XHRpZiAoZCkgeyBkLnJlbW92ZUF0dHIoayk7IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKHRbb2xkX3R5cGVdICYmIHRbb2xkX3R5cGVdLmFfYXR0ciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB0W29sZF90eXBlXS5hX2F0dHIgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdGZvciAoayBpbiB0W29sZF90eXBlXS5hX2F0dHIpIHtcblx0XHRcdFx0XHRpZiAodFtvbGRfdHlwZV0uYV9hdHRyLmhhc093blByb3BlcnR5KGspKSB7XG5cdFx0XHRcdFx0XHRpZiAoayA9PT0gJ2lkJykge1xuXHRcdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2UgaWYgKGsgPT09ICdjbGFzcycpIHtcblx0XHRcdFx0XHRcdFx0bVtvYmouaWRdLmFfYXR0clsnY2xhc3MnXSA9IChtW29iai5pZF0uYV9hdHRyWydjbGFzcyddIHx8ICcnKS5yZXBsYWNlKHRbb2xkX3R5cGVdLmFfYXR0cltrXSwgJycpO1xuXHRcdFx0XHRcdFx0XHRpZiAoYSkgeyBhLnJlbW92ZUNsYXNzKHRbb2xkX3R5cGVdLmFfYXR0cltrXSk7IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2UgaWYgKG1bb2JqLmlkXS5hX2F0dHJba10gPT09IHRbb2xkX3R5cGVdLmFfYXR0cltrXSkge1xuXHRcdFx0XHRcdFx0XHRpZiAoayA9PT0gJ2hyZWYnKSB7XG5cdFx0XHRcdFx0XHRcdFx0bVtvYmouaWRdLmFfYXR0cltrXSA9ICcjJztcblx0XHRcdFx0XHRcdFx0XHRpZiAoYSkgeyBhLmF0dHIoJ2hyZWYnLCAnIycpOyB9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0ZGVsZXRlIG1bb2JqLmlkXS5hX2F0dHJba107XG5cdFx0XHRcdFx0XHRcdFx0aWYgKGEpIHsgYS5yZW1vdmVBdHRyKGspOyB9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gYWRkIG5ldyBwcm9wc1xuXHRcdFx0aWYodFt0eXBlXS5saV9hdHRyICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHRbdHlwZV0ubGlfYXR0ciA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Zm9yIChrIGluIHRbdHlwZV0ubGlfYXR0cikge1xuXHRcdFx0XHRcdGlmICh0W3R5cGVdLmxpX2F0dHIuaGFzT3duUHJvcGVydHkoaykpIHtcblx0XHRcdFx0XHRcdGlmIChrID09PSAnaWQnKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSBpZiAobVtvYmouaWRdLmxpX2F0dHJba10gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHRtW29iai5pZF0ubGlfYXR0cltrXSA9IHRbdHlwZV0ubGlfYXR0cltrXTtcblx0XHRcdFx0XHRcdFx0aWYgKGQpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoayA9PT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZC5hZGRDbGFzcyh0W3R5cGVdLmxpX2F0dHJba10pO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGQuYXR0cihrLCB0W3R5cGVdLmxpX2F0dHJba10pO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSBpZiAoayA9PT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0XHRtW29iai5pZF0ubGlfYXR0clsnY2xhc3MnXSA9IHRbdHlwZV0ubGlfYXR0cltrXSArICcgJyArIG1bb2JqLmlkXS5saV9hdHRyWydjbGFzcyddO1xuXHRcdFx0XHRcdFx0XHRpZiAoZCkgeyBkLmFkZENsYXNzKHRbdHlwZV0ubGlfYXR0cltrXSk7IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmKHRbdHlwZV0uYV9hdHRyICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHRbdHlwZV0uYV9hdHRyID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRmb3IgKGsgaW4gdFt0eXBlXS5hX2F0dHIpIHtcblx0XHRcdFx0XHRpZiAodFt0eXBlXS5hX2F0dHIuaGFzT3duUHJvcGVydHkoaykpIHtcblx0XHRcdFx0XHRcdGlmIChrID09PSAnaWQnKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZWxzZSBpZiAobVtvYmouaWRdLmFfYXR0cltrXSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdG1bb2JqLmlkXS5hX2F0dHJba10gPSB0W3R5cGVdLmFfYXR0cltrXTtcblx0XHRcdFx0XHRcdFx0aWYgKGEpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoayA9PT0gJ2NsYXNzJykge1xuXHRcdFx0XHRcdFx0XHRcdFx0YS5hZGRDbGFzcyh0W3R5cGVdLmFfYXR0cltrXSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0YS5hdHRyKGssIHRbdHlwZV0uYV9hdHRyW2tdKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2UgaWYgKGsgPT09ICdocmVmJyAmJiBtW29iai5pZF0uYV9hdHRyW2tdID09PSAnIycpIHtcblx0XHRcdFx0XHRcdFx0bVtvYmouaWRdLmFfYXR0clsnaHJlZiddID0gdFt0eXBlXS5hX2F0dHJbJ2hyZWYnXTtcblx0XHRcdFx0XHRcdFx0aWYgKGEpIHsgYS5hdHRyKCdocmVmJywgdFt0eXBlXS5hX2F0dHJbJ2hyZWYnXSk7IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2UgaWYgKGsgPT09ICdjbGFzcycpIHtcblx0XHRcdFx0XHRcdFx0bVtvYmouaWRdLmFfYXR0clsnY2xhc3MnXSA9IHRbdHlwZV0uYV9hdHRyWydjbGFzcyddICsgJyAnICsgbVtvYmouaWRdLmFfYXR0clsnY2xhc3MnXTtcblx0XHRcdFx0XHRcdFx0aWYgKGEpIHsgYS5hZGRDbGFzcyh0W3R5cGVdLmFfYXR0cltrXSk7IH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fTtcblx0fTtcblx0Ly8gaW5jbHVkZSB0aGUgdHlwZXMgcGx1Z2luIGJ5IGRlZmF1bHRcblx0Ly8gJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2lucy5wdXNoKFwidHlwZXNcIik7XG5cblxuLyoqXG4gKiAjIyMgVW5pcXVlIHBsdWdpblxuICpcbiAqIEVuZm9yY2VzIHRoYXQgbm8gbm9kZXMgd2l0aCB0aGUgc2FtZSBuYW1lIGNhbiBjb2V4aXN0IGFzIHNpYmxpbmdzLlxuICovXG5cblx0LyoqXG5cdCAqIHN0b3JlcyBhbGwgZGVmYXVsdHMgZm9yIHRoZSB1bmlxdWUgcGx1Z2luXG5cdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnVuaXF1ZVxuXHQgKiBAcGx1Z2luIHVuaXF1ZVxuXHQgKi9cblx0JC5qc3RyZWUuZGVmYXVsdHMudW5pcXVlID0ge1xuXHRcdC8qKlxuXHRcdCAqIEluZGljYXRlcyBpZiB0aGUgY29tcGFyaXNvbiBzaG91bGQgYmUgY2FzZSBzZW5zaXRpdmUuIERlZmF1bHQgaXMgYGZhbHNlYC5cblx0XHQgKiBAbmFtZSAkLmpzdHJlZS5kZWZhdWx0cy51bmlxdWUuY2FzZV9zZW5zaXRpdmVcblx0XHQgKiBAcGx1Z2luIHVuaXF1ZVxuXHRcdCAqL1xuXHRcdGNhc2Vfc2Vuc2l0aXZlIDogZmFsc2UsXG5cdFx0LyoqXG5cdFx0ICogSW5kaWNhdGVzIGlmIHdoaXRlIHNwYWNlIHNob3VsZCBiZSB0cmltbWVkIGJlZm9yZSB0aGUgY29tcGFyaXNvbi4gRGVmYXVsdCBpcyBgZmFsc2VgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnVuaXF1ZS50cmltX3doaXRlc3BhY2Vcblx0XHQgKiBAcGx1Z2luIHVuaXF1ZVxuXHRcdCAqL1xuXHRcdHRyaW1fd2hpdGVzcGFjZSA6IGZhbHNlLFxuXHRcdC8qKlxuXHRcdCAqIEEgY2FsbGJhY2sgZXhlY3V0ZWQgaW4gdGhlIGluc3RhbmNlJ3Mgc2NvcGUgd2hlbiBhIG5ldyBub2RlIGlzIGNyZWF0ZWQgd2l0aCBubyBuYW1lIGFuZCBhIG5vZGUgd2l0aCB0aGUgZGVmYXVsdCBuYW1lIGFscmVhZHkgZXhpc3RzLCB0aGUgdHdvIGFyZ3VtZW50cyBhcmUgdGhlIGNvbmZsaWN0aW5nIG5hbWUgYW5kIHRoZSBjb3VudGVyLiBUaGUgZGVmYXVsdCB3aWxsIHByb2R1Y2UgcmVzdWx0cyBsaWtlIGBOZXcgbm9kZSAoMilgLlxuXHRcdCAqIEBuYW1lICQuanN0cmVlLmRlZmF1bHRzLnVuaXF1ZS5kdXBsaWNhdGVcblx0XHQgKiBAcGx1Z2luIHVuaXF1ZVxuXHRcdCAqL1xuXHRcdGR1cGxpY2F0ZSA6IGZ1bmN0aW9uIChuYW1lLCBjb3VudGVyKSB7XG5cdFx0XHRyZXR1cm4gbmFtZSArICcgKCcgKyBjb3VudGVyICsgJyknO1xuXHRcdH1cblx0fTtcblxuXHQkLmpzdHJlZS5wbHVnaW5zLnVuaXF1ZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBwYXJlbnQpIHtcblx0XHR0aGlzLmNoZWNrID0gZnVuY3Rpb24gKGNoaywgb2JqLCBwYXIsIHBvcywgbW9yZSkge1xuXHRcdFx0aWYocGFyZW50LmNoZWNrLmNhbGwodGhpcywgY2hrLCBvYmosIHBhciwgcG9zLCBtb3JlKSA9PT0gZmFsc2UpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0XHRvYmogPSBvYmogJiYgb2JqLmlkID8gb2JqIDogdGhpcy5nZXRfbm9kZShvYmopO1xuXHRcdFx0cGFyID0gcGFyICYmIHBhci5pZCA/IHBhciA6IHRoaXMuZ2V0X25vZGUocGFyKTtcblx0XHRcdGlmKCFwYXIgfHwgIXBhci5jaGlsZHJlbikgeyByZXR1cm4gdHJ1ZTsgfVxuXHRcdFx0dmFyIG4gPSBjaGsgPT09IFwicmVuYW1lX25vZGVcIiA/IHBvcyA6IG9iai50ZXh0LFxuXHRcdFx0XHRjID0gW10sXG5cdFx0XHRcdHMgPSB0aGlzLnNldHRpbmdzLnVuaXF1ZS5jYXNlX3NlbnNpdGl2ZSxcblx0XHRcdFx0dyA9IHRoaXMuc2V0dGluZ3MudW5pcXVlLnRyaW1fd2hpdGVzcGFjZSxcblx0XHRcdFx0bSA9IHRoaXMuX21vZGVsLmRhdGEsIGksIGosIHQ7XG5cdFx0XHRmb3IoaSA9IDAsIGogPSBwYXIuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdHQgPSBtW3Bhci5jaGlsZHJlbltpXV0udGV4dDtcblx0XHRcdFx0aWYgKCFzKSB7XG5cdFx0XHRcdFx0dCA9IHQudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodykge1xuXHRcdFx0XHRcdHQgPSB0LnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Yy5wdXNoKHQpO1xuXHRcdFx0fVxuXHRcdFx0aWYoIXMpIHsgbiA9IG4udG9Mb3dlckNhc2UoKTsgfVxuXHRcdFx0aWYgKHcpIHsgbiA9IG4ucmVwbGFjZSgvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csICcnKTsgfVxuXHRcdFx0c3dpdGNoKGNoaykge1xuXHRcdFx0XHRjYXNlIFwiZGVsZXRlX25vZGVcIjpcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0Y2FzZSBcInJlbmFtZV9ub2RlXCI6XG5cdFx0XHRcdFx0dCA9IG9iai50ZXh0IHx8ICcnO1xuXHRcdFx0XHRcdGlmICghcykge1xuXHRcdFx0XHRcdFx0dCA9IHQudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHcpIHtcblx0XHRcdFx0XHRcdHQgPSB0LnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGkgPSAoJC5pbkFycmF5KG4sIGMpID09PSAtMSB8fCAob2JqLnRleHQgJiYgdCA9PT0gbikpO1xuXHRcdFx0XHRcdGlmKCFpKSB7XG5cdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvciA9IHsgJ2Vycm9yJyA6ICdjaGVjaycsICdwbHVnaW4nIDogJ3VuaXF1ZScsICdpZCcgOiAndW5pcXVlXzAxJywgJ3JlYXNvbicgOiAnQ2hpbGQgd2l0aCBuYW1lICcgKyBuICsgJyBhbHJlYWR5IGV4aXN0cy4gUHJldmVudGluZzogJyArIGNoaywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoeyAnY2hrJyA6IGNoaywgJ3BvcycgOiBwb3MsICdvYmonIDogb2JqICYmIG9iai5pZCA/IG9iai5pZCA6IGZhbHNlLCAncGFyJyA6IHBhciAmJiBwYXIuaWQgPyBwYXIuaWQgOiBmYWxzZSB9KSB9O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdFx0Y2FzZSBcImNyZWF0ZV9ub2RlXCI6XG5cdFx0XHRcdFx0aSA9ICgkLmluQXJyYXkobiwgYykgPT09IC0xKTtcblx0XHRcdFx0XHRpZighaSkge1xuXHRcdFx0XHRcdFx0dGhpcy5fZGF0YS5jb3JlLmxhc3RfZXJyb3IgPSB7ICdlcnJvcicgOiAnY2hlY2snLCAncGx1Z2luJyA6ICd1bmlxdWUnLCAnaWQnIDogJ3VuaXF1ZV8wNCcsICdyZWFzb24nIDogJ0NoaWxkIHdpdGggbmFtZSAnICsgbiArICcgYWxyZWFkeSBleGlzdHMuIFByZXZlbnRpbmc6ICcgKyBjaGssICdkYXRhJyA6IEpTT04uc3RyaW5naWZ5KHsgJ2NoaycgOiBjaGssICdwb3MnIDogcG9zLCAnb2JqJyA6IG9iaiAmJiBvYmouaWQgPyBvYmouaWQgOiBmYWxzZSwgJ3BhcicgOiBwYXIgJiYgcGFyLmlkID8gcGFyLmlkIDogZmFsc2UgfSkgfTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHRcdGNhc2UgXCJjb3B5X25vZGVcIjpcblx0XHRcdFx0XHRpID0gKCQuaW5BcnJheShuLCBjKSA9PT0gLTEpO1xuXHRcdFx0XHRcdGlmKCFpKSB7XG5cdFx0XHRcdFx0XHR0aGlzLl9kYXRhLmNvcmUubGFzdF9lcnJvciA9IHsgJ2Vycm9yJyA6ICdjaGVjaycsICdwbHVnaW4nIDogJ3VuaXF1ZScsICdpZCcgOiAndW5pcXVlXzAyJywgJ3JlYXNvbicgOiAnQ2hpbGQgd2l0aCBuYW1lICcgKyBuICsgJyBhbHJlYWR5IGV4aXN0cy4gUHJldmVudGluZzogJyArIGNoaywgJ2RhdGEnIDogSlNPTi5zdHJpbmdpZnkoeyAnY2hrJyA6IGNoaywgJ3BvcycgOiBwb3MsICdvYmonIDogb2JqICYmIG9iai5pZCA/IG9iai5pZCA6IGZhbHNlLCAncGFyJyA6IHBhciAmJiBwYXIuaWQgPyBwYXIuaWQgOiBmYWxzZSB9KSB9O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdFx0Y2FzZSBcIm1vdmVfbm9kZVwiOlxuXHRcdFx0XHRcdGkgPSAoIChvYmoucGFyZW50ID09PSBwYXIuaWQgJiYgKCFtb3JlIHx8ICFtb3JlLmlzX211bHRpKSkgfHwgJC5pbkFycmF5KG4sIGMpID09PSAtMSk7XG5cdFx0XHRcdFx0aWYoIWkpIHtcblx0XHRcdFx0XHRcdHRoaXMuX2RhdGEuY29yZS5sYXN0X2Vycm9yID0geyAnZXJyb3InIDogJ2NoZWNrJywgJ3BsdWdpbicgOiAndW5pcXVlJywgJ2lkJyA6ICd1bmlxdWVfMDMnLCAncmVhc29uJyA6ICdDaGlsZCB3aXRoIG5hbWUgJyArIG4gKyAnIGFscmVhZHkgZXhpc3RzLiBQcmV2ZW50aW5nOiAnICsgY2hrLCAnZGF0YScgOiBKU09OLnN0cmluZ2lmeSh7ICdjaGsnIDogY2hrLCAncG9zJyA6IHBvcywgJ29iaicgOiBvYmogJiYgb2JqLmlkID8gb2JqLmlkIDogZmFsc2UsICdwYXInIDogcGFyICYmIHBhci5pZCA/IHBhci5pZCA6IGZhbHNlIH0pIH07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fTtcblx0XHR0aGlzLmNyZWF0ZV9ub2RlID0gZnVuY3Rpb24gKHBhciwgbm9kZSwgcG9zLCBjYWxsYmFjaywgaXNfbG9hZGVkKSB7XG5cdFx0XHRpZighbm9kZSB8fCAodHlwZW9mIG5vZGUgPT09ICdvYmplY3QnICYmIG5vZGUudGV4dCA9PT0gdW5kZWZpbmVkKSkge1xuXHRcdFx0XHRpZihwYXIgPT09IG51bGwpIHtcblx0XHRcdFx0XHRwYXIgPSAkLmpzdHJlZS5yb290O1xuXHRcdFx0XHR9XG5cdFx0XHRcdHBhciA9IHRoaXMuZ2V0X25vZGUocGFyKTtcblx0XHRcdFx0aWYoIXBhcikge1xuXHRcdFx0XHRcdHJldHVybiBwYXJlbnQuY3JlYXRlX25vZGUuY2FsbCh0aGlzLCBwYXIsIG5vZGUsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cG9zID0gcG9zID09PSB1bmRlZmluZWQgPyBcImxhc3RcIiA6IHBvcztcblx0XHRcdFx0aWYoIXBvcy50b1N0cmluZygpLm1hdGNoKC9eKGJlZm9yZXxhZnRlcikkLykgJiYgIWlzX2xvYWRlZCAmJiAhdGhpcy5pc19sb2FkZWQocGFyKSkge1xuXHRcdFx0XHRcdHJldHVybiBwYXJlbnQuY3JlYXRlX25vZGUuY2FsbCh0aGlzLCBwYXIsIG5vZGUsIHBvcywgY2FsbGJhY2ssIGlzX2xvYWRlZCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYoIW5vZGUpIHsgbm9kZSA9IHt9OyB9XG5cdFx0XHRcdHZhciB0bXAsIG4sIGRwYywgaSwgaiwgbSA9IHRoaXMuX21vZGVsLmRhdGEsIHMgPSB0aGlzLnNldHRpbmdzLnVuaXF1ZS5jYXNlX3NlbnNpdGl2ZSwgdyA9IHRoaXMuc2V0dGluZ3MudW5pcXVlLnRyaW1fd2hpdGVzcGFjZSwgY2IgPSB0aGlzLnNldHRpbmdzLnVuaXF1ZS5kdXBsaWNhdGUsIHQ7XG5cdFx0XHRcdG4gPSB0bXAgPSB0aGlzLmdldF9zdHJpbmcoJ05ldyBub2RlJyk7XG5cdFx0XHRcdGRwYyA9IFtdO1xuXHRcdFx0XHRmb3IoaSA9IDAsIGogPSBwYXIuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG5cdFx0XHRcdFx0dCA9IG1bcGFyLmNoaWxkcmVuW2ldXS50ZXh0O1xuXHRcdFx0XHRcdGlmICghcykge1xuXHRcdFx0XHRcdFx0dCA9IHQudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHcpIHtcblx0XHRcdFx0XHRcdHQgPSB0LnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRwYy5wdXNoKHQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGkgPSAxO1xuXHRcdFx0XHR0ID0gbjtcblx0XHRcdFx0aWYgKCFzKSB7XG5cdFx0XHRcdFx0dCA9IHQudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodykge1xuXHRcdFx0XHRcdHQgPSB0LnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0d2hpbGUoJC5pbkFycmF5KHQsIGRwYykgIT09IC0xKSB7XG5cdFx0XHRcdFx0biA9IGNiLmNhbGwodGhpcywgdG1wLCAoKytpKSkudG9TdHJpbmcoKTtcblx0XHRcdFx0XHR0ID0gbjtcblx0XHRcdFx0XHRpZiAoIXMpIHtcblx0XHRcdFx0XHRcdHQgPSB0LnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh3KSB7XG5cdFx0XHRcdFx0XHR0ID0gdC5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRub2RlLnRleHQgPSBuO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBhcmVudC5jcmVhdGVfbm9kZS5jYWxsKHRoaXMsIHBhciwgbm9kZSwgcG9zLCBjYWxsYmFjaywgaXNfbG9hZGVkKTtcblx0XHR9O1xuXHR9O1xuXG5cdC8vIGluY2x1ZGUgdGhlIHVuaXF1ZSBwbHVnaW4gYnkgZGVmYXVsdFxuXHQvLyAkLmpzdHJlZS5kZWZhdWx0cy5wbHVnaW5zLnB1c2goXCJ1bmlxdWVcIik7XG5cblxuLyoqXG4gKiAjIyMgV2hvbGVyb3cgcGx1Z2luXG4gKlxuICogTWFrZXMgZWFjaCBub2RlIGFwcGVhciBibG9jayBsZXZlbC4gTWFraW5nIHNlbGVjdGlvbiBlYXNpZXIuIE1heSBjYXVzZSBzbG93IGRvd24gZm9yIGxhcmdlIHRyZWVzIGluIG9sZCBicm93c2Vycy5cbiAqL1xuXG5cdHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdESVYnKTtcblx0ZGl2LnNldEF0dHJpYnV0ZSgndW5zZWxlY3RhYmxlJywnb24nKTtcblx0ZGl2LnNldEF0dHJpYnV0ZSgncm9sZScsJ3ByZXNlbnRhdGlvbicpO1xuXHRkaXYuY2xhc3NOYW1lID0gJ2pzdHJlZS13aG9sZXJvdyc7XG5cdGRpdi5pbm5lckhUTUwgPSAnJiMxNjA7Jztcblx0JC5qc3RyZWUucGx1Z2lucy53aG9sZXJvdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBwYXJlbnQpIHtcblx0XHR0aGlzLmJpbmQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRwYXJlbnQuYmluZC5jYWxsKHRoaXMpO1xuXG5cdFx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdFx0Lm9uKCdyZWFkeS5qc3RyZWUgc2V0X3N0YXRlLmpzdHJlZScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHRoaXMuaGlkZV9kb3RzKCk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJpbml0LmpzdHJlZSBsb2FkaW5nLmpzdHJlZSByZWFkeS5qc3RyZWVcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0Ly9kaXYuc3R5bGUuaGVpZ2h0ID0gdGhpcy5fZGF0YS5jb3JlLmxpX2hlaWdodCArICdweCc7XG5cdFx0XHRcdFx0XHR0aGlzLmdldF9jb250YWluZXJfdWwoKS5hZGRDbGFzcygnanN0cmVlLXdob2xlcm93LXVsJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJkZXNlbGVjdF9hbGwuanN0cmVlXCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmVsZW1lbnQuZmluZCgnLmpzdHJlZS13aG9sZXJvdy1jbGlja2VkJykucmVtb3ZlQ2xhc3MoJ2pzdHJlZS13aG9sZXJvdy1jbGlja2VkJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJjaGFuZ2VkLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50LmZpbmQoJy5qc3RyZWUtd2hvbGVyb3ctY2xpY2tlZCcpLnJlbW92ZUNsYXNzKCdqc3RyZWUtd2hvbGVyb3ctY2xpY2tlZCcpO1xuXHRcdFx0XHRcdFx0dmFyIHRtcCA9IGZhbHNlLCBpLCBqO1xuXHRcdFx0XHRcdFx0Zm9yKGkgPSAwLCBqID0gZGF0YS5zZWxlY3RlZC5sZW5ndGg7IGkgPCBqOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0dG1wID0gdGhpcy5nZXRfbm9kZShkYXRhLnNlbGVjdGVkW2ldLCB0cnVlKTtcblx0XHRcdFx0XHRcdFx0aWYodG1wICYmIHRtcC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHR0bXAuY2hpbGRyZW4oJy5qc3RyZWUtd2hvbGVyb3cnKS5hZGRDbGFzcygnanN0cmVlLXdob2xlcm93LWNsaWNrZWQnKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSlcblx0XHRcdFx0Lm9uKFwib3Blbl9ub2RlLmpzdHJlZVwiLCBmdW5jdGlvbiAoZSwgZGF0YSkge1xuXHRcdFx0XHRcdFx0dGhpcy5nZXRfbm9kZShkYXRhLm5vZGUsIHRydWUpLmZpbmQoJy5qc3RyZWUtY2xpY2tlZCcpLnBhcmVudCgpLmNoaWxkcmVuKCcuanN0cmVlLXdob2xlcm93JykuYWRkQ2xhc3MoJ2pzdHJlZS13aG9sZXJvdy1jbGlja2VkJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJob3Zlcl9ub2RlLmpzdHJlZSBkZWhvdmVyX25vZGUuanN0cmVlXCIsIGZ1bmN0aW9uIChlLCBkYXRhKSB7XG5cdFx0XHRcdFx0XHRpZihlLnR5cGUgPT09IFwiaG92ZXJfbm9kZVwiICYmIHRoaXMuaXNfZGlzYWJsZWQoZGF0YS5ub2RlKSkgeyByZXR1cm47IH1cblx0XHRcdFx0XHRcdHRoaXMuZ2V0X25vZGUoZGF0YS5ub2RlLCB0cnVlKS5jaGlsZHJlbignLmpzdHJlZS13aG9sZXJvdycpW2UudHlwZSA9PT0gXCJob3Zlcl9ub2RlXCI/XCJhZGRDbGFzc1wiOlwicmVtb3ZlQ2xhc3NcIl0oJ2pzdHJlZS13aG9sZXJvdy1ob3ZlcmVkJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJjb250ZXh0bWVudS5qc3RyZWVcIiwgXCIuanN0cmVlLXdob2xlcm93XCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRpZiAodGhpcy5fZGF0YS5jb250ZXh0bWVudSkge1xuXHRcdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdHZhciB0bXAgPSAkLkV2ZW50KCdjb250ZXh0bWVudScsIHsgbWV0YUtleSA6IGUubWV0YUtleSwgY3RybEtleSA6IGUuY3RybEtleSwgYWx0S2V5IDogZS5hbHRLZXksIHNoaWZ0S2V5IDogZS5zaGlmdEtleSwgcGFnZVggOiBlLnBhZ2VYLCBwYWdlWSA6IGUucGFnZVkgfSk7XG5cdFx0XHRcdFx0XHRcdCQoZS5jdXJyZW50VGFyZ2V0KS5jbG9zZXN0KFwiLmpzdHJlZS1ub2RlXCIpLmNoaWxkcmVuKFwiLmpzdHJlZS1hbmNob3JcIikuZmlyc3QoKS50cmlnZ2VyKHRtcCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQvKiFcblx0XHRcdFx0Lm9uKFwibW91c2Vkb3duLmpzdHJlZSB0b3VjaHN0YXJ0LmpzdHJlZVwiLCBcIi5qc3RyZWUtd2hvbGVyb3dcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGlmKGUudGFyZ2V0ID09PSBlLmN1cnJlbnRUYXJnZXQpIHtcblx0XHRcdFx0XHRcdFx0dmFyIGEgPSAkKGUuY3VycmVudFRhcmdldCkuY2xvc2VzdChcIi5qc3RyZWUtbm9kZVwiKS5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpO1xuXHRcdFx0XHRcdFx0XHRlLnRhcmdldCA9IGFbMF07XG5cdFx0XHRcdFx0XHRcdGEudHJpZ2dlcihlKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0XHQqL1xuXHRcdFx0XHQub24oXCJjbGljay5qc3RyZWVcIiwgXCIuanN0cmVlLXdob2xlcm93XCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0dmFyIHRtcCA9ICQuRXZlbnQoJ2NsaWNrJywgeyBtZXRhS2V5IDogZS5tZXRhS2V5LCBjdHJsS2V5IDogZS5jdHJsS2V5LCBhbHRLZXkgOiBlLmFsdEtleSwgc2hpZnRLZXkgOiBlLnNoaWZ0S2V5IH0pO1xuXHRcdFx0XHRcdFx0JChlLmN1cnJlbnRUYXJnZXQpLmNsb3Nlc3QoXCIuanN0cmVlLW5vZGVcIikuY2hpbGRyZW4oXCIuanN0cmVlLWFuY2hvclwiKS5maXJzdCgpLnRyaWdnZXIodG1wKS50cmlnZ2VyKCdmb2N1cycpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdC5vbihcImRibGNsaWNrLmpzdHJlZVwiLCBcIi5qc3RyZWUtd2hvbGVyb3dcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR2YXIgdG1wID0gJC5FdmVudCgnZGJsY2xpY2snLCB7IG1ldGFLZXkgOiBlLm1ldGFLZXksIGN0cmxLZXkgOiBlLmN0cmxLZXksIGFsdEtleSA6IGUuYWx0S2V5LCBzaGlmdEtleSA6IGUuc2hpZnRLZXkgfSk7XG5cdFx0XHRcdFx0XHQkKGUuY3VycmVudFRhcmdldCkuY2xvc2VzdChcIi5qc3RyZWUtbm9kZVwiKS5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpLmZpcnN0KCkudHJpZ2dlcih0bXApLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0Lm9uKFwiY2xpY2suanN0cmVlXCIsIFwiLmpzdHJlZS1sZWFmID4gLmpzdHJlZS1vY2xcIiwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR2YXIgdG1wID0gJC5FdmVudCgnY2xpY2snLCB7IG1ldGFLZXkgOiBlLm1ldGFLZXksIGN0cmxLZXkgOiBlLmN0cmxLZXksIGFsdEtleSA6IGUuYWx0S2V5LCBzaGlmdEtleSA6IGUuc2hpZnRLZXkgfSk7XG5cdFx0XHRcdFx0XHQkKGUuY3VycmVudFRhcmdldCkuY2xvc2VzdChcIi5qc3RyZWUtbm9kZVwiKS5jaGlsZHJlbihcIi5qc3RyZWUtYW5jaG9yXCIpLmZpcnN0KCkudHJpZ2dlcih0bXApLnRyaWdnZXIoJ2ZvY3VzJyk7XG5cdFx0XHRcdFx0fS5iaW5kKHRoaXMpKVxuXHRcdFx0XHQub24oXCJtb3VzZW92ZXIuanN0cmVlXCIsIFwiLmpzdHJlZS13aG9sZXJvdywgLmpzdHJlZS1pY29uXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0aWYoIXRoaXMuaXNfZGlzYWJsZWQoZS5jdXJyZW50VGFyZ2V0KSkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmhvdmVyX25vZGUoZS5jdXJyZW50VGFyZ2V0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9LmJpbmQodGhpcykpXG5cdFx0XHRcdC5vbihcIm1vdXNlbGVhdmUuanN0cmVlXCIsIFwiLmpzdHJlZS1ub2RlXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmRlaG92ZXJfbm9kZShlLmN1cnJlbnRUYXJnZXQpO1xuXHRcdFx0XHRcdH0uYmluZCh0aGlzKSk7XG5cdFx0fTtcblx0XHR0aGlzLnRlYXJkb3duID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYodGhpcy5zZXR0aW5ncy53aG9sZXJvdykge1xuXHRcdFx0XHR0aGlzLmVsZW1lbnQuZmluZChcIi5qc3RyZWUtd2hvbGVyb3dcIikucmVtb3ZlKCk7XG5cdFx0XHR9XG5cdFx0XHRwYXJlbnQudGVhcmRvd24uY2FsbCh0aGlzKTtcblx0XHR9O1xuXHRcdHRoaXMucmVkcmF3X25vZGUgPSBmdW5jdGlvbihvYmosIGRlZXAsIGNhbGxiYWNrLCBmb3JjZV9yZW5kZXIpIHtcblx0XHRcdG9iaiA9IHBhcmVudC5yZWRyYXdfbm9kZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXHRcdFx0aWYob2JqKSB7XG5cdFx0XHRcdHZhciB0bXAgPSBkaXYuY2xvbmVOb2RlKHRydWUpO1xuXHRcdFx0XHQvL3RtcC5zdHlsZS5oZWlnaHQgPSB0aGlzLl9kYXRhLmNvcmUubGlfaGVpZ2h0ICsgJ3B4Jztcblx0XHRcdFx0aWYoJC5pbkFycmF5KG9iai5pZCwgdGhpcy5fZGF0YS5jb3JlLnNlbGVjdGVkKSAhPT0gLTEpIHsgdG1wLmNsYXNzTmFtZSArPSAnIGpzdHJlZS13aG9sZXJvdy1jbGlja2VkJzsgfVxuXHRcdFx0XHRpZih0aGlzLl9kYXRhLmNvcmUuZm9jdXNlZCAmJiB0aGlzLl9kYXRhLmNvcmUuZm9jdXNlZCA9PT0gb2JqLmlkKSB7IHRtcC5jbGFzc05hbWUgKz0gJyBqc3RyZWUtd2hvbGVyb3ctaG92ZXJlZCc7IH1cblx0XHRcdFx0b2JqLmluc2VydEJlZm9yZSh0bXAsIG9iai5jaGlsZE5vZGVzWzBdKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBvYmo7XG5cdFx0fTtcblx0fTtcblx0Ly8gaW5jbHVkZSB0aGUgd2hvbGVyb3cgcGx1Z2luIGJ5IGRlZmF1bHRcblx0Ly8gJC5qc3RyZWUuZGVmYXVsdHMucGx1Z2lucy5wdXNoKFwid2hvbGVyb3dcIik7XG5cdGlmKHdpbmRvdy5jdXN0b21FbGVtZW50cyAmJiBPYmplY3QgJiYgT2JqZWN0LmNyZWF0ZSkge1xuXHRcdHZhciBwcm90byA9IE9iamVjdC5jcmVhdGUoSFRNTEVsZW1lbnQucHJvdG90eXBlKTtcblx0XHRwcm90by5jcmVhdGVkQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgYyA9IHsgY29yZSA6IHt9LCBwbHVnaW5zIDogW10gfSwgaTtcblx0XHRcdGZvcihpIGluICQuanN0cmVlLnBsdWdpbnMpIHtcblx0XHRcdFx0aWYoJC5qc3RyZWUucGx1Z2lucy5oYXNPd25Qcm9wZXJ0eShpKSAmJiB0aGlzLmF0dHJpYnV0ZXNbaV0pIHtcblx0XHRcdFx0XHRjLnBsdWdpbnMucHVzaChpKTtcblx0XHRcdFx0XHRpZih0aGlzLmdldEF0dHJpYnV0ZShpKSAmJiBKU09OLnBhcnNlKHRoaXMuZ2V0QXR0cmlidXRlKGkpKSkge1xuXHRcdFx0XHRcdFx0Y1tpXSA9IEpTT04ucGFyc2UodGhpcy5nZXRBdHRyaWJ1dGUoaSkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Zm9yKGkgaW4gJC5qc3RyZWUuZGVmYXVsdHMuY29yZSkge1xuXHRcdFx0XHRpZigkLmpzdHJlZS5kZWZhdWx0cy5jb3JlLmhhc093blByb3BlcnR5KGkpICYmIHRoaXMuYXR0cmlidXRlc1tpXSkge1xuXHRcdFx0XHRcdGMuY29yZVtpXSA9IEpTT04ucGFyc2UodGhpcy5nZXRBdHRyaWJ1dGUoaSkpIHx8IHRoaXMuZ2V0QXR0cmlidXRlKGkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQkKHRoaXMpLmpzdHJlZShjKTtcblx0XHR9O1xuXHRcdC8vIHByb3RvLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayA9IGZ1bmN0aW9uIChuYW1lLCBwcmV2aW91cywgdmFsdWUpIHsgfTtcblx0XHR0cnkge1xuXHRcdFx0d2luZG93LmN1c3RvbUVsZW1lbnRzLmRlZmluZShcInZha2F0YS1qc3RyZWVcIiwgZnVuY3Rpb24oKSB7fSwgeyBwcm90b3R5cGU6IHByb3RvIH0pO1xuXHRcdH0gY2F0Y2ggKGlnbm9yZSkgeyB9XG5cdH1cblxufSkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/jstree/dist/jstree.js\n"); - -/***/ }), - -/***/ "jquery": -/*!*************************!*\ - !*** external "jQuery" ***! - \*************************/ -/***/ (function(module) { - -"use strict"; -module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__; - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ !function() { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function() { return module['default']; } : -/******/ function() { return module; }; -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ }(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ !function() { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = function(exports, definition) { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ }(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ !function() { -/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -/******/ }(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ !function() { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ }(); -/******/ -/************************************************************************/ -/******/ -/******/ // startup -/******/ // Load entry module and return exports -/******/ // This entry module can't be inlined because the eval-source-map devtool is used. -/******/ var __webpack_exports__ = __webpack_require__("./libs/jstree/jstree.js"); -/******/ -/******/ return __webpack_exports__; -/******/ })() -; -}); \ No newline at end of file + + /** + * ### jsTree core functionality + */ + + // internal variables + var instance_counter = 0, + ccp_node = false, + ccp_mode = false, + ccp_inst = false, + themes_loaded = [], + src = $('script:last').attr('src'), + document = window.document; // local variable is always faster to access then a global + + /** + * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances. + * @name $.jstree + */ + $.jstree = { + /** + * specifies the jstree version in use + * @name $.jstree.version + */ + version : '3.3.7', + /** + * holds all the default options used when creating new instances + * @name $.jstree.defaults + */ + defaults : { + /** + * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]` + * @name $.jstree.defaults.plugins + */ + plugins : [] + }, + /** + * stores all loaded jstree plugins (used internally) + * @name $.jstree.plugins + */ + plugins : {}, + path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '', + idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g, + root : '#' + }; + + /** + * creates a jstree instance + * @name $.jstree.create(el [, options]) + * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector + * @param {Object} options options for this instance (extends `$.jstree.defaults`) + * @return {jsTree} the new instance + */ + $.jstree.create = function (el, options) { + var tmp = new $.jstree.core(++instance_counter), + opt = options; + options = $.extend(true, {}, $.jstree.defaults, options); + if(opt && opt.plugins) { + options.plugins = opt.plugins; + } + $.each(options.plugins, function (i, k) { + if(i !== 'core') { + tmp = tmp.plugin(k, options[k]); + } + }); + $(el).data('jstree', tmp); + tmp.init(el, options); + return tmp; + }; + /** + * remove all traces of jstree from the DOM and destroy all instances + * @name $.jstree.destroy() + */ + $.jstree.destroy = function () { + $('.jstree:jstree').jstree('destroy'); + $(document).off('.jstree'); + }; + /** + * the jstree class constructor, used only internally + * @private + * @name $.jstree.core(id) + * @param {Number} id this instance's index + */ + $.jstree.core = function (id) { + this._id = id; + this._cnt = 0; + this._wrk = null; + this._data = { + core : { + themes : { + name : false, + dots : false, + icons : false, + ellipsis : false + }, + selected : [], + last_error : {}, + working : false, + worker_queue : [], + focused : null + } + }; + }; + /** + * get a reference to an existing instance + * + * __Examples__ + * + * // provided a container with an ID of "tree", and a nested node with an ID of "branch" + * // all of there will return the same instance + * $.jstree.reference('tree'); + * $.jstree.reference('#tree'); + * $.jstree.reference($('#tree')); + * $.jstree.reference(document.getElementByID('tree')); + * $.jstree.reference('branch'); + * $.jstree.reference('#branch'); + * $.jstree.reference($('#branch')); + * $.jstree.reference(document.getElementByID('branch')); + * + * @name $.jstree.reference(needle) + * @param {DOMElement|jQuery|String} needle + * @return {jsTree|null} the instance or `null` if not found + */ + $.jstree.reference = function (needle) { + var tmp = null, + obj = null; + if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; } + + if(!obj || !obj.length) { + try { obj = $(needle); } catch (ignore) { } + } + if(!obj || !obj.length) { + try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { } + } + if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) { + tmp = obj; + } + else { + $('.jstree').each(function () { + var inst = $(this).data('jstree'); + if(inst && inst._model.data[needle]) { + tmp = inst; + return false; + } + }); + } + return tmp; + }; + /** + * Create an instance, get an instance or invoke a command on a instance. + * + * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken). + * + * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function). + * + * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`). + * + * In any other case - nothing is returned and chaining is not broken. + * + * __Examples__ + * + * $('#tree1').jstree(); // creates an instance + * $('#tree2').jstree({ plugins : [] }); // create an instance with some options + * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments + * $('#tree2').jstree(); // get an existing instance (or create an instance) + * $('#tree2').jstree(true); // get an existing instance (will not create new instance) + * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method) + * + * @name $().jstree([arg]) + * @param {String|Object} arg + * @return {Mixed} + */ + $.fn.jstree = function (arg) { + // check for string argument + var is_method = (typeof arg === 'string'), + args = Array.prototype.slice.call(arguments, 1), + result = null; + if(arg === true && !this.length) { return false; } + this.each(function () { + // get the instance (if there is one) and method (if it exists) + var instance = $.jstree.reference(this), + method = is_method && instance ? instance[arg] : null; + // if calling a method, and method is available - execute on the instance + result = is_method && method ? + method.apply(instance, args) : + null; + // if there is no instance and no method is being called - create one + if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) { + $.jstree.create(this, arg); + } + // if there is an instance and no method is called - return the instance + if( (instance && !is_method) || arg === true ) { + result = instance || false; + } + // if there was a method call which returned a result - break and return the value + if(result !== null && result !== undefined) { + return false; + } + }); + // if there was a method call with a valid return value - return that, otherwise continue the chain + return result !== null && result !== undefined ? + result : this; + }; + /** + * used to find elements containing an instance + * + * __Examples__ + * + * $('div:jstree').each(function () { + * $(this).jstree('destroy'); + * }); + * + * @name $(':jstree') + * @return {jQuery} + */ + $.expr.pseudos.jstree = $.expr.createPseudo(function(search) { + return function(a) { + return $(a).hasClass('jstree') && + $(a).data('jstree') !== undefined; + }; + }); + + /** + * stores all defaults for the core + * @name $.jstree.defaults.core + */ + $.jstree.defaults.core = { + /** + * data configuration + * + * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items). + * + * You can also pass in a HTML string or a JSON array here. + * + * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree. + * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used. + * + * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result. + * + * __Examples__ + * + * // AJAX + * $('#tree').jstree({ + * 'core' : { + * 'data' : { + * 'url' : '/get/children/', + * 'data' : function (node) { + * return { 'id' : node.id }; + * } + * } + * }); + * + * // direct data + * $('#tree').jstree({ + * 'core' : { + * 'data' : [ + * 'Simple root node', + * { + * 'id' : 'node_2', + * 'text' : 'Root node with options', + * 'state' : { 'opened' : true, 'selected' : true }, + * 'children' : [ { 'text' : 'Child 1' }, 'Child 2'] + * } + * ] + * } + * }); + * + * // function + * $('#tree').jstree({ + * 'core' : { + * 'data' : function (obj, callback) { + * callback.call(this, ['Root 1', 'Root 2']); + * } + * }); + * + * @name $.jstree.defaults.core.data + */ + data : false, + /** + * configure the various strings used throughout the tree + * + * You can use an object where the key is the string you need to replace and the value is your replacement. + * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement. + * If left as `false` no replacement is made. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'strings' : { + * 'Loading ...' : 'Please wait ...' + * } + * } + * }); + * + * @name $.jstree.defaults.core.strings + */ + strings : false, + /** + * determines what happens when a user tries to modify the structure of the tree + * If left as `false` all operations like create, rename, delete, move or copy are prevented. + * You can set this to `true` to allow all interactions or use a function to have better control. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'check_callback' : function (operation, node, node_parent, node_position, more) { + * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node', 'copy_node' or 'edit' + * // in case of 'rename_node' node_position is filled with the new node name + * return operation === 'rename_node' ? true : false; + * } + * } + * }); + * + * @name $.jstree.defaults.core.check_callback + */ + check_callback : false, + /** + * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc) + * @name $.jstree.defaults.core.error + */ + error : $.noop, + /** + * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`) + * @name $.jstree.defaults.core.animation + */ + animation : 200, + /** + * a boolean indicating if multiple nodes can be selected + * @name $.jstree.defaults.core.multiple + */ + multiple : true, + /** + * theme configuration object + * @name $.jstree.defaults.core.themes + */ + themes : { + /** + * the name of the theme to use (if left as `false` the default theme is used) + * @name $.jstree.defaults.core.themes.name + */ + name : false, + /** + * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme. + * @name $.jstree.defaults.core.themes.url + */ + url : false, + /** + * the location of all jstree themes - only used if `url` is set to `true` + * @name $.jstree.defaults.core.themes.dir + */ + dir : false, + /** + * a boolean indicating if connecting dots are shown + * @name $.jstree.defaults.core.themes.dots + */ + dots : true, + /** + * a boolean indicating if node icons are shown + * @name $.jstree.defaults.core.themes.icons + */ + icons : true, + /** + * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container + * @name $.jstree.defaults.core.themes.ellipsis + */ + ellipsis : false, + /** + * a boolean indicating if the tree background is striped + * @name $.jstree.defaults.core.themes.stripes + */ + stripes : false, + /** + * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants) + * @name $.jstree.defaults.core.themes.variant + */ + variant : false, + /** + * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`. + * @name $.jstree.defaults.core.themes.responsive + */ + responsive : false + }, + /** + * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user) + * @name $.jstree.defaults.core.expand_selected_onload + */ + expand_selected_onload : true, + /** + * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true` + * @name $.jstree.defaults.core.worker + */ + worker : true, + /** + * Force node text to plain text (and escape HTML). Defaults to `false` + * @name $.jstree.defaults.core.force_text + */ + force_text : false, + /** + * Should the node be toggled if the text is double clicked. Defaults to `true` + * @name $.jstree.defaults.core.dblclick_toggle + */ + dblclick_toggle : true, + /** + * Should the loaded nodes be part of the state. Defaults to `false` + * @name $.jstree.defaults.core.loaded_state + */ + loaded_state : false, + /** + * Should the last active node be focused when the tree container is blurred and the focused again. This helps working with screen readers. Defaults to `true` + * @name $.jstree.defaults.core.restore_focus + */ + restore_focus : true, + /** + * Default keyboard shortcuts (an object where each key is the button name or combo - like 'enter', 'ctrl-space', 'p', etc and the value is the function to execute in the instance's scope) + * @name $.jstree.defaults.core.keyboard + */ + keyboard : { + 'ctrl-space': function (e) { + // aria defines space only with Ctrl + e.type = "click"; + $(e.currentTarget).trigger(e); + }, + 'enter': function (e) { + // enter + e.type = "click"; + $(e.currentTarget).trigger(e); + }, + 'left': function (e) { + // left + e.preventDefault(); + if(this.is_open(e.currentTarget)) { + this.close_node(e.currentTarget); + } + else { + var o = this.get_parent(e.currentTarget); + if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); } + } + }, + 'up': function (e) { + // up + e.preventDefault(); + var o = this.get_prev_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + }, + 'right': function (e) { + // right + e.preventDefault(); + if(this.is_closed(e.currentTarget)) { + this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); }); + } + else if (this.is_open(e.currentTarget)) { + var o = this.get_node(e.currentTarget, true).children('.jstree-children')[0]; + if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); } + } + }, + 'down': function (e) { + // down + e.preventDefault(); + var o = this.get_next_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + }, + '*': function (e) { + // aria defines * on numpad as open_all - not very common + this.open_all(); + }, + 'home': function (e) { + // home + e.preventDefault(); + var o = this._firstChild(this.get_container_ul()[0]); + if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); } + }, + 'end': function (e) { + // end + e.preventDefault(); + this.element.find('.jstree-anchor').filter(':visible').last().focus(); + }, + 'f2': function (e) { + // f2 - safe to include - if check_callback is false it will fail + e.preventDefault(); + this.edit(e.currentTarget); + } + } + }; + $.jstree.core.prototype = { + /** + * used to decorate an instance with a plugin. Used internally. + * @private + * @name plugin(deco [, opts]) + * @param {String} deco the plugin to decorate with + * @param {Object} opts options for the plugin + * @return {jsTree} + */ + plugin : function (deco, opts) { + var Child = $.jstree.plugins[deco]; + if(Child) { + this._data[deco] = {}; + Child.prototype = this; + return new Child(opts, this); + } + return this; + }, + /** + * initialize the instance. Used internally. + * @private + * @name init(el, optons) + * @param {DOMElement|jQuery|String} el the element we are transforming + * @param {Object} options options for this instance + * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree + */ + init : function (el, options) { + this._model = { + data : {}, + changed : [], + force_full_redraw : false, + redraw_timeout : false, + default_state : { + loaded : true, + opened : false, + selected : false, + disabled : false + } + }; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + + this.element = $(el).addClass('jstree jstree-' + this._id); + this.settings = options; + + this._data.core.ready = false; + this._data.core.loaded = false; + this._data.core.rtl = (this.element.css("direction") === "rtl"); + this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl"); + this.element.attr('role','tree'); + if(this.settings.core.multiple) { + this.element.attr('aria-multiselectable', true); + } + if(!this.element.attr('tabindex')) { + this.element.attr('tabindex','0'); + } + + this.bind(); + /** + * triggered after all events are bound + * @event + * @name init.jstree + */ + this.trigger("init"); + + this._data.core.original_container_html = this.element.find(" > ul > li").clone(true); + this._data.core.original_container_html + .find("li").addBack() + .contents().filter(function() { + return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); + }) + .remove(); + this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><"+"a class='jstree-anchor' href='#'>" + this.get_string("Loading ...") + "
        • "); + this.element.attr('aria-activedescendant','j' + this._id + '_loading'); + this._data.core.li_height = this.get_container_ul().children("li").first().outerHeight() || 24; + this._data.core.node = this._create_prototype_node(); + /** + * triggered after the loading text is shown and before loading starts + * @event + * @name loading.jstree + */ + this.trigger("loading"); + this.load_node($.jstree.root); + }, + /** + * destroy an instance + * @name destroy() + * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact + */ + destroy : function (keep_html) { + /** + * triggered before the tree is destroyed + * @event + * @name destroy.jstree + */ + this.trigger("destroy"); + if(this._wrk) { + try { + window.URL.revokeObjectURL(this._wrk); + this._wrk = null; + } + catch (ignore) { } + } + if(!keep_html) { this.element.empty(); } + this.teardown(); + }, + /** + * Create a prototype node + * @name _create_prototype_node() + * @return {DOMElement} + */ + _create_prototype_node : function () { + var _node = document.createElement('LI'), _temp1, _temp2; + _node.setAttribute('role', 'treeitem'); + _temp1 = document.createElement('I'); + _temp1.className = 'jstree-icon jstree-ocl'; + _temp1.setAttribute('role', 'presentation'); + _node.appendChild(_temp1); + _temp1 = document.createElement('A'); + _temp1.className = 'jstree-anchor'; + _temp1.setAttribute('href','#'); + _temp1.setAttribute('tabindex','-1'); + _temp2 = document.createElement('I'); + _temp2.className = 'jstree-icon jstree-themeicon'; + _temp2.setAttribute('role', 'presentation'); + _temp1.appendChild(_temp2); + _node.appendChild(_temp1); + _temp1 = _temp2 = null; + + return _node; + }, + _kbevent_to_func : function (e) { + var keys = { + 8: "Backspace", 9: "Tab", 13: "Return", 19: "Pause", 27: "Esc", + 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", + 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "Print", 45: "Insert", + 46: "Delete", 96: "Numpad0", 97: "Numpad1", 98: "Numpad2", 99 : "Numpad3", + 100: "Numpad4", 101: "Numpad5", 102: "Numpad6", 103: "Numpad7", + 104: "Numpad8", 105: "Numpad9", '-13': "NumpadEnter", 112: "F1", + 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", + 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", 144: "Numlock", + 145: "Scrolllock", 16: 'Shift', 17: 'Ctrl', 18: 'Alt', + 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', + 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a', + 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', + 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o', + 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', + 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.', + 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', + 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*', 173: '-' + }; + var parts = []; + if (e.ctrlKey) { parts.push('ctrl'); } + if (e.altKey) { parts.push('alt'); } + if (e.shiftKey) { parts.push('shift'); } + parts.push(keys[e.which] || e.which); + parts = parts.sort().join('-').toLowerCase(); + + var kb = this.settings.core.keyboard, i, tmp; + for (i in kb) { + if (kb.hasOwnProperty(i)) { + tmp = i; + if (tmp !== '-' && tmp !== '+') { + tmp = tmp.replace('--', '-MINUS').replace('+-', '-MINUS').replace('++', '-PLUS').replace('-+', '-PLUS'); + tmp = tmp.split(/-|\+/).sort().join('-').replace('MINUS', '-').replace('PLUS', '+').toLowerCase(); + } + if (tmp === parts) { + return kb[i]; + } + } + } + return null; + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name teardown() + */ + teardown : function () { + this.unbind(); + this.element + .removeClass('jstree') + .removeData('jstree') + .find("[class^='jstree']") + .addBack() + .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); + this.element = null; + }, + /** + * bind all events. Used internally. + * @private + * @name bind() + */ + bind : function () { + var word = '', + tout = null, + was_click = 0; + this.element + .on("dblclick.jstree", function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(document.selection && document.selection.empty) { + document.selection.empty(); + } + else { + if(window.getSelection) { + var sel = window.getSelection(); + try { + sel.removeAllRanges(); + sel.collapse(); + } catch (ignore) { } + } + } + }) + .on("mousedown.jstree", $.proxy(function (e) { + if(e.target === this.element[0]) { + e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome) + was_click = +(new Date()); // ie does not allow to prevent losing focus + } + }, this)) + .on("mousedown.jstree", ".jstree-ocl", function (e) { + e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon + }) + .on("click.jstree", ".jstree-ocl", $.proxy(function (e) { + this.toggle_node(e.target); + }, this)) + .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(this.settings.core.dblclick_toggle) { + this.toggle_node(e.target); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + e.preventDefault(); + if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); } + this.activate_node(e.currentTarget, e); + }, this)) + .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(this._data.core.rtl) { + if(e.which === 37) { e.which = 39; } + else if(e.which === 39) { e.which = 37; } + } + var f = this._kbevent_to_func(e); + if (f) { + var r = f.call(this, e); + if (r === false || r === true) { + return r; + } + } + }, this)) + .on("load_node.jstree", $.proxy(function (e, data) { + if(data.status) { + if(data.node.id === $.jstree.root && !this._data.core.loaded) { + this._data.core.loaded = true; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + /** + * triggered after the root node is loaded for the first time + * @event + * @name loaded.jstree + */ + this.trigger("loaded"); + } + if(!this._data.core.ready) { + setTimeout($.proxy(function() { + if(this.element && !this.get_container_ul().find('.jstree-loading').length) { + this._data.core.ready = true; + if(this._data.core.selected.length) { + if(this.settings.core.expand_selected_onload) { + var tmp = [], i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents); + } + tmp = $.vakata.array_unique(tmp); + for(i = 0, j = tmp.length; i < j; i++) { + this.open_node(tmp[i], false, 0); + } + } + this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected }); + } + /** + * triggered after all nodes are finished loading + * @event + * @name ready.jstree + */ + this.trigger("ready"); + } + }, this), 0); + } + } + }, this)) + // quick searching when the tree is focused + .on('keypress.jstree', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(tout) { clearTimeout(tout); } + tout = setTimeout(function () { + word = ''; + }, 500); + + var chr = String.fromCharCode(e.which).toLowerCase(), + col = this.element.find('.jstree-anchor').filter(':visible'), + ind = col.index(document.activeElement) || 0, + end = false; + word += chr; + + // match for whole word from current node down (including the current node) + if(word.length > 1) { + col.slice(ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // match for whole word from the beginning of the tree + col.slice(0, ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + // list nodes that start with that letter (only if word consists of a single char) + if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) { + // search for the next node starting with that letter + col.slice(ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // search from the beginning + col.slice(0, ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + }, this)) + // THEME RELATED + .on("init.jstree", $.proxy(function () { + var s = this.settings.core.themes; + this._data.core.themes.dots = s.dots; + this._data.core.themes.stripes = s.stripes; + this._data.core.themes.icons = s.icons; + this._data.core.themes.ellipsis = s.ellipsis; + this.set_theme(s.name || "default", s.url); + this.set_theme_variant(s.variant); + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ](); + this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ](); + this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ](); + this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ](); + }, this)) + .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) { + this._data.core.focused = null; + $(e.currentTarget).filter('.jstree-hovered').mouseleave(); + this.element.attr('tabindex', '0'); + }, this)) + .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) { + var tmp = this.get_node(e.currentTarget); + if(tmp && tmp.id) { + this._data.core.focused = tmp.id; + } + this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave(); + $(e.currentTarget).mouseenter(); + this.element.attr('tabindex', '-1'); + }, this)) + .on('focus.jstree', $.proxy(function () { + if(+(new Date()) - was_click > 500 && !this._data.core.focused && this.settings.core.restore_focus) { + was_click = 0; + var act = this.get_node(this.element.attr('aria-activedescendant'), true); + if(act) { + act.find('> .jstree-anchor').focus(); + } + } + }, this)) + .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) { + this.hover_node(e.currentTarget); + }, this)) + .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name unbind() + */ + unbind : function () { + this.element.off('.jstree'); + $(document).off('.jstree-' + this._id); + }, + /** + * trigger an event. Used internally. + * @private + * @name trigger(ev [, data]) + * @param {String} ev the name of the event to trigger + * @param {Object} data additional data to pass with the event + */ + trigger : function (ev, data) { + if(!data) { + data = {}; + } + data.instance = this; + this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data); + }, + /** + * returns the jQuery extended instance container + * @name get_container() + * @return {jQuery} + */ + get_container : function () { + return this.element; + }, + /** + * returns the jQuery extended main UL node inside the instance container. Used internally. + * @private + * @name get_container_ul() + * @return {jQuery} + */ + get_container_ul : function () { + return this.element.children(".jstree-children").first(); + }, + /** + * gets string replacements (localization). Used internally. + * @private + * @name get_string(key) + * @param {String} key + * @return {String} + */ + get_string : function (key) { + var a = this.settings.core.strings; + if($.isFunction(a)) { return a.call(this, key); } + if(a && a[key]) { return a[key]; } + return key; + }, + /** + * gets the first child of a DOM node. Used internally. + * @private + * @name _firstChild(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _firstChild : function (dom) { + dom = dom ? dom.firstChild : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the next sibling of a DOM node. Used internally. + * @private + * @name _nextSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _nextSibling : function (dom) { + dom = dom ? dom.nextSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the previous sibling of a DOM node. Used internally. + * @private + * @name _previousSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _previousSibling : function (dom) { + dom = dom ? dom.previousSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.previousSibling; + } + return dom; + }, + /** + * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc) + * @name get_node(obj [, as_dom]) + * @param {mixed} obj + * @param {Boolean} as_dom + * @return {Object|jQuery} + */ + get_node : function (obj, as_dom) { + if(obj && obj.id) { + obj = obj.id; + } + if (obj instanceof jQuery && obj.length && obj[0].id) { + obj = obj[0].id; + } + var dom; + try { + if(this._model.data[obj]) { + obj = this._model.data[obj]; + } + else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) { + obj = this._model.data[obj.replace(/^#/, '')]; + } + else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = this.element.find(obj)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = this.element.find(obj)).length && dom.hasClass('jstree')) { + obj = this._model.data[$.jstree.root]; + } + else { + return false; + } + + if(as_dom) { + obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + } + return obj; + } catch (ex) { return false; } + }, + /** + * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array) + * @name get_path(obj [, glue, ids]) + * @param {mixed} obj the node + * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned + * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used + * @return {mixed} + */ + get_path : function (obj, glue, ids) { + obj = obj.parents ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root || !obj.parents) { + return false; + } + var i, j, p = []; + p.push(ids ? obj.id : obj.text); + for(i = 0, j = obj.parents.length; i < j; i++) { + p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i])); + } + p = p.reverse().slice(1); + return glue ? p.join(glue) : p; + }, + /** + * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_next_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_next_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this._firstChild(this.get_container_ul()[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + if(obj.hasClass("jstree-open")) { + tmp = this._firstChild(obj.children('.jstree-children')[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + if(tmp !== null) { + return $(tmp); + } + } + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + return $(tmp); + } + return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first(); + }, + /** + * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_prev_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_prev_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this.get_container_ul()[0].lastChild; + while (tmp && tmp.offsetHeight === 0) { + tmp = this._previousSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + obj = $(tmp); + while(obj.hasClass("jstree-open")) { + obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last"); + } + return obj; + } + tmp = obj[0].parentNode.parentNode; + return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false; + }, + /** + * get the parent ID of a node + * @name get_parent(obj) + * @param {mixed} obj + * @return {String} + */ + get_parent : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.parent; + }, + /** + * get a jQuery collection of all the children of a node (node must be rendered), returns false on error + * @name get_children_dom(obj) + * @param {mixed} obj + * @return {jQuery} + */ + get_children_dom : function (obj) { + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + return this.get_container_ul().children(".jstree-node"); + } + if(!obj || !obj.length) { + return false; + } + return obj.children(".jstree-children").children(".jstree-node"); + }, + /** + * checks if a node has children + * @name is_parent(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_parent : function (obj) { + obj = this.get_node(obj); + return obj && (obj.state.loaded === false || obj.children.length > 0); + }, + /** + * checks if a node is loaded (its children are available) + * @name is_loaded(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loaded : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.loaded; + }, + /** + * check if a node is currently loading (fetching children) + * @name is_loading(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loading : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.loading; + }, + /** + * check if a node is opened + * @name is_open(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_open : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.opened; + }, + /** + * check if a node is in a closed state + * @name is_closed(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_closed : function (obj) { + obj = this.get_node(obj); + return obj && this.is_parent(obj) && !obj.state.opened; + }, + /** + * check if a node has no children + * @name is_leaf(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_leaf : function (obj) { + return !this.is_parent(obj); + }, + /** + * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array. + * @name load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status + * @return {Boolean} + * @trigger load_node.jstree + */ + load_node : function (obj, callback) { + var k, l, i, j, c; + if($.isArray(obj)) { + this._load_nodes(obj.slice(), callback); + return true; + } + obj = this.get_node(obj); + if(!obj) { + if(callback) { callback.call(this, obj, false); } + return false; + } + // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again? + if(obj.state.loaded) { + obj.state.loaded = false; + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + for(k = 0, l = obj.children_d.length; k < l; k++) { + if(this._model.data[obj.children_d[k]].state.selected) { + c = true; + } + delete this._model.data[obj.children_d[k]]; + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + obj.children = []; + obj.children_d = []; + if(c) { + this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected }); + } + } + obj.state.failed = false; + obj.state.loading = true; + this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true); + this._load_node(obj, $.proxy(function (status) { + obj = this._model.data[obj.id]; + obj.state.loading = false; + obj.state.loaded = status; + obj.state.failed = !obj.state.loaded; + var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false; + for(i = 0, j = obj.children.length; i < j; i++) { + if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.state.loaded && dom && dom.length) { + dom.removeClass('jstree-closed jstree-open jstree-leaf'); + if (!has_children) { + dom.addClass('jstree-leaf'); + } + else { + if (obj.id !== '#') { + dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed'); + } + } + } + dom.removeClass("jstree-loading").attr('aria-busy',false); + /** + * triggered after a node is loaded + * @event + * @name load_node.jstree + * @param {Object} node the node that was loading + * @param {Boolean} status was the node loaded successfully + */ + this.trigger('load_node', { "node" : obj, "status" : status }); + if(callback) { + callback.call(this, obj, status); + } + }, this)); + return true; + }, + /** + * load an array of nodes (will also load unavailable nodes as soon as they appear in the structure). Used internally. + * @private + * @name _load_nodes(nodes [, callback]) + * @param {array} nodes + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes + */ + _load_nodes : function (nodes, callback, is_callback, force_reload) { + var r = true, + c = function () { this._load_nodes(nodes, callback, true); }, + m = this._model.data, i, j, tmp = []; + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) { + if(!this.is_loading(nodes[i])) { + this.load_node(nodes[i], c); + } + r = false; + } + } + if(r) { + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && m[nodes[i]].state.loaded) { + tmp.push(nodes[i]); + } + } + if(callback && !callback.done) { + callback.call(this, tmp); + callback.done = true; + } + } + }, + /** + * loads all unloaded nodes + * @name load_all([obj, callback]) + * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree + * @param {function} callback a function to be executed once loading all the nodes is complete, + * @trigger load_all.jstree + */ + load_all : function (obj, callback) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var to_load = [], + m = this._model.data, + c = m[obj.id].children_d, + i, j; + if(obj.state && !obj.state.loaded) { + to_load.push(obj.id); + } + for(i = 0, j = c.length; i < j; i++) { + if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) { + to_load.push(c[i]); + } + } + if(to_load.length) { + this._load_nodes(to_load, function () { + this.load_all(obj, callback); + }); + } + else { + /** + * triggered after a load_all call completes + * @event + * @name load_all.jstree + * @param {Object} node the recursively loaded node + */ + if(callback) { callback.call(this, obj); } + this.trigger('load_all', { "node" : obj }); + } + }, + /** + * handles the actual loading of a node. Used only internally. + * @private + * @name _load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status + * @return {Boolean} + */ + _load_node : function (obj, callback) { + var s = this.settings.core.data, t; + var notTextOrCommentNode = function notTextOrCommentNode () { + return this.nodeType !== 3 && this.nodeType !== 8; + }; + // use original HTML + if(!s) { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) { + callback.call(this, status); + }); + } + else { + return callback.call(this, false); + } + // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false); + } + if($.isFunction(s)) { + return s.call(this, obj, $.proxy(function (d) { + if(d === false) { + callback.call(this, false); + } + else { + this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) { + callback.call(this, status); + }); + } + // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d)); + }, this)); + } + if(typeof s === 'object') { + if(s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, obj); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, obj); + } + return $.ajax(s) + .done($.proxy(function (d,t,x) { + var type = x.getResponseHeader('Content-Type'); + if((type && type.indexOf('json') !== -1) || typeof d === "object") { + return this._append_json_data(obj, d, function (status) { callback.call(this, status); }); + //return callback.call(this, this._append_json_data(obj, d)); + } + if((type && type.indexOf('html') !== -1) || typeof d === "string") { + return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); + // return callback.call(this, this._append_html_data(obj, $(d))); + } + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + }, this)) + .fail($.proxy(function (f) { + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) }; + callback.call(this, false); + this.settings.core.error.call(this, this._data.core.last_error); + }, this)); + } + if ($.isArray(s)) { + t = $.extend(true, [], s); + } else if ($.isPlainObject(s)) { + t = $.extend(true, {}, s); + } else { + t = s; + } + if(obj.id === $.jstree.root) { + return this._append_json_data(obj, t, function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) ); + } + if(typeof s === 'string') { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) ); + } + return callback.call(this, false); + }, + /** + * adds a node to the list of nodes to redraw. Used only internally. + * @private + * @name _node_changed(obj [, callback]) + * @param {mixed} obj + */ + _node_changed : function (obj) { + obj = this.get_node(obj); + if (obj && $.inArray(obj.id, this._model.changed) === -1) { + this._model.changed.push(obj.id); + } + }, + /** + * appends HTML content to the tree. Used internally. + * @private + * @name _append_html_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the HTML string to parse and append + * @trigger model.jstree, changed.jstree + */ + _append_html_data : function (dom, data, cb) { + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + var dat = data.is('ul') ? data.children() : data, + par = dom.id, + chd = [], + dpc = [], + m = this._model.data, + p = m[par], + s = this._data.core.selected.length, + tmp, i, j; + dat.each($.proxy(function (i, v) { + tmp = this._parse_model_from_html($(v), par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + }, this)); + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + /** + * triggered when new data is inserted to the tree model + * @event + * @name model.jstree + * @param {Array} nodes an array of node IDs + * @param {String} parent the parent ID of the nodes + */ + this.trigger('model', { "nodes" : dpc, 'parent' : par }); + if(par !== $.jstree.root) { + this._node_changed(par); + this.redraw(); + } + else { + this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(this._data.core.selected.length !== s) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }, + /** + * appends JSON content to the tree. Used internally. + * @private + * @name _append_json_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the JSON object to parse and append + * @param {Boolean} force_processing internal param - do not set + * @trigger model.jstree, changed.jstree + */ + _append_json_data : function (dom, data, cb, force_processing) { + if(this.element === null) { return; } + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + // *%$@!!! + if(data.d) { + data = data.d; + if(typeof data === "string") { + data = JSON.parse(data); + } + } + if(!$.isArray(data)) { data = [data]; } + var w = null, + args = { + 'df' : this._model.default_state, + 'dat' : data, + 'par' : dom.id, + 'm' : this._model.data, + 't_id' : this._id, + 't_cnt' : this._cnt, + 'sel' : this._data.core.selected + }, + func = function (data, undefined) { + if(data.data) { data = data.data; } + var dat = data.dat, + par = data.par, + chd = [], + dpc = [], + add = [], + df = data.df, + t_id = data.t_id, + t_cnt = data.t_cnt, + m = data.m, + p = m[par], + sel = data.sel, + tmp, i, j, rslt, + parse_flat = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = parse_flat(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }, + parse_nest = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, tmp; + do { + tid = 'j' + t_id + '_' + (++t_cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = parse_nest(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }; + + if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) { + // Flat JSON support (for easy import from DB): + // 1) convert to object (foreach) + for(i = 0, j = dat.length; i < j; i++) { + if(!dat[i].children) { + dat[i].children = []; + } + if(!dat[i].state) { + dat[i].state = {}; + } + m[dat[i].id.toString()] = dat[i]; + } + // 2) populate children (foreach) + for(i = 0, j = dat.length; i < j; i++) { + if (!m[dat[i].parent.toString()]) { + this._data.core.last_error = { 'error' : 'parse', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Node with invalid parent', 'data' : JSON.stringify({ 'id' : dat[i].id.toString(), 'parent' : dat[i].parent.toString() }) }; + this.settings.core.error.call(this, this._data.core.last_error); + continue; + } + + m[dat[i].parent.toString()].children.push(dat[i].id.toString()); + // populate parent.children_d + p.children_d.push(dat[i].id.toString()); + } + // 3) normalize && populate parents and children_d with recursion + for(i = 0, j = p.children.length; i < j; i++) { + tmp = parse_flat(m[p.children[i]], par, p.parents.concat()); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true; + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + else { + for(i = 0, j = dat.length; i < j; i++) { + tmp = parse_nest(dat[i], par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + } + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + if(typeof window === 'undefined' || typeof window.document === 'undefined') { + postMessage(rslt); + } + else { + return rslt; + } + }, + rslt = function (rslt, worker) { + if(this.element === null) { return; } + this._cnt = rslt.cnt; + var i, m = this._model.data; + for (i in m) { + if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) { + rslt.mod[i].state.loading = true; + } + } + this._model.data = rslt.mod; // breaks the reference in load_node - careful + + if(worker) { + var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(); + m = this._model.data; + // if selection was changed while calculating in worker + if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) { + // deselect nodes that are no longer selected + for(i = 0, j = r.length; i < j; i++) { + if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) { + m[r[i]].state.selected = false; + } + } + // select nodes that were selected in the mean time + for(i = 0, j = s.length; i < j; i++) { + if($.inArray(s[i], r) === -1) { + m[s[i]].state.selected = true; + } + } + } + } + if(rslt.add.length) { + this._data.core.selected = this._data.core.selected.concat(rslt.add); + } + + this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par }); + + if(rslt.par !== $.jstree.root) { + this._node_changed(rslt.par); + this.redraw(); + } + else { + // this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(rslt.add.length) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }; + if(this.settings.core.worker && window.Blob && window.URL && window.Worker) { + try { + if(this._wrk === null) { + this._wrk = window.URL.createObjectURL( + new window.Blob( + ['self.onmessage = ' + func.toString()], + {type:"text/javascript"} + ) + ); + } + if(!this._data.core.working || force_processing) { + this._data.core.working = true; + w = new window.Worker(this._wrk); + w.onmessage = $.proxy(function (e) { + rslt.call(this, e.data, true); + try { w.terminate(); w = null; } catch(ignore) { } + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + }, this); + if(!args.par) { + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + else { + w.postMessage(args); + } + } + else { + this._data.core.worker_queue.push([dom, data, cb, true]); + } + } + catch(e) { + rslt.call(this, func(args), false); + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + } + else { + rslt.call(this, func(args), false); + } + }, + /** + * parses a node from a jQuery object and appends them to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_html(d [, p, ps]) + * @param {jQuery} d the jQuery object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_html : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = [].concat(ps); } + if(p) { ps.unshift(p); } + var c, e, m = this._model.data, + data = { + id : false, + text : false, + icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }, i, tmp, tid; + for(i in this._model.default_state) { + if(this._model.default_state.hasOwnProperty(i)) { + data.state[i] = this._model.default_state[i]; + } + } + tmp = $.vakata.attributes(d, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(!v.length) { return true; } + data.li_attr[i] = v; + if(i === 'id') { + data.id = v.toString(); + } + }); + tmp = d.children('a').first(); + if(tmp.length) { + tmp = $.vakata.attributes(tmp, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(v.length) { + data.a_attr[i] = v; + } + }); + } + tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone(); + tmp.children("ins, i, ul").remove(); + tmp = tmp.html(); + tmp = $('
          ').html(tmp); + data.text = this.settings.core.force_text ? tmp.text() : tmp.html(); + tmp = d.data(); + data.data = tmp ? $.extend(true, {}, tmp) : null; + data.state.opened = d.hasClass('jstree-open'); + data.state.selected = d.children('a').hasClass('jstree-clicked'); + data.state.disabled = d.children('a').hasClass('jstree-disabled'); + if(data.data && data.data.jstree) { + for(i in data.data.jstree) { + if(data.data.jstree.hasOwnProperty(i)) { + data.state[i] = data.data.jstree[i]; + } + } + } + tmp = d.children("a").children(".jstree-themeicon"); + if(tmp.length) { + data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel'); + } + if(data.state.icon !== undefined) { + data.icon = data.state.icon; + } + if(data.icon === undefined || data.icon === null || data.icon === "") { + data.icon = true; + } + tmp = d.children("ul").children("li"); + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + data.id = data.li_attr.id ? data.li_attr.id.toString() : tid; + if(tmp.length) { + tmp.each($.proxy(function (i, v) { + c = this._parse_model_from_html($(v), data.id, ps); + e = this._model.data[c]; + data.children.push(c); + if(e.children_d.length) { + data.children_d = data.children_d.concat(e.children_d); + } + }, this)); + data.children_d = data.children_d.concat(data.children); + } + else { + if(d.hasClass('jstree-closed')) { + data.state.loaded = false; + } + } + if(data.li_attr['class']) { + data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open',''); + } + if(data.a_attr['class']) { + data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled',''); + } + m[data.id] = data; + if(data.state.selected) { + this._data.core.selected.push(data.id); + } + return data.id; + }, + /** + * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_flat_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_flat_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + m = this._model.data, + df = this._model.default_state, + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * parses a node from a JSON object and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp; + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = this._parse_model_from_json(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * redraws all nodes that need to be redrawn. Used internally. + * @private + * @name _redraw() + * @trigger redraw.jstree + */ + _redraw : function () { + var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]), + f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused; + for(i = 0, j = nodes.length; i < j; i++) { + tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw); + if(tmp && this._model.force_full_redraw) { + f.appendChild(tmp); + } + } + if(this._model.force_full_redraw) { + f.className = this.get_container_ul()[0].className; + f.setAttribute('role','group'); + this.element.empty().append(f); + //this.get_container_ul()[0].appendChild(f); + } + if(fe !== null && this.settings.core.restore_focus) { + tmp = this.get_node(fe, true); + if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) { + tmp.children('.jstree-anchor').focus(); + } + else { + this._data.core.focused = null; + } + } + this._model.force_full_redraw = false; + this._model.changed = []; + /** + * triggered after nodes are redrawn + * @event + * @name redraw.jstree + * @param {array} nodes the redrawn nodes + */ + this.trigger('redraw', { "nodes" : nodes }); + }, + /** + * redraws all nodes that need to be redrawn or optionally - the whole tree + * @name redraw([full]) + * @param {Boolean} full if set to `true` all nodes are redrawn. + */ + redraw : function (full) { + if(full) { + this._model.force_full_redraw = true; + } + //if(this._model.redraw_timeout) { + // clearTimeout(this._model.redraw_timeout); + //} + //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0); + this._redraw(); + }, + /** + * redraws a single node's children. Used internally. + * @private + * @name draw_children(node) + * @param {mixed} node the node whose children will be redrawn + */ + draw_children : function (node) { + var obj = this.get_node(node), + i = false, + j = false, + k = false, + d = document; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + node = this.get_node(node, true); + if(!node || !node.length) { return false; } // TODO: quick toggle + + node.children('.jstree-children').remove(); + node = node[0]; + if(obj.children.length && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], true, true)); + } + node.appendChild(k); + } + }, + /** + * redraws a single node. Used internally. + * @private + * @name redraw_node(node, deep, is_callback, force_render) + * @param {mixed} node the node to redraw + * @param {Boolean} deep should child nodes be redrawn too + * @param {Boolean} is_callback is this a recursion call + * @param {Boolean} force_render should children of closed parents be drawn anyway + */ + redraw_node : function (node, deep, is_callback, force_render) { + var obj = this.get_node(node), + par = false, + ind = false, + old = false, + i = false, + j = false, + k = false, + c = '', + d = document, + m = this._model.data, + f = false, + s = false, + tmp = null, + t = 0, + l = 0, + has_children = false, + last_sibling = false; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + deep = deep || obj.children.length === 0; + node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element); + if(!node) { + deep = true; + //node = d.createElement('LI'); + if(!is_callback) { + par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null; + if(par !== null && (!par || !m[obj.parent].state.opened)) { + return false; + } + ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children); + } + } + else { + node = $(node); + if(!is_callback) { + par = node.parent().parent()[0]; + if(par === this.element[0]) { + par = null; + } + ind = node.index(); + } + // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage + if(!deep && obj.children.length && !node.children('.jstree-children').length) { + deep = true; + } + if(!deep) { + old = node.children('.jstree-children')[0]; + } + f = node.children('.jstree-anchor')[0] === document.activeElement; + node.remove(); + //node = d.createElement('LI'); + //node = node[0]; + } + node = this._data.core.node.cloneNode(true); + // node is DOM, deep is boolean + + c = 'jstree-node '; + for(i in obj.li_attr) { + if(obj.li_attr.hasOwnProperty(i)) { + if(i === 'id') { continue; } + if(i !== 'class') { + node.setAttribute(i, obj.li_attr[i]); + } + else { + c += obj.li_attr[i]; + } + } + } + if(!obj.a_attr.id) { + obj.a_attr.id = obj.id + '_anchor'; + } + node.setAttribute('aria-selected', !!obj.state.selected); + node.setAttribute('aria-level', obj.parents.length); + node.setAttribute('aria-labelledby', obj.a_attr.id); + if(obj.state.disabled) { + node.setAttribute('aria-disabled', true); + } + + for(i = 0, j = obj.children.length; i < j; i++) { + if(!m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) { + i = $.inArray(obj.id, m[obj.parent].children); + last_sibling = obj.id; + if(i !== -1) { + i++; + for(j = m[obj.parent].children.length; i < j; i++) { + if(!m[m[obj.parent].children[i]].state.hidden) { + last_sibling = m[obj.parent].children[i]; + } + if(last_sibling !== obj.id) { + break; + } + } + } + } + + if(obj.state.hidden) { + c += ' jstree-hidden'; + } + if (obj.state.loading) { + c += ' jstree-loading'; + } + if(obj.state.loaded && !has_children) { + c += ' jstree-leaf'; + } + else { + c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed'; + node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) ); + } + if(last_sibling === obj.id) { + c += ' jstree-last'; + } + node.id = obj.id; + node.className = c; + c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : ''); + for(j in obj.a_attr) { + if(obj.a_attr.hasOwnProperty(j)) { + if(j === 'href' && obj.a_attr[j] === '#') { continue; } + if(j !== 'class') { + node.childNodes[1].setAttribute(j, obj.a_attr[j]); + } + else { + c += ' ' + obj.a_attr[j]; + } + } + } + if(c.length) { + node.childNodes[1].className = 'jstree-anchor ' + c; + } + if((obj.icon && obj.icon !== true) || obj.icon === false) { + if(obj.icon === false) { + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden'; + } + else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) { + node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom'; + } + else { + node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")'; + node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center'; + node.childNodes[1].childNodes[0].style.backgroundSize = 'auto'; + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom'; + } + } + + if(this.settings.core.force_text) { + node.childNodes[1].appendChild(d.createTextNode(obj.text)); + } + else { + node.childNodes[1].innerHTML += obj.text; + } + + + if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], deep, true)); + } + node.appendChild(k); + } + if(old) { + node.appendChild(old); + } + if(!is_callback) { + // append back using par / ind + if(!par) { + par = this.element[0]; + } + for(i = 0, j = par.childNodes.length; i < j; i++) { + if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) { + tmp = par.childNodes[i]; + break; + } + } + if(!tmp) { + tmp = d.createElement('UL'); + tmp.setAttribute('role', 'group'); + tmp.className = 'jstree-children'; + par.appendChild(tmp); + } + par = tmp; + + if(ind < par.childNodes.length) { + par.insertBefore(node, par.childNodes[ind]); + } + else { + par.appendChild(node); + } + if(f) { + t = this.element[0].scrollTop; + l = this.element[0].scrollLeft; + node.childNodes[1].focus(); + this.element[0].scrollTop = t; + this.element[0].scrollLeft = l; + } + } + if(obj.state.opened && !obj.state.loaded) { + obj.state.opened = false; + setTimeout($.proxy(function () { + this.open_node(obj.id, false, 0); + }, this), 0); + } + return node; + }, + /** + * opens a node, revealing its children. If the node is not loaded it will be loaded and opened once ready. + * @name open_node(obj [, callback, animation]) + * @param {mixed} obj the node to open + * @param {Function} callback a function to execute once the node is opened + * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger open_node.jstree, after_open.jstree, before_open.jstree + */ + open_node : function (obj, callback, animation) { + var t1, t2, d, t; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.open_node(obj[t1], callback, animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + if(!this.is_closed(obj)) { + if(callback) { + callback.call(this, obj, false); + } + return false; + } + if(!this.is_loaded(obj)) { + if(this.is_loading(obj)) { + return setTimeout($.proxy(function () { + this.open_node(obj, callback, animation); + }, this), 500); + } + this.load_node(obj, function (o, ok) { + return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false); + }); + } + else { + d = this.get_node(obj, true); + t = this; + if(d.length) { + if(animation && d.children(".jstree-children").length) { + d.children(".jstree-children").stop(true, true); + } + if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) { + this.draw_children(obj); + //d = this.get_node(obj, true); + } + if(!animation) { + this.trigger('before_open', { "node" : obj }); + d[0].className = d[0].className.replace('jstree-closed', 'jstree-open'); + d[0].setAttribute("aria-expanded", true); + } + else { + this.trigger('before_open', { "node" : obj }); + d + .children(".jstree-children").css("display","none").end() + .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true) + .children(".jstree-children").stop(true, true) + .slideDown(animation, function () { + this.style.display = ""; + if (t.element) { + t.trigger("after_open", { "node" : obj }); + } + }); + } + } + obj.state.opened = true; + if(callback) { + callback.call(this, obj, true); + } + if(!d.length) { + /** + * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet) + * @event + * @name before_open.jstree + * @param {Object} node the opened node + */ + this.trigger('before_open', { "node" : obj }); + } + /** + * triggered when a node is opened (if there is an animation it will not be completed yet) + * @event + * @name open_node.jstree + * @param {Object} node the opened node + */ + this.trigger('open_node', { "node" : obj }); + if(!animation || !d.length) { + /** + * triggered when a node is opened and the animation is complete + * @event + * @name after_open.jstree + * @param {Object} node the opened node + */ + this.trigger("after_open", { "node" : obj }); + } + return true; + } + }, + /** + * opens every parent of a node (node should be loaded) + * @name _open_to(obj) + * @param {mixed} obj the node to reveal + * @private + */ + _open_to : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + var i, j, p = obj.parents; + for(i = 0, j = p.length; i < j; i+=1) { + if(i !== $.jstree.root) { + this.open_node(p[i], false, 0); + } + } + return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + }, + /** + * closes a node, hiding its children + * @name close_node(obj [, animation]) + * @param {mixed} obj the node to close + * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger close_node.jstree, after_close.jstree + */ + close_node : function (obj, animation) { + var t1, t2, t, d; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.close_node(obj[t1], animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(this.is_closed(obj)) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + t = this; + d = this.get_node(obj, true); + + obj.state.opened = false; + /** + * triggered when a node is closed (if there is an animation it will not be complete yet) + * @event + * @name close_node.jstree + * @param {Object} node the closed node + */ + this.trigger('close_node',{ "node" : obj }); + if(!d.length) { + /** + * triggered when a node is closed and the animation is complete + * @event + * @name after_close.jstree + * @param {Object} node the closed node + */ + this.trigger("after_close", { "node" : obj }); + } + else { + if(!animation) { + d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); + d.attr("aria-expanded", false).children('.jstree-children').remove(); + this.trigger("after_close", { "node" : obj }); + } + else { + d + .children(".jstree-children").attr("style","display:block !important").end() + .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false) + .children(".jstree-children").stop(true, true).slideUp(animation, function () { + this.style.display = ""; + d.children('.jstree-children').remove(); + if (t.element) { + t.trigger("after_close", { "node" : obj }); + } + }); + } + } + }, + /** + * toggles a node - closing it if it is open, opening it if it is closed + * @name toggle_node(obj) + * @param {mixed} obj the node to toggle + */ + toggle_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.toggle_node(obj[t1]); + } + return true; + } + if(this.is_closed(obj)) { + return this.open_node(obj); + } + if(this.is_open(obj)) { + return this.close_node(obj); + } + }, + /** + * opens all nodes within a node (or the tree), revealing their children. If the node is not loaded it will be loaded and opened once ready. + * @name open_all([obj, animation, original_obj]) + * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation + * @param {jQuery} reference to the node that started the process (internal use) + * @trigger open_all.jstree + */ + open_all : function (obj, animation, original_obj) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this; + if(!dom.length) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + if(this.is_closed(this._model.data[obj.children_d[i]])) { + this._model.data[obj.children_d[i]].state.opened = true; + } + } + return this.trigger('open_all', { "node" : obj }); + } + original_obj = original_obj || dom; + _this = this; + dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed'); + dom.each(function () { + _this.open_node( + this, + function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } }, + animation || 0 + ); + }); + if(original_obj.find('.jstree-closed').length === 0) { + /** + * triggered when an `open_all` call completes + * @event + * @name open_all.jstree + * @param {Object} node the opened node + */ + this.trigger('open_all', { "node" : this.get_node(original_obj) }); + } + }, + /** + * closes all nodes within a node (or the tree), revealing their children + * @name close_all([obj, animation]) + * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation + * @trigger close_all.jstree + */ + close_all : function (obj, animation) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), + _this = this, i, j; + if(dom.length) { + dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open'); + $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); }); + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].state.opened = false; + } + /** + * triggered when an `close_all` call completes + * @event + * @name close_all.jstree + * @param {Object} node the closed node + */ + this.trigger('close_all', { "node" : obj }); + }, + /** + * checks if a node is disabled (not selectable) + * @name is_disabled(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_disabled : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.disabled; + }, + /** + * enables a node - so that it can be selected + * @name enable_node(obj) + * @param {mixed} obj the node to enable + * @trigger enable_node.jstree + */ + enable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = false; + this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false); + /** + * triggered when an node is enabled + * @event + * @name enable_node.jstree + * @param {Object} node the enabled node + */ + this.trigger('enable_node', { 'node' : obj }); + }, + /** + * disables a node - so that it can not be selected + * @name disable_node(obj) + * @param {mixed} obj the node to disable + * @trigger disable_node.jstree + */ + disable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = true; + this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true); + /** + * triggered when an node is disabled + * @event + * @name disable_node.jstree + * @param {Object} node the disabled node + */ + this.trigger('disable_node', { 'node' : obj }); + }, + /** + * determines if a node is hidden + * @name is_hidden(obj) + * @param {mixed} obj the node + */ + is_hidden : function (obj) { + obj = this.get_node(obj); + return obj.state.hidden === true; + }, + /** + * hides a node - it is still in the structure but will not be visible + * @name hide_node(obj) + * @param {mixed} obj the node to hide + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger hide_node.jstree + */ + hide_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(!obj.state.hidden) { + obj.state.hidden = true; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is hidden + * @event + * @name hide_node.jstree + * @param {Object} node the hidden node + */ + this.trigger('hide_node', { 'node' : obj }); + } + }, + /** + * shows a node + * @name show_node(obj) + * @param {mixed} obj the node to show + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger show_node.jstree + */ + show_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(obj.state.hidden) { + obj.state.hidden = false; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is shown + * @event + * @name show_node.jstree + * @param {Object} node the shown node + */ + this.trigger('show_node', { 'node' : obj }); + } + }, + /** + * hides all nodes + * @name hide_all() + * @trigger hide_all.jstree + */ + hide_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) { + m[i].state.hidden = true; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are hidden + * @event + * @name hide_all.jstree + * @param {Array} nodes the IDs of all hidden nodes + */ + this.trigger('hide_all', { 'nodes' : ids }); + return ids; + }, + /** + * shows all nodes + * @name show_all() + * @trigger show_all.jstree + */ + show_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) { + m[i].state.hidden = false; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are shown + * @event + * @name show_all.jstree + * @param {Array} nodes the IDs of all shown nodes + */ + this.trigger('show_all', { 'nodes' : ids }); + return ids; + }, + /** + * called when a node is selected by the user. Used internally. + * @private + * @name activate_node(obj, e) + * @param {mixed} obj the node + * @param {Object} e the related event + * @trigger activate_node.jstree, changed.jstree + */ + activate_node : function (obj, e) { + if(this.is_disabled(obj)) { + return false; + } + if(!e || typeof e !== 'object') { + e = {}; + } + + // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node + this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null; + if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; } + if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); } + + if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) { + if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) { + this.deselect_node(obj, false, e); + } + else { + this.deselect_all(true); + this.select_node(obj, false, false, e); + this._data.core.last_clicked = this.get_node(obj); + } + } + else { + if(e.shiftKey) { + var o = this.get_node(obj).id, + l = this._data.core.last_clicked.id, + p = this.get_node(this._data.core.last_clicked.parent).children, + c = false, + i, j; + for(i = 0, j = p.length; i < j; i += 1) { + // separate IFs work whem o and l are the same + if(p[i] === o) { + c = !c; + } + if(p[i] === l) { + c = !c; + } + if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) { + if (!this.is_hidden(p[i])) { + this.select_node(p[i], true, false, e); + } + } + else { + this.deselect_node(p[i], true, e); + } + } + this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e }); + } + else { + if(!this.is_selected(obj)) { + this.select_node(obj, false, false, e); + } + else { + this.deselect_node(obj, false, e); + } + } + } + /** + * triggered when an node is clicked or intercated with by the user + * @event + * @name activate_node.jstree + * @param {Object} node + * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object) + */ + this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e }); + }, + /** + * applies the hover state on a node, called when a node is hovered by the user. Used internally. + * @private + * @name hover_node(obj) + * @param {mixed} obj + * @trigger hover_node.jstree + */ + hover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || obj.children('.jstree-hovered').length) { + return false; + } + var o = this.element.find('.jstree-hovered'), t = this.element; + if(o && o.length) { this.dehover_node(o); } + + obj.children('.jstree-anchor').addClass('jstree-hovered'); + /** + * triggered when an node is hovered + * @event + * @name hover_node.jstree + * @param {Object} node + */ + this.trigger('hover_node', { 'node' : this.get_node(obj) }); + setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0); + }, + /** + * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally. + * @private + * @name dehover_node(obj) + * @param {mixed} obj + * @trigger dehover_node.jstree + */ + dehover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || !obj.children('.jstree-hovered').length) { + return false; + } + obj.children('.jstree-anchor').removeClass('jstree-hovered'); + /** + * triggered when an node is no longer hovered + * @event + * @name dehover_node.jstree + * @param {Object} node + */ + this.trigger('dehover_node', { 'node' : this.get_node(obj) }); + }, + /** + * select a node + * @name select_node(obj [, supress_event, prevent_open]) + * @param {mixed} obj an array can be used to select multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened + * @trigger select_node.jstree, changed.jstree + */ + select_node : function (obj, supress_event, prevent_open, e) { + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.select_node(obj[t1], supress_event, prevent_open, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.selected) { + obj.state.selected = true; + this._data.core.selected.push(obj.id); + if(!prevent_open) { + dom = this._open_to(obj); + } + if(dom && dom.length) { + dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked'); + } + /** + * triggered when an node is selected + * @event + * @name select_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this select_node + */ + this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + /** + * triggered when selection changes + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this changed event + */ + this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * deselect a node + * @name deselect_node(obj [, supress_event]) + * @param {mixed} obj an array can be used to deselect multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_node.jstree, changed.jstree + */ + deselect_node : function (obj, supress_event, e) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.deselect_node(obj[t1], supress_event, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.selected) { + obj.state.selected = false; + this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id); + if(dom.length) { + dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked'); + } + /** + * triggered when an node is deselected + * @event + * @name deselect_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this deselect_node + */ + this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * select all nodes in the tree + * @name select_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger select_all.jstree, changed.jstree + */ + select_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + this._data.core.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are selected + * @event + * @name select_all.jstree + * @param {Array} selected the current selection + */ + this.trigger('select_all', { 'selected' : this._data.core.selected }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * deselect all selected nodes + * @name deselect_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_all.jstree, changed.jstree + */ + deselect_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = false; + } + } + this._data.core.selected = []; + this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false); + /** + * triggered when all nodes are deselected + * @event + * @name deselect_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + */ + this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * checks if a node is selected + * @name is_selected(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_selected : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.state.selected; + }, + /** + * get an array of all selected nodes + * @name get_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_selected : function (full) { + return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice(); + }, + /** + * get an array of all top level selected nodes (ignoring children of selected nodes) + * @name get_top_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_top_selected : function (full) { + var tmp = this.get_selected(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }, + /** + * get an array of all bottom level selected nodes (ignoring selected parents) + * @name get_bottom_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_bottom_selected : function (full) { + var tmp = this.get_selected(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }, + /** + * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally. + * @name get_state() + * @private + * @return {Object} + */ + get_state : function () { + var state = { + 'core' : { + 'open' : [], + 'loaded' : [], + 'scroll' : { + 'left' : this.element.scrollLeft(), + 'top' : this.element.scrollTop() + }, + /*! + 'themes' : { + 'name' : this.get_theme(), + 'icons' : this._data.core.themes.icons, + 'dots' : this._data.core.themes.dots + }, + */ + 'selected' : [] + } + }, i; + for(i in this._model.data) { + if(this._model.data.hasOwnProperty(i)) { + if(i !== $.jstree.root) { + if(this._model.data[i].state.loaded && this.settings.core.loaded_state) { + state.core.loaded.push(i); + } + if(this._model.data[i].state.opened) { + state.core.open.push(i); + } + if(this._model.data[i].state.selected) { + state.core.selected.push(i); + } + } + } + } + return state; + }, + /** + * sets the state of the tree. Used internally. + * @name set_state(state [, callback]) + * @private + * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it. + * @param {Function} callback an optional function to execute once the state is restored. + * @trigger set_state.jstree + */ + set_state : function (state, callback) { + if(state) { + if(state.core && state.core.selected && state.core.initial_selection === undefined) { + state.core.initial_selection = this._data.core.selected.concat([]).sort().join(','); + } + if(state.core) { + var res, n, t, _this, i; + if(state.core.loaded) { + if(!this.settings.core.loaded_state || !$.isArray(state.core.loaded) || !state.core.loaded.length) { + delete state.core.loaded; + this.set_state(state, callback); + } + else { + this._load_nodes(state.core.loaded, function (nodes) { + delete state.core.loaded; + this.set_state(state, callback); + }); + } + return false; + } + if(state.core.open) { + if(!$.isArray(state.core.open) || !state.core.open.length) { + delete state.core.open; + this.set_state(state, callback); + } + else { + this._load_nodes(state.core.open, function (nodes) { + this.open_node(nodes, false, 0); + delete state.core.open; + this.set_state(state, callback); + }); + } + return false; + } + if(state.core.scroll) { + if(state.core.scroll && state.core.scroll.left !== undefined) { + this.element.scrollLeft(state.core.scroll.left); + } + if(state.core.scroll && state.core.scroll.top !== undefined) { + this.element.scrollTop(state.core.scroll.top); + } + delete state.core.scroll; + this.set_state(state, callback); + return false; + } + if(state.core.selected) { + _this = this; + if (state.core.initial_selection === undefined || + state.core.initial_selection === this._data.core.selected.concat([]).sort().join(',') + ) { + this.deselect_all(); + $.each(state.core.selected, function (i, v) { + _this.select_node(v, false, true); + }); + } + delete state.core.initial_selection; + delete state.core.selected; + this.set_state(state, callback); + return false; + } + for(i in state) { + if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) { + delete state[i]; + } + } + if($.isEmptyObject(state.core)) { + delete state.core; + this.set_state(state, callback); + return false; + } + } + if($.isEmptyObject(state)) { + state = null; + if(callback) { callback.call(this); } + /** + * triggered when a `set_state` call completes + * @event + * @name set_state.jstree + */ + this.trigger('set_state'); + return false; + } + return true; + } + return false; + }, + /** + * refreshes the tree - all nodes are reloaded with calls to `load_node`. + * @name refresh() + * @param {Boolean} skip_loading an option to skip showing the loading indicator + * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state + * @trigger refresh.jstree + */ + refresh : function (skip_loading, forget_state) { + this._data.core.state = forget_state === true ? {} : this.get_state(); + if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); } + this._cnt = 0; + this._model.data = {}; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + this._data.core.selected = []; + this._data.core.last_clicked = null; + this._data.core.focused = null; + + var c = this.get_container_ul()[0].className; + if(!skip_loading) { + this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><"+"a class='jstree-anchor' href='#'>" + this.get_string("Loading ...") + ""); + this.element.attr('aria-activedescendant','j'+this._id+'_loading'); + } + this.load_node($.jstree.root, function (o, s) { + if(s) { + this.get_container_ul()[0].className = c; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + this.set_state($.extend(true, {}, this._data.core.state), function () { + /** + * triggered when a `refresh` call completes + * @event + * @name refresh.jstree + */ + this.trigger('refresh'); + }); + } + this._data.core.state = null; + }); + }, + /** + * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`. + * @name refresh_node(obj) + * @param {mixed} obj the node + * @trigger refresh_node.jstree + */ + refresh_node : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var opened = [], to_load = [], s = this._data.core.selected.concat([]); + to_load.push(obj.id); + if(obj.state.opened === true) { opened.push(obj.id); } + this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); }); + this._load_nodes(to_load, $.proxy(function (nodes) { + this.open_node(opened, false, 0); + this.select_node(s); + /** + * triggered when a node is refreshed + * @event + * @name refresh_node.jstree + * @param {Object} node - the refreshed node + * @param {Array} nodes - an array of the IDs of the nodes that were reloaded + */ + this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes }); + }, this), false, true); + }, + /** + * set (change) the ID of a node + * @name set_id(obj, id) + * @param {mixed} obj the node + * @param {String} id the new ID + * @return {Boolean} + * @trigger set_id.jstree + */ + set_id : function (obj, id) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var i, j, m = this._model.data, old = obj.id; + id = id.toString(); + // update parents (replace current ID with new one in children and children_d) + m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id; + for(i = 0, j = obj.parents.length; i < j; i++) { + m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id; + } + // update children (replace current ID with new one in parent and parents) + for(i = 0, j = obj.children.length; i < j; i++) { + m[obj.children[i]].parent = id; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id; + } + i = $.inArray(obj.id, this._data.core.selected); + if(i !== -1) { this._data.core.selected[i] = id; } + // update model and obj itself (obj.id, this._model.data[KEY]) + i = this.get_node(obj.id, true); + if(i) { + i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor'); + if(this.element.attr('aria-activedescendant') === obj.id) { + this.element.attr('aria-activedescendant', id); + } + } + delete m[obj.id]; + obj.id = id; + obj.li_attr.id = id; + m[id] = obj; + /** + * triggered when a node id value is changed + * @event + * @name set_id.jstree + * @param {Object} node + * @param {String} old the old id + */ + this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old }); + return true; + }, + /** + * get the text value of a node + * @name get_text(obj) + * @param {mixed} obj the node + * @return {String} + */ + get_text : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.text; + }, + /** + * set the text value of a node. Used internally, please use `rename_node(obj, val)`. + * @private + * @name set_text(obj, val) + * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes + * @param {String} val the new text value + * @return {Boolean} + * @trigger set_text.jstree + */ + set_text : function (obj, val) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_text(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + obj.text = val; + if(this.get_node(obj, true).length) { + this.redraw_node(obj.id); + } + /** + * triggered when a node text value is changed + * @event + * @name set_text.jstree + * @param {Object} obj + * @param {String} text the new value + */ + this.trigger('set_text',{ "obj" : obj, "text" : val }); + return true; + }, + /** + * gets a JSON representation of a node (or the whole tree) + * @name get_json([obj, options]) + * @param {mixed} obj + * @param {Object} options + * @param {Boolean} options.no_state do not return state information + * @param {Boolean} options.no_id do not return ID + * @param {Boolean} options.no_children do not include children + * @param {Boolean} options.no_data do not include node data + * @param {Boolean} options.no_li_attr do not include LI attributes + * @param {Boolean} options.no_a_attr do not include A attributes + * @param {Boolean} options.flat return flat JSON instead of nested + * @return {Object} + */ + get_json : function (obj, options, flat) { + obj = this.get_node(obj || $.jstree.root); + if(!obj) { return false; } + if(options && options.flat && !flat) { flat = []; } + var tmp = { + 'id' : obj.id, + 'text' : obj.text, + 'icon' : this.get_icon(obj), + 'li_attr' : $.extend(true, {}, obj.li_attr), + 'a_attr' : $.extend(true, {}, obj.a_attr), + 'state' : {}, + 'data' : options && options.no_data ? false : $.extend(true, $.isArray(obj.data)?[]:{}, obj.data) + //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ), + }, i, j; + if(options && options.flat) { + tmp.parent = obj.parent; + } + else { + tmp.children = []; + } + if(!options || !options.no_state) { + for(i in obj.state) { + if(obj.state.hasOwnProperty(i)) { + tmp.state[i] = obj.state[i]; + } + } + } else { + delete tmp.state; + } + if(options && options.no_li_attr) { + delete tmp.li_attr; + } + if(options && options.no_a_attr) { + delete tmp.a_attr; + } + if(options && options.no_id) { + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + } + if(options && options.flat && obj.id !== $.jstree.root) { + flat.push(tmp); + } + if(!options || !options.no_children) { + for(i = 0, j = obj.children.length; i < j; i++) { + if(options && options.flat) { + this.get_json(obj.children[i], options, flat); + } + else { + tmp.children.push(this.get_json(obj.children[i], options)); + } + } + } + return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp); + }, + /** + * create a new node (do not confuse with load_node) + * @name create_node([par, node, pos, callback, is_loaded]) + * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`) + * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name) + * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last" + * @param {Function} callback a function to be called once the node is created + * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded + * @return {String} the ID of the newly create node + * @trigger model.jstree, create_node.jstree + */ + create_node : function (par, node, pos, callback, is_loaded) { + if(par === null) { par = $.jstree.root; } + par = this.get_node(par); + if(!par) { return false; } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); }); + } + if(!node) { node = { "text" : this.get_string('New node') }; } + if(typeof node === "string") { + node = { "text" : node }; + } else { + node = $.extend(true, {}, node); + } + if(node.text === undefined) { node.text = this.get_string('New node'); } + var tmp, dpc, i, j; + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children); + par = tmp; + break; + case "after" : + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children) + 1; + par = tmp; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > par.children.length) { pos = par.children.length; } + if(!node.id) { node.id = true; } + if(!this.check("create_node", node, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, par.id, par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : par.id }); + + par.children_d = par.children_d.concat(dpc); + for(i = 0, j = par.parents.length; i < j; i++) { + this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc); + } + node = tmp; + tmp = []; + for(i = 0, j = par.children.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = par.children[i]; + } + tmp[pos] = node.id; + par.children = tmp; + + this.redraw_node(par, true); + /** + * triggered when a node is created + * @event + * @name create_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the new node among the parent's children + */ + this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos }); + if(callback) { callback.call(this, this.get_node(node)); } + return node.id; + }, + /** + * set the text value of a node + * @name rename_node(obj, val) + * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name + * @param {String} val the new text value + * @return {Boolean} + * @trigger rename_node.jstree + */ + rename_node : function (obj, val) { + var t1, t2, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.rename_node(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.text; + if(!this.check("rename_node", obj, this.get_parent(obj), val)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments)) + /** + * triggered when a node is renamed + * @event + * @name rename_node.jstree + * @param {Object} node + * @param {String} text the new value + * @param {String} old the old value + */ + this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old }); + return true; + }, + /** + * remove a node + * @name delete_node(obj) + * @param {mixed} obj the node, you can pass an array to delete multiple nodes + * @return {Boolean} + * @trigger delete_node.jstree, changed.jstree + */ + delete_node : function (obj) { + var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.delete_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + par = this.get_node(obj.parent); + pos = $.inArray(obj.id, par.children); + c = false; + if(!this.check("delete_node", obj, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(pos !== -1) { + par.children = $.vakata.array_remove(par.children, pos); + } + tmp = obj.children_d.concat([]); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + for(k = 0, l = tmp.length; k < l; k++) { + if(this._model.data[tmp[k]].state.selected) { + c = true; + break; + } + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + /** + * triggered when a node is deleted + * @event + * @name delete_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + */ + this.trigger('delete_node', { "node" : obj, "parent" : par.id }); + if(c) { + this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id }); + } + for(k = 0, l = tmp.length; k < l; k++) { + delete this._model.data[tmp[k]]; + } + if($.inArray(this._data.core.focused, tmp) !== -1) { + this._data.core.focused = null; + top = this.element[0].scrollTop; + lft = this.element[0].scrollLeft; + if(par.id === $.jstree.root) { + if (this._model.data[$.jstree.root].children[0]) { + this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus(); + } + } + else { + this.get_node(par, true).children('.jstree-anchor').focus(); + } + this.element[0].scrollTop = top; + this.element[0].scrollLeft = lft; + } + this.redraw_node(par, true); + return true; + }, + /** + * check if an operation is premitted on the tree. Used internally. + * @private + * @name check(chk, obj, par, pos) + * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node" + * @param {mixed} obj the node + * @param {mixed} par the parent + * @param {mixed} pos the position to insert at, or if "rename_node" - the new name + * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node + * @return {Boolean} + */ + check : function (chk, obj, par, pos, more) { + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj, + chc = this.settings.core.check_callback; + if(chk === "move_node" || chk === "copy_node") { + if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + } + if(tmp && tmp.data) { tmp = tmp.data; } + if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) { + if(tmp.functions[chk] === false) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return tmp.functions[chk]; + } + if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + return true; + }, + /** + * get the last error + * @name last_error() + * @return {Object} + */ + last_error : function () { + return this._data.core.last_error; + }, + /** + * move a node to a new parent + * @name move_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to move, pass an array to move multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger move_node.jstree + */ + move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1; + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(is_multi) { + if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) { + if(old_ins) { old_ins.delete_node(obj); } + return tmp; + } + return false; + } + //var m = this._model.data; + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(obj.parent === new_par.id) { + dpc = new_par.children.concat(); + tmp = $.inArray(obj.id, dpc); + if(tmp !== -1) { + dpc = $.vakata.array_remove(dpc, tmp); + if(pos > tmp) { pos--; } + } + tmp = []; + for(i = 0, j = dpc.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = dpc[i]; + } + tmp[pos] = obj.id; + new_par.children = tmp; + this._node_changed(new_par.id); + this.redraw(new_par.id === $.jstree.root); + } + else { + // clean old parent and up + tmp = obj.children_d.concat(); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + dpc = []; + p = old_ins._model.data[obj.parents[i]].children_d; + for(k = 0, l = p.length; k < l; k++) { + if($.inArray(p[k], tmp) === -1) { + dpc.push(p[k]); + } + } + old_ins._model.data[obj.parents[i]].children_d = dpc; + } + old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = obj.id; + new_par.children = dpc; + new_par.children_d.push(obj.id); + new_par.children_d = new_par.children_d.concat(obj.children_d); + + // update object + obj.parent = new_par.id; + tmp = new_par.parents.concat(); + tmp.unshift(new_par.id); + p = obj.parents.length; + obj.parents = tmp; + + // update object children + tmp = tmp.concat(); + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1); + Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp); + } + + if(old_par === $.jstree.root || new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(old_par); + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(); + } + } + if(callback) { callback.call(this, obj, new_par, pos); } + /** + * triggered when a node is moved + * @event + * @name move_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the old position of the node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return obj.id; + }, + /** + * copy a node to a new parent + * @name copy_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to copy, pass an array to copy multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger model.jstree copy_node.jstree + */ + copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj; + if(!node) { return false; } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; } + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : new_par.id }); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = tmp.id; + new_par.children = dpc; + new_par.children_d.push(tmp.id); + new_par.children_d = new_par.children_d.concat(tmp.children_d); + + if(new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(new_par.id === $.jstree.root); + } + if(callback) { callback.call(this, tmp, new_par, pos); } + /** + * triggered when a node is copied + * @event + * @name copy_node.jstree + * @param {Object} node the copied node + * @param {Object} original the original node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the position of the original node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return tmp.id; + }, + /** + * cut a node (a later call to `paste(obj)` would move the node) + * @name cut(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger cut.jstree + */ + cut : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'move_node'; + /** + * triggered when nodes are added to the buffer for moving + * @event + * @name cut.jstree + * @param {Array} node + */ + this.trigger('cut', { "node" : obj }); + }, + /** + * copy a node (a later call to `paste(obj)` would copy the node) + * @name copy(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger copy.jstree + */ + copy : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'copy_node'; + /** + * triggered when nodes are added to the buffer for copying + * @event + * @name copy.jstree + * @param {Array} node + */ + this.trigger('copy', { "node" : obj }); + }, + /** + * get the current buffer (any nodes that are waiting for a paste operation) + * @name get_buffer() + * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance) + */ + get_buffer : function () { + return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst }; + }, + /** + * check if there is something in the buffer to paste + * @name can_paste() + * @return {Boolean} + */ + can_paste : function () { + return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node]; + }, + /** + * copy or move the previously cut or copied nodes to a new parent + * @name paste(obj [, pos]) + * @param {mixed} obj the new parent + * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0` + * @trigger paste.jstree + */ + paste : function (obj, pos) { + obj = this.get_node(obj); + if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; } + if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) { + /** + * triggered when paste is invoked + * @event + * @name paste.jstree + * @param {String} parent the ID of the receiving node + * @param {Array} node the nodes in the buffer + * @param {String} mode the performed operation - "copy_node" or "move_node" + */ + this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode }); + } + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + }, + /** + * clear the buffer of previously copied or cut nodes + * @name clear_buffer() + * @trigger clear_buffer.jstree + */ + clear_buffer : function () { + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + /** + * triggered when the copy / cut buffer is cleared + * @event + * @name clear_buffer.jstree + */ + this.trigger('clear_buffer'); + }, + /** + * put a node in edit mode (input field to rename the node) + * @name edit(obj [, default_text, callback]) + * @param {mixed} obj + * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used) + * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise) and a boolean indicating if the user cancelled the edit. You can access the node's title using .text + */ + edit : function (obj, default_text, callback) { + var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false; + obj = this.get_node(obj); + if(!obj) { return false; } + if(!this.check("edit", obj, this.get_parent(obj))) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + tmp = obj; + default_text = typeof default_text === 'string' ? default_text : obj.text; + this.set_text(obj, ""); + obj = this._open_to(obj); + tmp.text = default_text; + + rtl = this._data.core.rtl; + w = this.element.width(); + this._data.core.focused = tmp.id; + a = obj.children('.jstree-anchor').focus(); + s = $(''); + /*! + oi = obj.children("i:visible"), + ai = a.children("i:visible"), + w1 = oi.width() * oi.length, + w2 = ai.width() * ai.length, + */ + t = default_text; + h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo(document.body); + h2 = $("<"+"input />", { + "value" : t, + "class" : "jstree-rename-input", + // "size" : t.length, + "css" : { + "padding" : "0", + "border" : "1px solid silver", + "box-sizing" : "border-box", + "display" : "inline-block", + "height" : (this._data.core.li_height) + "px", + "lineHeight" : (this._data.core.li_height) + "px", + "width" : "150px" // will be set a bit further down + }, + "blur" : $.proxy(function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + var i = s.children(".jstree-rename-input"), + v = i.val(), + f = this.settings.core.force_text, + nv; + if(v === "") { v = t; } + h1.remove(); + s.replaceWith(a); + s.remove(); + t = f ? t : $('
          ').append($.parseHTML(t)).html(); + obj = this.get_node(obj); + this.set_text(obj, t); + nv = !!this.rename_node(obj, f ? $('
          ').text(v).text() : $('
          ').append($.parseHTML(v)).html()); + if(!nv) { + this.set_text(obj, t); // move this up? and fix #483 + } + this._data.core.focused = tmp.id; + setTimeout($.proxy(function () { + var node = this.get_node(tmp.id, true); + if(node.length) { + this._data.core.focused = tmp.id; + node.children('.jstree-anchor').focus(); + } + }, this), 0); + if(callback) { + callback.call(this, tmp, nv, cancel); + } + h2 = null; + }, this), + "keydown" : function (e) { + var key = e.which; + if(key === 27) { + cancel = true; + this.value = t; + } + if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { + e.stopImmediatePropagation(); + } + if(key === 27 || key === 13) { + e.preventDefault(); + this.blur(); + } + }, + "click" : function (e) { e.stopImmediatePropagation(); }, + "mousedown" : function (e) { e.stopImmediatePropagation(); }, + "keyup" : function (e) { + h2.width(Math.min(h1.text("pW" + this.value).width(),w)); + }, + "keypress" : function(e) { + if(e.which === 13) { return false; } + } + }); + fn = { + fontFamily : a.css('fontFamily') || '', + fontSize : a.css('fontSize') || '', + fontWeight : a.css('fontWeight') || '', + fontStyle : a.css('fontStyle') || '', + fontStretch : a.css('fontStretch') || '', + fontVariant : a.css('fontVariant') || '', + letterSpacing : a.css('letterSpacing') || '', + wordSpacing : a.css('wordSpacing') || '' + }; + s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2); + a.replaceWith(s); + h1.css(fn); + h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); + $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) { + if (h2 && e.target !== h2) { + $(h2).blur(); + } + }); + }, + + + /** + * changes the theme + * @name set_theme(theme_name [, theme_url]) + * @param {String} theme_name the name of the new theme to apply + * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory. + * @trigger set_theme.jstree + */ + set_theme : function (theme_name, theme_url) { + if(!theme_name) { return false; } + if(theme_url === true) { + var dir = this.settings.core.themes.dir; + if(!dir) { dir = $.jstree.path + '/themes'; } + theme_url = dir + '/' + theme_name + '/style.css'; + } + if(theme_url && $.inArray(theme_url, themes_loaded) === -1) { + $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />'); + themes_loaded.push(theme_url); + } + if(this._data.core.themes.name) { + this.element.removeClass('jstree-' + this._data.core.themes.name); + } + this._data.core.themes.name = theme_name; + this.element.addClass('jstree-' + theme_name); + this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive'); + /** + * triggered when a theme is set + * @event + * @name set_theme.jstree + * @param {String} theme the new theme + */ + this.trigger('set_theme', { 'theme' : theme_name }); + }, + /** + * gets the name of the currently applied theme name + * @name get_theme() + * @return {String} + */ + get_theme : function () { return this._data.core.themes.name; }, + /** + * changes the theme variant (if the theme has variants) + * @name set_theme_variant(variant_name) + * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed) + */ + set_theme_variant : function (variant_name) { + if(this._data.core.themes.variant) { + this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + this._data.core.themes.variant = variant_name; + if(variant_name) { + this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + }, + /** + * gets the name of the currently applied theme variant + * @name get_theme() + * @return {String} + */ + get_theme_variant : function () { return this._data.core.themes.variant; }, + /** + * shows a striped background on the container (if the theme supports it) + * @name show_stripes() + */ + show_stripes : function () { + this._data.core.themes.stripes = true; + this.get_container_ul().addClass("jstree-striped"); + /** + * triggered when stripes are shown + * @event + * @name show_stripes.jstree + */ + this.trigger('show_stripes'); + }, + /** + * hides the striped background on the container + * @name hide_stripes() + */ + hide_stripes : function () { + this._data.core.themes.stripes = false; + this.get_container_ul().removeClass("jstree-striped"); + /** + * triggered when stripes are hidden + * @event + * @name hide_stripes.jstree + */ + this.trigger('hide_stripes'); + }, + /** + * toggles the striped background on the container + * @name toggle_stripes() + */ + toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } }, + /** + * shows the connecting dots (if the theme supports it) + * @name show_dots() + */ + show_dots : function () { + this._data.core.themes.dots = true; + this.get_container_ul().removeClass("jstree-no-dots"); + /** + * triggered when dots are shown + * @event + * @name show_dots.jstree + */ + this.trigger('show_dots'); + }, + /** + * hides the connecting dots + * @name hide_dots() + */ + hide_dots : function () { + this._data.core.themes.dots = false; + this.get_container_ul().addClass("jstree-no-dots"); + /** + * triggered when dots are hidden + * @event + * @name hide_dots.jstree + */ + this.trigger('hide_dots'); + }, + /** + * toggles the connecting dots + * @name toggle_dots() + */ + toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, + /** + * show the node icons + * @name show_icons() + */ + show_icons : function () { + this._data.core.themes.icons = true; + this.get_container_ul().removeClass("jstree-no-icons"); + /** + * triggered when icons are shown + * @event + * @name show_icons.jstree + */ + this.trigger('show_icons'); + }, + /** + * hide the node icons + * @name hide_icons() + */ + hide_icons : function () { + this._data.core.themes.icons = false; + this.get_container_ul().addClass("jstree-no-icons"); + /** + * triggered when icons are hidden + * @event + * @name hide_icons.jstree + */ + this.trigger('hide_icons'); + }, + /** + * toggle the node icons + * @name toggle_icons() + */ + toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }, + /** + * show the node ellipsis + * @name show_icons() + */ + show_ellipsis : function () { + this._data.core.themes.ellipsis = true; + this.get_container_ul().addClass("jstree-ellipsis"); + /** + * triggered when ellisis is shown + * @event + * @name show_ellipsis.jstree + */ + this.trigger('show_ellipsis'); + }, + /** + * hide the node ellipsis + * @name hide_ellipsis() + */ + hide_ellipsis : function () { + this._data.core.themes.ellipsis = false; + this.get_container_ul().removeClass("jstree-ellipsis"); + /** + * triggered when ellisis is hidden + * @event + * @name hide_ellipsis.jstree + */ + this.trigger('hide_ellipsis'); + }, + /** + * toggle the node ellipsis + * @name toggle_icons() + */ + toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } }, + /** + * set the node icon for a node + * @name set_icon(obj, icon) + * @param {mixed} obj + * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + */ + set_icon : function (obj, icon) { + var t1, t2, dom, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_icon(obj[t1], icon); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.icon; + obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon; + dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon"); + if(icon === false) { + dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); + this.hide_icon(obj); + } + else if(icon === true || icon === null || icon === undefined || icon === '') { + dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); + if(old === false) { this.show_icon(obj); } + } + else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) { + dom.removeClass(old).css("background",""); + dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + else { + dom.removeClass(old).css("background",""); + dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + return true; + }, + /** + * get the node icon for a node + * @name get_icon(obj) + * @param {mixed} obj + * @return {String} + */ + get_icon : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.icon; + }, + /** + * hide the icon on an individual node + * @name hide_icon(obj) + * @param {mixed} obj + */ + hide_icon : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + obj.icon = false; + this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden'); + return true; + }, + /** + * show the icon on an individual node + * @name show_icon(obj) + * @param {mixed} obj + */ + show_icon : function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + dom = this.get_node(obj, true); + obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true; + if(!obj.icon) { obj.icon = true; } + dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden'); + return true; + } + }; + + // helpers + $.vakata = {}; + // collect attributes + $.vakata.attributes = function(node, with_values) { + node = $(node)[0]; + var attr = with_values ? {} : []; + if(node && node.attributes) { + $.each(node.attributes, function (i, v) { + if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; } + if(v.value !== null && $.trim(v.value) !== '') { + if(with_values) { attr[v.name] = v.value; } + else { attr.push(v.name); } + } + }); + } + return attr; + }; + $.vakata.array_unique = function(array) { + var a = [], i, j, l, o = {}; + for(i = 0, l = array.length; i < l; i++) { + if(o[array[i]] === undefined) { + a.push(array[i]); + o[array[i]] = true; + } + } + return a; + }; + // remove item from array + $.vakata.array_remove = function(array, from) { + array.splice(from, 1); + return array; + //var rest = array.slice((to || from) + 1 || array.length); + //array.length = from < 0 ? array.length + from : from; + //array.push.apply(array, rest); + //return array; + }; + // remove item from array + $.vakata.array_remove_item = function(array, item) { + var tmp = $.inArray(item, array); + return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array; + }; + $.vakata.array_filter = function(c,a,b,d,e) { + if (c.filter) { + return c.filter(a, b); + } + d=[]; + for (e in c) { + if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) { + d.push(c[e]); + } + } + return d; + }; + + +/** + * ### Changed plugin + * + * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes. + */ + + $.jstree.plugins.changed = function (options, parent) { + var last = []; + this.trigger = function (ev, data) { + var i, j; + if(!data) { + data = {}; + } + if(ev.replace('.jstree','') === 'changed') { + data.changed = { selected : [], deselected : [] }; + var tmp = {}; + for(i = 0, j = last.length; i < j; i++) { + tmp[last[i]] = 1; + } + for(i = 0, j = data.selected.length; i < j; i++) { + if(!tmp[data.selected[i]]) { + data.changed.selected.push(data.selected[i]); + } + else { + tmp[data.selected[i]] = 2; + } + } + for(i = 0, j = last.length; i < j; i++) { + if(tmp[last[i]] === 1) { + data.changed.deselected.push(last[i]); + } + } + last = data.selected.slice(); + } + /** + * triggered when selection changes (the "changed" plugin enhances the original event with more data) + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event + * @param {Object} event the event (if any) that triggered this changed event + * @plugin changed + */ + parent.trigger.call(this, ev, data); + }; + this.refresh = function (skip_loading, forget_state) { + last = []; + return parent.refresh.apply(this, arguments); + }; + }; + +/** + * ### Checkbox plugin + * + * This plugin renders checkbox icons in front of each node, making multiple selection much easier. + * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up. + */ + + var _i = document.createElement('I'); + _i.className = 'jstree-icon jstree-checkbox'; + _i.setAttribute('role', 'presentation'); + /** + * stores all defaults for the checkbox plugin + * @name $.jstree.defaults.checkbox + * @plugin checkbox + */ + $.jstree.defaults.checkbox = { + /** + * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + visible : true, + /** + * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`. + * @name $.jstree.defaults.checkbox.three_state + * @plugin checkbox + */ + three_state : true, + /** + * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`. + * @name $.jstree.defaults.checkbox.whole_node + * @plugin checkbox + */ + whole_node : true, + /** + * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`. + * @name $.jstree.defaults.checkbox.keep_selected_style + * @plugin checkbox + */ + keep_selected_style : true, + /** + * This setting controls how cascading and undetermined nodes are applied. + * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used. + * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''. + * @name $.jstree.defaults.checkbox.cascade + * @plugin checkbox + */ + cascade : '', + /** + * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing. + * @name $.jstree.defaults.checkbox.tie_selection + * @plugin checkbox + */ + tie_selection : true, + + /** + * This setting controls if cascading down affects disabled checkboxes + * @name $.jstree.defaults.checkbox.cascade_to_disabled + * @plugin checkbox + */ + cascade_to_disabled : true, + + /** + * This setting controls if cascading down affects hidden checkboxes + * @name $.jstree.defaults.checkbox.cascade_to_hidden + * @plugin checkbox + */ + cascade_to_hidden : true + }; + $.jstree.plugins.checkbox = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this._data.checkbox.uto = false; + this._data.checkbox.selected = []; + if(this.settings.checkbox.three_state) { + this.settings.checkbox.cascade = 'up+down+undetermined'; + } + this.element + .on("init.jstree", $.proxy(function () { + this._data.checkbox.visible = this.settings.checkbox.visible; + if(!this.settings.checkbox.keep_selected_style) { + this.element.addClass('jstree-checkbox-no-clicked'); + } + if(this.settings.checkbox.tie_selection) { + this.element.addClass('jstree-checkbox-selection'); + } + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ](); + }, this)); + if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + this.element + .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () { + // only if undetermined is in setting + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + }, this)); + } + if(!this.settings.checkbox.tie_selection) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + i, j; + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked); + if(m[dpc[i]].state.checked) { + this._data.checkbox.selected.push(dpc[i]); + } + } + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + chd = [], + c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection; + + if(s.indexOf('down') !== -1) { + // apply down + if(p.state[ t ? 'selected' : 'checked' ]) { + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true; + } + + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc); + } + else { + for(i = 0, j = dpc.length; i < j; i++) { + if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) { + for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) { + m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true; + } + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d); + } + } + } + } + + if(s.indexOf('up') !== -1) { + // apply up + for(i = 0, j = p.children_d.length; i < j; i++) { + if(!m[p.children_d[i]].children.length) { + chd.push(m[p.children_d[i]].parent); + } + } + chd = $.vakata.array_unique(chd); + for(k = 0, l = chd.length; k < l; k++) { + p = m[chd[k]]; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + } + + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected); + }, this)) + .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) { + var self = this, + obj = data.node, + m = this._model.data, + par = this.get_node(obj.parent), + i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected; + + for (i = 0, j = cur.length; i < j; i++) { + sel[cur[i]] = true; + } + + // apply down + if(s.indexOf('down') !== -1) { + //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d)); + var selectedIds = this._cascade_new_checked_state(obj.id, true); + var temp = obj.children_d.concat(obj.id); + for (i = 0, j = temp.length; i < j; i++) { + if (selectedIds.indexOf(temp[i]) > -1) { + sel[temp[i]] = true; + } + else { + delete sel[temp[i]]; + } + } + } + + // apply up + if(s.indexOf('up') !== -1) { + while(par && par.id !== $.jstree.root) { + c = 0; + for(i = 0, j = par.children.length; i < j; i++) { + c += m[par.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + par.state[ t ? 'selected' : 'checked' ] = true; + sel[par.id] = true; + //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id); + tmp = this.get_node(par, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + par = this.get_node(par.parent); + } + } + + cur = []; + for (i in sel) { + if (sel.hasOwnProperty(i)) { + cur.push(i); + } + } + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) { + var obj = this.get_node($.jstree.root), + m = this._model.data, + i, j, tmp; + for(i = 0, j = obj.children_d.length; i < j; i++) { + tmp = m[obj.children_d[i]]; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) { + var self = this, + obj = data.node, + dom = this.get_node(obj, true), + i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {}, + stillSelectedIds = [], + allIds = obj.children_d.concat(obj.id); + + // apply down + if(s.indexOf('down') !== -1) { + var selectedIds = this._cascade_new_checked_state(obj.id, false); + + cur = cur.filter(function(id) { + return allIds.indexOf(id) === -1 || selectedIds.indexOf(id) > -1; + }); + } + + // only apply up if cascade up is enabled and if this node is not selected + // (if all child nodes are disabled and cascade_to_disabled === false then this node will till be selected). + if(s.indexOf('up') !== -1 && cur.indexOf(obj.id) === -1) { + for(i = 0, j = obj.parents.length; i < j; i++) { + tmp = this._model.data[obj.parents[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = false; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + tmp = this.get_node(obj.parents[i], true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + + cur = cur.filter(function(id) { + return obj.parents.indexOf(id) === -1; + }); + } + + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1) { + this.element + .on('delete_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var p = this.get_node(data.parent), + m = this._model.data, + i, j, c, tmp, t = this.settings.checkbox.tie_selection; + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + }, this)) + .on('move_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var is_multi = data.is_multi, + old_par = data.old_parent, + new_par = this.get_node(data.parent), + m = this._model.data, + p, c, i, j, tmp, t = this.settings.checkbox.tie_selection; + if(!is_multi) { + p = this.get_node(old_par); + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + p = new_par; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + if(!p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + } + else { + if(p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = false; + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + } + p = this.get_node(p.parent); + } + }, this)); + } + }; + /** + * get an array of all nodes whose state is "undetermined" + * @name get_undetermined([full]) + * @param {boolean} full: if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_undetermined = function (full) { + if (this.settings.checkbox.cascade.indexOf('undetermined') === -1) { + return []; + } + var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this, r = []; + for(i = 0, j = s.length; i < j; i++) { + if(m[s[i]] && m[s[i]].parents) { + for(k = 0, l = m[s[i]].parents.length; k < l; k++) { + if(o[m[s[i]].parents[k]] !== undefined) { + break; + } + if(m[s[i]].parents[k] !== $.jstree.root) { + o[m[s[i]].parents[k]] = true; + p.push(m[s[i]].parents[k]); + } + } + } + } + // attempt for server side undetermined state + this.element.find('.jstree-closed').not(':has(.jstree-children)') + .each(function () { + var tmp = tt.get_node(this), tmp2; + + if(!tmp) { return; } + + if(!tmp.state.loaded) { + if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) { + if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) { + o[tmp.id] = true; + p.push(tmp.id); + } + for(k = 0, l = tmp.parents.length; k < l; k++) { + if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) { + o[tmp.parents[k]] = true; + p.push(tmp.parents[k]); + } + } + } + } + else { + for(i = 0, j = tmp.children_d.length; i < j; i++) { + tmp2 = m[tmp.children_d[i]]; + if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) { + if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) { + o[tmp2.id] = true; + p.push(tmp2.id); + } + for(k = 0, l = tmp2.parents.length; k < l; k++) { + if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) { + o[tmp2.parents[k]] = true; + p.push(tmp2.parents[k]); + } + } + } + } + } + }); + for (i = 0, j = p.length; i < j; i++) { + if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) { + r.push(full ? m[p[i]] : p[i]); + } + } + return r; + }; + /** + * set the undetermined state where and if necessary. Used internally. + * @private + * @name _undetermined() + * @plugin checkbox + */ + this._undetermined = function () { + if(this.element === null) { return; } + var p = this.get_undetermined(false), i, j, s; + + this.element.find('.jstree-undetermined').removeClass('jstree-undetermined'); + for (i = 0, j = p.length; i < j; i++) { + s = this.get_node(p[i], true); + if(s && s.length) { + s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined'); + } + } + }; + this.redraw_node = function(obj, deep, is_callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var i, j, tmp = null, icon = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; } + icon = _i.cloneNode(false); + if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; } + tmp.insertBefore(icon, tmp.childNodes[0]); + } + } + if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + } + return obj; + }; + /** + * show the node checkbox icons + * @name show_checkboxes() + * @plugin checkbox + */ + this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); }; + /** + * hide the node checkbox icons + * @name hide_checkboxes() + * @plugin checkbox + */ + this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); }; + /** + * toggle the node icons + * @name toggle_checkboxes() + * @plugin checkbox + */ + this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } }; + /** + * checks if a node is in an undetermined state + * @name is_undetermined(obj) + * @param {mixed} obj + * @return {Boolean} + */ + this.is_undetermined = function (obj) { + obj = this.get_node(obj); + var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data; + if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) { + return false; + } + if(!obj.state.loaded && obj.original.state.undetermined === true) { + return true; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) { + return true; + } + } + return false; + }; + /** + * disable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger disable_checkbox.jstree + * @plugin checkbox + */ + this.disable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = true; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is disabled + * @event + * @name disable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('disable_checkbox', { 'node' : obj }); + } + }; + /** + * enable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger enable_checkbox.jstree + * @plugin checkbox + */ + this.enable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = false; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is enabled + * @event + * @name enable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('enable_checkbox', { 'node' : obj }); + } + }; + + this.activate_node = function (obj, e) { + if($(e.target).hasClass('jstree-checkbox-disabled')) { + return false; + } + if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) { + e.ctrlKey = true; + } + if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) { + return parent.activate_node.call(this, obj, e); + } + if(this.is_disabled(obj)) { + return false; + } + if(this.is_checked(obj)) { + this.uncheck_node(obj, e); + } + else { + this.check_node(obj, e); + } + this.trigger('activate_node', { 'node' : this.get_node(obj) }); + }; + + /** + * Cascades checked state to a node and all its descendants. This function does NOT affect hidden and disabled nodes (or their descendants). + * However if these unaffected nodes are already selected their ids will be included in the returned array. + * @private + * @param {string} id the node ID + * @param {bool} checkedState should the nodes be checked or not + * @returns {Array} Array of all node id's (in this tree branch) that are checked. + */ + this._cascade_new_checked_state = function (id, checkedState) { + var self = this; + var t = this.settings.checkbox.tie_selection; + var node = this._model.data[id]; + var selectedNodeIds = []; + var selectedChildrenIds = [], i, j, selectedChildIds; + + if ( + (this.settings.checkbox.cascade_to_disabled || !node.state.disabled) && + (this.settings.checkbox.cascade_to_hidden || !node.state.hidden) + ) { + //First try and check/uncheck the children + if (node.children) { + for (i = 0, j = node.children.length; i < j; i++) { + var childId = node.children[i]; + selectedChildIds = self._cascade_new_checked_state(childId, checkedState); + selectedNodeIds = selectedNodeIds.concat(selectedChildIds); + if (selectedChildIds.indexOf(childId) > -1) { + selectedChildrenIds.push(childId); + } + } + } + + var dom = self.get_node(node, true); + + //A node's state is undetermined if some but not all of it's children are checked/selected . + var undetermined = selectedChildrenIds.length > 0 && selectedChildrenIds.length < node.children.length; + + if(node.original && node.original.state && node.original.state.undetermined) { + node.original.state.undetermined = undetermined; + } + + //If a node is undetermined then remove selected class + if (undetermined) { + node.state[ t ? 'selected' : 'checked' ] = false; + dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + //Otherwise, if the checkedState === true (i.e. the node is being checked now) and all of the node's children are checked (if it has any children), + //check the node and style it correctly. + else if (checkedState && selectedChildrenIds.length === node.children.length) { + node.state[ t ? 'selected' : 'checked' ] = checkedState; + selectedNodeIds.push(node.id); + + dom.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + else { + node.state[ t ? 'selected' : 'checked' ] = false; + dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + selectedChildIds = this.get_checked_descendants(id); + + if (node.state[ t ? 'selected' : 'checked' ]) { + selectedChildIds.push(node.id); + } + + selectedNodeIds = selectedNodeIds.concat(selectedChildIds); + } + + return selectedNodeIds; + }; + + /** + * Gets ids of nodes selected in branch (of tree) specified by id (does not include the node specified by id) + * @name get_checked_descendants(obj) + * @param {string} id the node ID + * @return {Array} array of IDs + * @plugin checkbox + */ + this.get_checked_descendants = function (id) { + var self = this; + var t = self.settings.checkbox.tie_selection; + var node = self._model.data[id]; + + return node.children_d.filter(function(_id) { + return self._model.data[_id].state[ t ? 'selected' : 'checked' ]; + }); + }; + + /** + * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally) + * @name check_node(obj) + * @param {mixed} obj an array can be used to check multiple nodes + * @trigger check_node.jstree + * @plugin checkbox + */ + this.check_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); } + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.check_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checked) { + obj.state.checked = true; + this._data.checkbox.selected.push(obj.id); + if(dom && dom.length) { + dom.children('.jstree-anchor').addClass('jstree-checked'); + } + /** + * triggered when an node is checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this check_node + * @plugin checkbox + */ + this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + /** + * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally) + * @name uncheck_node(obj) + * @param {mixed} obj an array can be used to uncheck multiple nodes + * @trigger uncheck_node.jstree + * @plugin checkbox + */ + this.uncheck_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); } + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.uncheck_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checked) { + obj.state.checked = false; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id); + if(dom.length) { + dom.children('.jstree-anchor').removeClass('jstree-checked'); + } + /** + * triggered when an node is unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this uncheck_node + * @plugin checkbox + */ + this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + + /** + * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally) + * @name check_all() + * @trigger check_all.jstree, changed.jstree + * @plugin checkbox + */ + this.check_all = function () { + if(this.settings.checkbox.tie_selection) { return this.select_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_all.jstree + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('check_all', { 'selected' : this._data.checkbox.selected }); + }; + /** + * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally) + * @name uncheck_all() + * @trigger uncheck_all.jstree + * @plugin checkbox + */ + this.uncheck_all = function () { + if(this.settings.checkbox.tie_selection) { return this.deselect_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = false; + } + } + this._data.checkbox.selected = []; + this.element.find('.jstree-checked').removeClass('jstree-checked'); + /** + * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp }); + }; + /** + * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected) + * @name is_checked(obj) + * @param {mixed} obj + * @return {Boolean} + * @plugin checkbox + */ + this.is_checked = function (obj) { + if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + return obj.state.checked; + }; + /** + * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected) + * @name get_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_selected(full); } + return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected; + }; + /** + * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected) + * @name get_top_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_top_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); } + var tmp = this.get_checked(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }; + /** + * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected) + * @name get_bottom_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_bottom_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); } + var tmp = this.get_checked(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }; + this.load_node = function (obj, callback) { + var k, l, i, j, c, tmp; + if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) { + tmp = this.get_node(obj); + if(tmp && tmp.state.loaded) { + for(k = 0, l = tmp.children_d.length; k < l; k++) { + if(this._model.data[tmp.children_d[k]].state.checked) { + c = true; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]); + } + } + } + } + return parent.load_node.apply(this, arguments); + }; + this.get_state = function () { + var state = parent.get_state.apply(this, arguments); + if(this.settings.checkbox.tie_selection) { return state; } + state.checkbox = this._data.checkbox.selected.slice(); + return state; + }; + this.set_state = function (state, callback) { + var res = parent.set_state.apply(this, arguments); + if(res && state.checkbox) { + if(!this.settings.checkbox.tie_selection) { + this.uncheck_all(); + var _this = this; + $.each(state.checkbox, function (i, v) { + _this.check_node(v); + }); + } + delete state.checkbox; + this.set_state(state, callback); + return false; + } + return res; + }; + this.refresh = function (skip_loading, forget_state) { + if(this.settings.checkbox.tie_selection) { + this._data.checkbox.selected = []; + } + return parent.refresh.apply(this, arguments); + }; + }; + + // include the checkbox plugin by default + // $.jstree.defaults.plugins.push("checkbox"); + + +/** + * ### Conditionalselect plugin + * + * This plugin allows defining a callback to allow or deny node selection by user input (activate node method). + */ + + /** + * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + $.jstree.defaults.conditionalselect = function () { return true; }; + $.jstree.plugins.conditionalselect = function (options, parent) { + // own function + this.activate_node = function (obj, e) { + if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) { + return parent.activate_node.call(this, obj, e); + } + }; + }; + + +/** + * ### Contextmenu plugin + * + * Shows a context menu when a node is right-clicked. + */ + + /** + * stores all defaults for the contextmenu plugin + * @name $.jstree.defaults.contextmenu + * @plugin contextmenu + */ + $.jstree.defaults.contextmenu = { + /** + * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. + * @name $.jstree.defaults.contextmenu.select_node + * @plugin contextmenu + */ + select_node : true, + /** + * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. + * @name $.jstree.defaults.contextmenu.show_at_node + * @plugin contextmenu + */ + show_at_node : true, + /** + * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). + * + * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. + * + * * `separator_before` - a boolean indicating if there should be a separator before this item + * * `separator_after` - a boolean indicating if there should be a separator after this item + * * `_disabled` - a boolean indicating if this action should be disabled + * * `label` - a string - the name of the action (could be a function returning a string) + * * `title` - a string - an optional tooltip for the item + * * `action` - a function to be executed if this item is chosen, the function will receive + * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) + * * `shortcut_label` - shortcut label (like for example `F2` for rename) + * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered + * + * @name $.jstree.defaults.contextmenu.items + * @plugin contextmenu + */ + items : function (o, cb) { // Could be an object directly + return { + "create" : { + "separator_before" : false, + "separator_after" : true, + "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), + "label" : "Create", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.create_node(obj, {}, "last", function (new_node) { + try { + inst.edit(new_node); + } catch (ex) { + setTimeout(function () { inst.edit(new_node); },0); + } + }); + } + }, + "rename" : { + "separator_before" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Rename", + /*! + "shortcut" : 113, + "shortcut_label" : 'F2', + "icon" : "glyphicon glyphicon-leaf", + */ + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.edit(obj); + } + }, + "remove" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Delete", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.delete_node(inst.get_selected()); + } + else { + inst.delete_node(obj); + } + } + }, + "ccp" : { + "separator_before" : true, + "icon" : false, + "separator_after" : false, + "label" : "Edit", + "action" : false, + "submenu" : { + "cut" : { + "separator_before" : false, + "separator_after" : false, + "label" : "Cut", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.cut(inst.get_top_selected()); + } + else { + inst.cut(obj); + } + } + }, + "copy" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "label" : "Copy", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.copy(inst.get_top_selected()); + } + else { + inst.copy(obj); + } + } + }, + "paste" : { + "separator_before" : false, + "icon" : false, + "_disabled" : function (data) { + return !$.jstree.reference(data.reference).can_paste(); + }, + "separator_after" : false, + "label" : "Paste", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.paste(obj); + } + } + } + } + }; + } + }; + + $.jstree.plugins.contextmenu = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + var last_ts = 0, cto = null, ex, ey; + this.element + .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { + this.get_container_ul().addClass('jstree-contextmenu'); + }, this)) + .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) { + if (e.target.tagName.toLowerCase() === 'input') { + return; + } + e.preventDefault(); + last_ts = e.ctrlKey ? +new Date() : 0; + if(data || cto) { + last_ts = (+new Date()) + 10000; + } + if(cto) { + clearTimeout(cto); + } + if(!this.is_loading(e.currentTarget)) { + this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click + $.vakata.context.hide(); + } + last_ts = 0; + }, this)) + .on("touchstart.jstree", ".jstree-anchor", function (e) { + if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { + return; + } + ex = e.originalEvent.changedTouches[0].clientX; + ey = e.originalEvent.changedTouches[0].clientY; + cto = setTimeout(function () { + $(e.currentTarget).trigger('contextmenu', true); + }, 750); + }) + .on('touchmove.vakata.jstree', function (e) { + if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 10 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 10)) { + clearTimeout(cto); + $.vakata.context.hide(); + } + }) + .on('touchend.vakata.jstree', function (e) { + if(cto) { + clearTimeout(cto); + } + }); + + /*! + if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { + var el = null, tm = null; + this.element + .on("touchstart", ".jstree-anchor", function (e) { + el = e.currentTarget; + tm = +new Date(); + $(document).one("touchend", function (e) { + e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); + e.currentTarget = e.target; + tm = ((+(new Date())) - tm); + if(e.target === el && tm > 600 && tm < 1000) { + e.preventDefault(); + $(el).trigger('contextmenu', e); + } + el = null; + tm = null; + }); + }); + } + */ + $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) { + this._data.contextmenu.visible = false; + $(data.reference).removeClass('jstree-context'); + }, this)); + }; + this.teardown = function () { + if(this._data.contextmenu.visible) { + $.vakata.context.hide(); + } + parent.teardown.call(this); + }; + + /** + * prepare and show the context menu for a node + * @name show_contextmenu(obj [, x, y]) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Object} e the event if available that triggered the contextmenu + * @plugin contextmenu + * @trigger show_contextmenu.jstree + */ + this.show_contextmenu = function (obj, x, y, e) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var s = this.settings.contextmenu, + d = this.get_node(obj, true), + a = d.children(".jstree-anchor"), + o = false, + i = false; + if(s.show_at_node || x === undefined || y === undefined) { + o = a.offset(); + x = o.left; + y = o.top + this._data.core.li_height; + } + if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { + this.activate_node(obj, e); + } + + i = s.items; + if($.isFunction(i)) { + i = i.call(this, obj, $.proxy(function (i) { + this._show_contextmenu(obj, x, y, i); + }, this)); + } + if($.isPlainObject(i)) { + this._show_contextmenu(obj, x, y, i); + } + }; + /** + * show the prepared context menu for a node + * @name _show_contextmenu(obj, x, y, i) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Number} i the object of items to show + * @plugin contextmenu + * @trigger show_contextmenu.jstree + * @private + */ + this._show_contextmenu = function (obj, x, y, i) { + var d = this.get_node(obj, true), + a = d.children(".jstree-anchor"); + $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) { + var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; + $(data.element).addClass(cls); + a.addClass('jstree-context'); + }, this)); + this._data.contextmenu.visible = true; + $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); + /** + * triggered when the contextmenu is shown for a node + * @event + * @name show_contextmenu.jstree + * @param {Object} node the node + * @param {Number} x the x-coordinate of the menu relative to the document + * @param {Number} y the y-coordinate of the menu relative to the document + * @plugin contextmenu + */ + this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); + }; + }; + + // contextmenu helper + (function ($) { + var right_to_left = false, + vakata_context = { + element : false, + reference : false, + position_x : 0, + position_y : 0, + items : [], + html : "", + is_visible : false + }; + + $.vakata.context = { + settings : { + hide_onmouseleave : 0, + icons : true + }, + _trigger : function (event_name) { + $(document).triggerHandler("context_" + event_name + ".vakata", { + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }); + }, + _execute : function (i) { + i = vakata_context.items[i]; + return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { + "item" : i, + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }) : false; + }, + _parse : function (o, is_callback) { + if(!o) { return false; } + if(!is_callback) { + vakata_context.html = ""; + vakata_context.items = []; + } + var str = "", + sep = false, + tmp; + + if(is_callback) { str += "<"+"ul>"; } + $.each(o, function (i, val) { + if(!val) { return true; } + vakata_context.items.push(val); + if(!sep && val.separator_before) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + } + sep = false; + str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; + str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; + if($.vakata.context.settings.icons) { + str += "<"+"i "; + if(val.icon) { + if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } + else { str += " class='" + val.icon + "' "; } + } + str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; + } + str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' '+ (val.shortcut_label || '') +'':'') + "<"+"/a>"; + if(val.submenu) { + tmp = $.vakata.context._parse(val.submenu, true); + if(tmp) { str += tmp; } + } + str += "<"+"/li>"; + if(val.separator_after) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + sep = true; + } + }); + str = str.replace(/
        • <\/li\>$/,""); + if(is_callback) { str += ""; } + /** + * triggered on the document when the contextmenu is parsed (HTML is built) + * @event + * @plugin contextmenu + * @name context_parse.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } + return str.length > 10 ? str : false; + }, + _show_submenu : function (o) { + o = $(o); + if(!o.length || !o.children("ul").length) { return; } + var e = o.children("ul"), + xl = o.offset().left, + x = xl + o.outerWidth(), + y = o.offset().top, + w = e.width(), + h = e.height(), + dw = $(window).width() + $(window).scrollLeft(), + dh = $(window).height() + $(window).scrollTop(); + // може да се спести е една проверка - дали няма някой от класовете вече нагоре + if(right_to_left) { + o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); + } + else { + o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); + } + if(y + h + 10 > dh) { + e.css("bottom","-1px"); + } + + //if does not fit - stick it to the side + if (o.hasClass('vakata-context-right')) { + if (xl < w) { + e.css("margin-right", xl - w); + } + } else { + if (dw - x < w) { + e.css("margin-left", dw - x - w); + } + } + + e.show(); + }, + show : function (reference, position, data) { + var o, e, x, y, w, h, dw, dh, cond = true; + if(vakata_context.element && vakata_context.element.length) { + vakata_context.element.width(''); + } + switch(cond) { + case (!position && !reference): + return false; + case (!!position && !!reference): + vakata_context.reference = reference; + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + case (!position && !!reference): + vakata_context.reference = reference; + o = reference.offset(); + vakata_context.position_x = o.left + reference.outerHeight(); + vakata_context.position_y = o.top; + break; + case (!!position && !reference): + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + } + if(!!reference && !data && $(reference).data('vakata_contextmenu')) { + data = $(reference).data('vakata_contextmenu'); + } + if($.vakata.context._parse(data)) { + vakata_context.element.html(vakata_context.html); + } + if(vakata_context.items.length) { + vakata_context.element.appendTo(document.body); + e = vakata_context.element; + x = vakata_context.position_x; + y = vakata_context.position_y; + w = e.width(); + h = e.height(); + dw = $(window).width() + $(window).scrollLeft(); + dh = $(window).height() + $(window).scrollTop(); + if(right_to_left) { + x -= (e.outerWidth() - $(reference).outerWidth()); + if(x < $(window).scrollLeft() + 20) { + x = $(window).scrollLeft() + 20; + } + } + if(x + w + 20 > dw) { + x = dw - (w + 20); + } + if(y + h + 20 > dh) { + y = dh - (h + 20); + } + + vakata_context.element + .css({ "left" : x, "top" : y }) + .show() + .find('a').first().focus().parent().addClass("vakata-context-hover"); + vakata_context.is_visible = true; + /** + * triggered on the document when the contextmenu is shown + * @event + * @plugin contextmenu + * @name context_show.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("show"); + } + }, + hide : function () { + if(vakata_context.is_visible) { + vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach(); + vakata_context.is_visible = false; + /** + * triggered on the document when the contextmenu is hidden + * @event + * @plugin contextmenu + * @name context_hide.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("hide"); + } + } + }; + $(function () { + right_to_left = $(document.body).css("direction") === "rtl"; + var to = false; + + vakata_context.element = $("
            "); + vakata_context.element + .on("mouseenter", "li", function (e) { + e.stopImmediatePropagation(); + + if($.contains(this, e.relatedTarget)) { + // премахнато заради delegate mouseleave по-долу + // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + return; + } + + if(to) { clearTimeout(to); } + vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); + + $(this) + .siblings().find("ul").hide().end().end() + .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); + $.vakata.context._show_submenu(this); + }) + // тестово - дали не натоварва? + .on("mouseleave", "li", function (e) { + if($.contains(this, e.relatedTarget)) { return; } + $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); + }) + .on("mouseleave", function (e) { + $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + if($.vakata.context.settings.hide_onmouseleave) { + to = setTimeout( + (function (t) { + return function () { $.vakata.context.hide(); }; + }(this)), $.vakata.context.settings.hide_onmouseleave); + } + }) + .on("click", "a", function (e) { + e.preventDefault(); + //}) + //.on("mouseup", "a", function (e) { + if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { + $.vakata.context.hide(); + } + }) + .on('keydown', 'a', function (e) { + var o = null; + switch(e.which) { + case 13: + case 32: + e.type = "click"; + e.preventDefault(); + $(e.currentTarget).trigger(e); + break; + case 37: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 38: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 39: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 40: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 27: + $.vakata.context.hide(); + e.preventDefault(); + break; + default: + //console.log(e.which); + break; + } + }) + .on('keydown', function (e) { + e.preventDefault(); + var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); + if(a.parent().not('.vakata-context-disabled')) { + a.click(); + } + }); + + $(document) + .on("mousedown.vakata.jstree", function (e) { + if(vakata_context.is_visible && vakata_context.element[0] !== e.target && !$.contains(vakata_context.element[0], e.target)) { + $.vakata.context.hide(); + } + }) + .on("context_show.vakata.jstree", function (e, data) { + vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); + if(right_to_left) { + vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); + } + // also apply a RTL class? + vakata_context.element.find("ul").hide().end(); + }); + }); + }($)); + // $.jstree.defaults.plugins.push("contextmenu"); + + +/** + * ### Drag'n'drop plugin + * + * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. + */ + + /** + * stores all defaults for the drag'n'drop plugin + * @name $.jstree.defaults.dnd + * @plugin dnd + */ + $.jstree.defaults.dnd = { + /** + * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. + * @name $.jstree.defaults.dnd.copy + * @plugin dnd + */ + copy : true, + /** + * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. + * @name $.jstree.defaults.dnd.open_timeout + * @plugin dnd + */ + open_timeout : 500, + /** + * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging + * @name $.jstree.defaults.dnd.is_draggable + * @plugin dnd + */ + is_draggable : true, + /** + * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` + * @name $.jstree.defaults.dnd.check_while_dragging + * @plugin dnd + */ + check_while_dragging : true, + /** + * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` + * @name $.jstree.defaults.dnd.always_copy + * @plugin dnd + */ + always_copy : false, + /** + * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` + * @name $.jstree.defaults.dnd.inside_pos + * @plugin dnd + */ + inside_pos : 0, + /** + * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node + * @name $.jstree.defaults.dnd.drag_selection + * @plugin dnd + */ + drag_selection : true, + /** + * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. + * @name $.jstree.defaults.dnd.touch + * @plugin dnd + */ + touch : true, + /** + * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. + * @name $.jstree.defaults.dnd.large_drop_target + * @plugin dnd + */ + large_drop_target : false, + /** + * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". + * @name $.jstree.defaults.dnd.large_drag_target + * @plugin dnd + */ + large_drag_target : false, + /** + * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. + * @reference http://caniuse.com/#feat=dragndrop + * @name $.jstree.defaults.dnd.use_html5 + * @plugin dnd + */ + use_html5: false + }; + var drg, elm; + // TODO: now check works by checking for each node individually, how about max_children, unique, etc? + $.jstree.plugins.dnd = function (options, parent) { + this.init = function (el, options) { + parent.init.call(this, el, options); + this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); + }; + this.bind = function () { + parent.bind.call(this); + + this.element + .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { + return true; + } + if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { + return true; + } + var obj = this.get_node(e.target), + mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, + txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); + if(this.settings.core.force_text) { + txt = $.vakata.html.escape(txt); + } + if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && + (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) + ) { + drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; + elm = e.currentTarget; + if (this.settings.dnd.use_html5) { + $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); + } else { + this.element.trigger('mousedown.jstree'); + return $.vakata.dnd.start(e, drg, '
            ' + txt + '
            '); + } + } + }, this)); + if (this.settings.dnd.use_html5) { + this.element + .on('dragover.jstree', function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }) + //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + // e.preventDefault(); + // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + // return false; + // }, this)) + .on('drop.jstree', $.proxy(function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }, this)); + } + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if (obj && this.settings.dnd.use_html5) { + if (this.settings.dnd.large_drag_target) { + obj.setAttribute('draggable', true); + } else { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.setAttribute('draggable', true); + } + } + } + return obj; + }; + }; + + $(function() { + // bind only once for all instances + var lastmv = false, + laster = false, + lastev = false, + opento = false, + marker = $('
             
            ').hide(); //.appendTo('body'); + + $(document) + .on('dragover.vakata.jstree', function (e) { + if (elm) { + $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + } + }) + .on('drop.vakata.jstree', function (e) { + if (elm) { + $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); + elm = null; + drg = null; + } + }) + .on('dnd_start.vakata.jstree', function (e, data) { + lastmv = false; + lastev = false; + if(!data || !data.data || !data.data.jstree) { return; } + marker.appendTo(document.body); //.show(); + }) + .on('dnd_move.vakata.jstree', function (e, data) { + var isDifferentNode = data.event.target !== lastev.target; + if(opento) { + if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { + clearTimeout(opento); + } + } + if(!data || !data.data || !data.data.jstree) { return; } + + // if we are hovering the marker image do nothing (can happen on "inside" drags) + if(data.event.target.id && data.event.target.id === 'jstree-marker') { + return; + } + lastev = data.event; + + var ins = $.jstree.reference(data.event.target), + ref = false, + off = false, + rel = false, + tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn; + // if we are over an instance + if(ins && ins._data && ins._data.dnd) { + marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); + is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); + data.helper + .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) + .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); + + // if are hovering the container itself add a new root node + //console.log(data.event); + if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); + if(!ok) { break; } + } + if(ok) { + lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; + marker.hide(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + return; + } + } + else { + // if we are hovering a tree node + ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); + if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { + off = ref.offset(); + rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; + h = ref.outerHeight(); + if(rel < h / 3) { + o = ['b', 'i', 'a']; + } + else if(rel > h - h / 3) { + o = ['a', 'i', 'b']; + } + else { + o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; + } + $.each(o, function (j, v) { + switch(v) { + case 'b': + l = off.left - 6; + t = off.top; + p = ins.get_parent(ref); + i = ref.parent().index(); + break; + case 'i': + ip = ins.settings.dnd.inside_pos; + tm = ins.get_node(ref.parent()); + l = off.left - 2; + t = off.top + h / 2 + 1; + p = tm.id; + i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); + break; + case 'a': + l = off.left - 6; + t = off.top + h; + p = ins.get_parent(ref); + i = ref.parent().index() + 1; + break; + } + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; + ps = i; + if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { + pr = ins.get_node(p); + if(ps > $.inArray(data.data.nodes[t1], pr.children)) { + ps -= 1; + } + } + ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); + if(!ok) { + if(ins && ins.last_error) { laster = ins.last_error(); } + break; + } + } + if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { + if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { + if (opento) { clearTimeout(opento); } + opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); + } + } + if(ok) { + pn = ins.get_node(p, true); + if (!pn.hasClass('.jstree-dnd-parent')) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + pn.addClass('jstree-dnd-parent'); + } + lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; + marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + laster = {}; + o = true; + return false; + } + }); + if(o === true) { return; } + } + } + } + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + lastmv = false; + data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + //data.event.originalEvent.dataTransfer.dropEffect = 'none'; + } + marker.hide(); + }) + .on('dnd_scroll.vakata.jstree', function (e, data) { + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide(); + lastmv = false; + lastev = false; + data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); + }) + .on('dnd_stop.vakata.jstree', function (e, data) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + if(opento) { clearTimeout(opento); } + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide().detach(); + var i, j, nodes = []; + if(lastmv) { + for(i = 0, j = data.data.nodes.length; i < j; i++) { + nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; + } + lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin); + } + else { + i = $(data.event.target).closest('.jstree'); + if(i.length && laster && laster.error && laster.error === 'check') { + i = i.jstree(true); + if(i) { + i.settings.core.error.call(this, laster); + } + } + } + lastev = false; + lastmv = false; + }) + .on('keyup.jstree keydown.jstree', function (e, data) { + data = $.vakata.dnd._get(); + if(data && data.data && data.data.jstree) { + if (e.type === "keyup" && e.which === 27) { + if (opento) { clearTimeout(opento); } + lastmv = false; + laster = false; + lastev = false; + opento = false; + marker.hide().detach(); + $.vakata.dnd._clean(); + } else { + data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); + if(lastev) { + lastev.metaKey = e.metaKey; + lastev.ctrlKey = e.ctrlKey; + $.vakata.dnd._trigger('move', lastev); + } + } + } + }); + }); + + // helpers + (function ($) { + $.vakata.html = { + div : $('
            '), + escape : function (str) { + return $.vakata.html.div.text(str).html(); + }, + strip : function (str) { + return $.vakata.html.div.empty().append($.parseHTML(str)).text(); + } + }; + // private variable + var vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $.vakata.dnd = { + settings : { + scroll_speed : 10, + scroll_proximity : 20, + helper_left : 5, + helper_top : 10, + threshold : 5, + threshold_touch : 10 + }, + _trigger : function (event_name, e, data) { + if (data === undefined) { + data = $.vakata.dnd._get(); + } + data.event = e; + $(document).triggerHandler("dnd_" + event_name + ".vakata", data); + }, + _get : function () { + return { + "data" : vakata_dnd.data, + "element" : vakata_dnd.element, + "helper" : vakata_dnd.helper + }; + }, + _clean : function () { + if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + }, + _scroll : function (init_only) { + if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + return false; + } + if(!vakata_dnd.scroll_i) { + vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); + return false; + } + if(init_only === true) { return false; } + + var i = vakata_dnd.scroll_e.scrollTop(), + j = vakata_dnd.scroll_e.scrollLeft(); + vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); + vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); + if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { + /** + * triggered on the document when a drag causes an element to scroll + * @event + * @plugin dnd + * @name dnd_scroll.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {jQuery} event the element that is scrolling + */ + $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); + } + }, + start : function (e, data, html) { + if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } + try { + e.currentTarget.unselectable = "on"; + e.currentTarget.onselectstart = function() { return false; }; + if(e.currentTarget.style) { + e.currentTarget.style.touchAction = "none"; + e.currentTarget.style.msTouchAction = "none"; + e.currentTarget.style.MozUserSelect = "none"; + } + } catch(ignore) { } + vakata_dnd.init_x = e.pageX; + vakata_dnd.init_y = e.pageY; + vakata_dnd.data = data; + vakata_dnd.is_down = true; + vakata_dnd.element = e.currentTarget; + vakata_dnd.target = e.target; + vakata_dnd.is_touch = e.type === "touchstart"; + if(html !== false) { + vakata_dnd.helper = $("
            ").html(html).css({ + "display" : "block", + "margin" : "0", + "padding" : "0", + "position" : "absolute", + "top" : "-2000px", + "lineHeight" : "16px", + "zIndex" : "10000" + }); + } + $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + return false; + }, + drag : function (e) { + if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(!vakata_dnd.is_down) { return; } + if(!vakata_dnd.is_drag) { + if( + Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || + Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) + ) { + if(vakata_dnd.helper) { + vakata_dnd.helper.appendTo(document.body); + vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); + } + vakata_dnd.is_drag = true; + $(vakata_dnd.target).one('click.vakata', false); + /** + * triggered on the document when a drag starts + * @event + * @plugin dnd + * @name dnd_start.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the start (probably mousemove) + */ + $.vakata.dnd._trigger("start", e); + } + else { return; } + } + + var d = false, w = false, + dh = false, wh = false, + dw = false, ww = false, + dt = false, dl = false, + ht = false, hl = false; + + vakata_dnd.scroll_t = 0; + vakata_dnd.scroll_l = 0; + vakata_dnd.scroll_e = false; + $($(e.target).parentsUntil("body").addBack().get().reverse()) + .filter(function () { + return (/^auto|scroll$/).test($(this).css("overflow")) && + (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); + }) + .each(function () { + var t = $(this), o = t.offset(); + if(this.scrollHeight > this.offsetHeight) { + if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + } + if(this.scrollWidth > this.offsetWidth) { + if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = $(this); + return false; + } + }); + + if(!vakata_dnd.scroll_e) { + d = $(document); w = $(window); + dh = d.height(); wh = w.height(); + dw = d.width(); ww = w.width(); + dt = d.scrollTop(); dl = d.scrollLeft(); + if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = d; + } + } + if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } + + if(vakata_dnd.helper) { + ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); + hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); + if(dh && ht + 25 > dh) { ht = dh - 50; } + if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } + vakata_dnd.helper.css({ + left : hl + "px", + top : ht + "px" + }); + } + /** + * triggered on the document when a drag is in progress + * @event + * @plugin dnd + * @name dnd_move.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused this to trigger (most likely mousemove) + */ + $.vakata.dnd._trigger("move", e); + return false; + }, + stop : function (e) { + if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { + /** + * triggered on the document when a drag stops (the dragged element is dropped) + * @event + * @plugin dnd + * @name dnd_stop.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the stop + */ + if (e.target !== vakata_dnd.target) { + $(vakata_dnd.target).off('click.vakata'); + } + $.vakata.dnd._trigger("stop", e); + } + else { + if(e.type === "touchend" && e.target === vakata_dnd.target) { + var to = setTimeout(function () { $(e.target).click(); }, 100); + $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); + } + } + $.vakata.dnd._clean(); + return false; + } + }; + }($)); + + // include the dnd plugin by default + // $.jstree.defaults.plugins.push("dnd"); + + +/** + * ### Massload plugin + * + * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading). + */ + + /** + * massload configuration + * + * It is possible to set this to a standard jQuery-like AJAX config. + * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used. + * + * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result. + * + * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array. + * + * { + * "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }], + * "id2" : [{ "text" : "Child of ID2", "id" : "c3" }] + * } + * + * @name $.jstree.defaults.massload + * @plugin massload + */ + $.jstree.defaults.massload = null; + $.jstree.plugins.massload = function (options, parent) { + this.init = function (el, options) { + this._data.massload = {}; + parent.init.call(this, el, options); + }; + this._load_nodes = function (nodes, callback, is_callback, force_reload) { + var s = this.settings.massload, + nodesString = JSON.stringify(nodes), + toLoad = [], + m = this._model.data, + i, j, dom; + if (!is_callback) { + for(i = 0, j = nodes.length; i < j; i++) { + if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) { + toLoad.push(nodes[i]); + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.addClass("jstree-loading").attr('aria-busy',true); + } + } + } + this._data.massload = {}; + if (toLoad.length) { + if($.isFunction(s)) { + return s.call(this, toLoad, $.proxy(function (data) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + if(typeof s === 'object' && s && s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, toLoad); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, toLoad); + } + return $.ajax(s) + .done($.proxy(function (data,t,x) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)) + .fail($.proxy(function (f) { + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + } + } + return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }; + this._load_node = function (obj, callback) { + var data = this._data.massload[obj.id], + rslt = null, dom; + if(data) { + rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data']( + obj, + typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data, + function (status) { callback.call(this, status); } + ); + dom = this.get_node(obj.id, true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + delete this._data.massload[obj.id]; + return rslt; + } + return parent._load_node.call(this, obj, callback); + }; + }; + +/** + * ### Search plugin + * + * Adds search functionality to jsTree. + */ + + /** + * stores all defaults for the search plugin + * @name $.jstree.defaults.search + * @plugin search + */ + $.jstree.defaults.search = { + /** + * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. + * + * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed. + * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to + * @name $.jstree.defaults.search.ajax + * @plugin search + */ + ajax : false, + /** + * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`. + * @name $.jstree.defaults.search.fuzzy + * @plugin search + */ + fuzzy : false, + /** + * Indicates if the search should be case sensitive. Default is `false`. + * @name $.jstree.defaults.search.case_sensitive + * @plugin search + */ + case_sensitive : false, + /** + * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches + * @plugin search + */ + show_only_matches : false, + /** + * Indicates if the children of matched element are shown (when show_only_matches is true) + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches_children + * @plugin search + */ + show_only_matches_children : false, + /** + * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`. + * @name $.jstree.defaults.search.close_opened_onclear + * @plugin search + */ + close_opened_onclear : true, + /** + * Indicates if only leaf nodes should be included in search results. Default is `false`. + * @name $.jstree.defaults.search.search_leaves_only + * @plugin search + */ + search_leaves_only : false, + /** + * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution). + * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`. + * @name $.jstree.defaults.search.search_callback + * @plugin search + */ + search_callback : false + }; + + $.jstree.plugins.search = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this._data.search.str = ""; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = false; + this._data.search.smc = false; + this._data.search.hdn = []; + + this.element + .on("search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + var m = this._model.data, i, j, p = [], k, l; + for(i = 0, j = data.res.length; i < j; i++) { + if(m[data.res[i]] && !m[data.res[i]].state.hidden) { + p.push(data.res[i]); + p = p.concat(m[data.res[i]].parents); + if(this._data.search.smc) { + for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { + if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { + p.push(m[data.res[i]].children_d[k]); + } + } + } + } + } + p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); + this._data.search.hdn = this.hide_all(true); + this.show_node(p, true); + this.redraw(true); + } + }, this)) + .on("clear_search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + this.show_node(this._data.search.hdn, true); + this.redraw(true); + } + }, this)); + }; + /** + * used to search the tree nodes for a given string + * @name search(str [, skip_async]) + * @param {String} str the search string + * @param {Boolean} skip_async if set to true server will not be queried even if configured + * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers) + * @param {mixed} inside an optional node to whose children to limit the search + * @param {Boolean} append if set to true the results of this search are appended to the previous search + * @plugin search + * @trigger search.jstree + */ + this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) { + if(str === false || $.trim(str.toString()) === "") { + return this.clear_search(); + } + inside = this.get_node(inside); + inside = inside && inside.id ? inside.id : null; + str = str.toString(); + var s = this.settings.search, + a = s.ajax ? s.ajax : false, + m = this._model.data, + f = null, + r = [], + p = [], i, j; + if(this._data.search.res.length && !append) { + this.clear_search(); + } + if(show_only_matches === undefined) { + show_only_matches = s.show_only_matches; + } + if(show_only_matches_children === undefined) { + show_only_matches_children = s.show_only_matches_children; + } + if(!skip_async && a !== false) { + if($.isFunction(a)) { + return a.call(this, str, $.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this), inside); + } + else { + a = $.extend({}, a); + if(!a.data) { a.data = {}; } + a.data.str = str; + if(inside) { + a.data.inside = inside; + } + if (this._data.search.lastRequest) { + this._data.search.lastRequest.abort(); + } + this._data.search.lastRequest = $.ajax(a) + .fail($.proxy(function () { + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) }; + this.settings.core.error.call(this, this._data.core.last_error); + }, this)) + .done($.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this)); + return this._data.search.lastRequest; + } + } + if(!append) { + this._data.search.str = str; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = show_only_matches; + this._data.search.smc = show_only_matches_children; + } + + f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); + $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { + var v = m[i]; + if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) { + r.push(i); + p = p.concat(v.parents); + } + }); + if(r.length) { + p = $.vakata.array_unique(p); + for(i = 0, j = p.length; i < j; i++) { + if(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) { + this._data.search.opn.push(p[i]); + } + } + if(!append) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); + this._data.search.res = r; + } + else { + this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')))); + this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r)); + } + this._data.search.dom.children(".jstree-anchor").addClass('jstree-search'); + } + /** + * triggered after search is complete + * @event + * @name search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes + * @param {String} str the search string + * @param {Array} res a collection of objects represeing the matching nodes + * @plugin search + */ + this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches }); + }; + /** + * used to clear the last search (removes classes and shows all nodes if filtering is on) + * @name clear_search() + * @plugin search + * @trigger clear_search.jstree + */ + this.clear_search = function () { + if(this.settings.search.close_opened_onclear) { + this.close_node(this._data.search.opn, 0); + } + /** + * triggered after search is complete + * @event + * @name clear_search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search) + * @param {String} str the search string (the last search string) + * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search) + * @plugin search + */ + this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res }); + if(this._data.search.res.length) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) { + return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); + }).join(', #'))); + this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"); + } + this._data.search.str = ""; + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.dom = $(); + }; + + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + if($.inArray(obj.id, this._data.search.res) !== -1) { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.className += ' jstree-search'; + } + } + } + return obj; + }; + }; + + // helpers + (function ($) { + // from http://kiro.me/projects/fuse.html + $.vakata.search = function(pattern, txt, options) { + options = options || {}; + options = $.extend({}, $.vakata.search.defaults, options); + if(options.fuzzy !== false) { + options.fuzzy = true; + } + pattern = options.caseSensitive ? pattern : pattern.toLowerCase(); + var MATCH_LOCATION = options.location, + MATCH_DISTANCE = options.distance, + MATCH_THRESHOLD = options.threshold, + patternLen = pattern.length, + matchmask, pattern_alphabet, match_bitapScore, search; + if(patternLen > 32) { + options.fuzzy = false; + } + if(options.fuzzy) { + matchmask = 1 << (patternLen - 1); + pattern_alphabet = (function () { + var mask = {}, + i = 0; + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] = 0; + } + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1); + } + return mask; + }()); + match_bitapScore = function (e, x) { + var accuracy = e / patternLen, + proximity = Math.abs(MATCH_LOCATION - x); + if(!MATCH_DISTANCE) { + return proximity ? 1.0 : accuracy; + } + return accuracy + (proximity / MATCH_DISTANCE); + }; + } + search = function (text) { + text = options.caseSensitive ? text : text.toLowerCase(); + if(pattern === text || text.indexOf(pattern) !== -1) { + return { + isMatch: true, + score: 0 + }; + } + if(!options.fuzzy) { + return { + isMatch: false, + score: 1 + }; + } + var i, j, + textLen = text.length, + scoreThreshold = MATCH_THRESHOLD, + bestLoc = text.indexOf(pattern, MATCH_LOCATION), + binMin, binMid, + binMax = patternLen + textLen, + lastRd, start, finish, rd, charMatch, + score = 1, + locations = []; + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen); + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + } + } + bestLoc = -1; + for (i = 0; i < patternLen; i++) { + binMin = 0; + binMid = binMax; + while (binMin < binMid) { + if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + binMax = binMid; + start = Math.max(1, MATCH_LOCATION - binMid + 1); + finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen; + rd = new Array(finish + 2); + rd[finish + 1] = (1 << i) - 1; + for (j = finish; j >= start; j--) { + charMatch = pattern_alphabet[text.charAt(j - 1)]; + if (i === 0) { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; + } else { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; + } + if (rd[j] & matchmask) { + score = match_bitapScore(i, j - 1); + if (score <= scoreThreshold) { + scoreThreshold = score; + bestLoc = j - 1; + locations.push(bestLoc); + if (bestLoc > MATCH_LOCATION) { + start = Math.max(1, 2 * MATCH_LOCATION - bestLoc); + } else { + break; + } + } + } + } + if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) { + break; + } + lastRd = rd; + } + return { + isMatch: bestLoc >= 0, + score: score + }; + }; + return txt === true ? { 'search' : search } : search(txt); + }; + $.vakata.search.defaults = { + location : 0, + distance : 100, + threshold : 0.6, + fuzzy : false, + caseSensitive : false + }; + }($)); + + // include the search plugin by default + // $.jstree.defaults.plugins.push("search"); + + +/** + * ### Sort plugin + * + * Automatically sorts all siblings in the tree according to a sorting function. + */ + + /** + * the settings function used to sort the nodes. + * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`. + * @name $.jstree.defaults.sort + * @plugin sort + */ + $.jstree.defaults.sort = function (a, b) { + //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b); + return this.get_text(a) > this.get_text(b) ? 1 : -1; + }; + $.jstree.plugins.sort = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this.element + .on("model.jstree", $.proxy(function (e, data) { + this.sort(data.parent, true); + }, this)) + .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent || data.node.parent, false); + this.redraw_node(data.parent || data.node.parent, true); + }, this)) + .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent, false); + this.redraw_node(data.parent, true); + }, this)); + }; + /** + * used to sort a node's children + * @private + * @name sort(obj [, deep]) + * @param {mixed} obj the node + * @param {Boolean} deep if set to `true` nodes are sorted recursively. + * @plugin sort + * @trigger search.jstree + */ + this.sort = function (obj, deep) { + var i, j; + obj = this.get_node(obj); + if(obj && obj.children && obj.children.length) { + obj.children.sort($.proxy(this.settings.sort, this)); + if(deep) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + this.sort(obj.children_d[i], false); + } + } + } + }; + }; + + // include the sort plugin by default + // $.jstree.defaults.plugins.push("sort"); + +/** + * ### State plugin + * + * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc) + */ + + var to = false; + /** + * stores all defaults for the state plugin + * @name $.jstree.defaults.state + * @plugin state + */ + $.jstree.defaults.state = { + /** + * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`. + * @name $.jstree.defaults.state.key + * @plugin state + */ + key : 'jstree', + /** + * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`. + * @name $.jstree.defaults.state.events + * @plugin state + */ + events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree', + /** + * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire. + * @name $.jstree.defaults.state.ttl + * @plugin state + */ + ttl : false, + /** + * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state. + * @name $.jstree.defaults.state.filter + * @plugin state + */ + filter : false, + /** + * Should loaded nodes be restored (setting this to true means that it is possible that the whole tree will be loaded for some users - use with caution). Defaults to `false` + * @name $.jstree.defaults.state.preserve_loaded + * @plugin state + */ + preserve_loaded : false + }; + $.jstree.plugins.state = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + var bind = $.proxy(function () { + this.element.on(this.settings.state.events, $.proxy(function () { + if(to) { clearTimeout(to); } + to = setTimeout($.proxy(function () { this.save_state(); }, this), 100); + }, this)); + /** + * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore). + * @event + * @name state_ready.jstree + * @plugin state + */ + this.trigger('state_ready'); + }, this); + this.element + .on("ready.jstree", $.proxy(function (e, data) { + this.element.one("restore_state.jstree", bind); + if(!this.restore_state()) { bind(); } + }, this)); + }; + /** + * save the state + * @name save_state() + * @plugin state + */ + this.save_state = function () { + var tm = this.get_state(); + if (!this.settings.state.preserve_loaded) { + delete tm.core.loaded; + } + var st = { 'state' : tm, 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) }; + $.vakata.storage.set(this.settings.state.key, JSON.stringify(st)); + }; + /** + * restore the state from the user's computer + * @name restore_state() + * @plugin state + */ + this.restore_state = function () { + var k = $.vakata.storage.get(this.settings.state.key); + if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } } + if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; } + if(!!k && k.state) { k = k.state; } + if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); } + if(!!k) { + if (!this.settings.state.preserve_loaded) { + delete k.core.loaded; + } + this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); }); + this.set_state(k); + return true; + } + return false; + }; + /** + * clear the state on the user's computer + * @name clear_state() + * @plugin state + */ + this.clear_state = function () { + return $.vakata.storage.del(this.settings.state.key); + }; + }; + + (function ($, undefined) { + $.vakata.storage = { + // simply specifying the functions in FF throws an error + set : function (key, val) { return window.localStorage.setItem(key, val); }, + get : function (key) { return window.localStorage.getItem(key); }, + del : function (key) { return window.localStorage.removeItem(key); } + }; + }($)); + + // include the state plugin by default + // $.jstree.defaults.plugins.push("state"); + +/** + * ### Types plugin + * + * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group. + */ + + /** + * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional). + * + * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited. + * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited. + * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits. + * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme. + * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data) + * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data) + * + * There are two predefined types: + * + * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes. + * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified. + * + * @name $.jstree.defaults.types + * @plugin types + */ + $.jstree.defaults.types = { + 'default' : {} + }; + $.jstree.defaults.types[$.jstree.root] = {}; + + $.jstree.plugins.types = function (options, parent) { + this.init = function (el, options) { + var i, j; + if(options && options.types && options.types['default']) { + for(i in options.types) { + if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) { + for(j in options.types['default']) { + if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) { + options.types[i][j] = options.types['default'][j]; + } + } + } + } + } + parent.init.call(this, el, options); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.refresh = function (skip_loading, forget_state) { + parent.refresh.call(this, skip_loading, forget_state); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.bind = function () { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + dpc = data.nodes, + t = this.settings.types, + i, j, c = 'default', k; + for(i = 0, j = dpc.length; i < j; i++) { + c = 'default'; + if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) { + c = m[dpc[i]].original.type; + } + if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) { + c = m[dpc[i]].data.jstree.type; + } + m[dpc[i]].type = c; + if(m[dpc[i]].icon === true && t[c].icon !== undefined) { + m[dpc[i]].icon = t[c].icon; + } + if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') { + for (k in t[c].li_attr) { + if (t[c].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].li_attr[k] === undefined) { + m[dpc[i]].li_attr[k] = t[c].li_attr[k]; + } + else if (k === 'class') { + m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class']; + } + } + } + } + if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') { + for (k in t[c].a_attr) { + if (t[c].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].a_attr[k] === undefined) { + m[dpc[i]].a_attr[k] = t[c].a_attr[k]; + } + else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') { + m[dpc[i]].a_attr['href'] = t[c].a_attr['href']; + } + else if (k === 'class') { + m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class']; + } + } + } + } + } + m[$.jstree.root].type = $.jstree.root; + }, this)); + parent.bind.call(this); + }; + this.get_json = function (obj, options, flat) { + var i, j, + m = this._model.data, + opt = options ? $.extend(true, {}, options, {no_id:false}) : {}, + tmp = parent.get_json.call(this, obj, opt, flat); + if(tmp === false) { return false; } + if($.isArray(tmp)) { + for(i = 0, j = tmp.length; i < j; i++) { + tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default"; + if(options && options.no_id) { + delete tmp[i].id; + if(tmp[i].li_attr && tmp[i].li_attr.id) { + delete tmp[i].li_attr.id; + } + if(tmp[i].a_attr && tmp[i].a_attr.id) { + delete tmp[i].a_attr.id; + } + } + } + } + else { + tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default"; + if(options && options.no_id) { + tmp = this._delete_ids(tmp); + } + } + return tmp; + }; + this._delete_ids = function (tmp) { + if($.isArray(tmp)) { + for(var i = 0, j = tmp.length; i < j; i++) { + tmp[i] = this._delete_ids(tmp[i]); + } + return tmp; + } + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + if(tmp.children && $.isArray(tmp.children)) { + tmp.children = this._delete_ids(tmp.children); + } + return tmp; + }; + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j; + m = m && m._model && m._model.data ? m._model.data : null; + switch(chk) { + case "create_node": + case "move_node": + case "copy_node": + if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) { + tmp = this.get_rules(par); + if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(m && obj.children_d && obj.parents) { + d = 0; + for(i = 0, j = obj.children_d.length; i < j; i++) { + d = Math.max(d, m[obj.children_d[i]].parents.length); + } + d = d - obj.parents.length + 1; + } + if(d <= 0 || d === undefined) { d = 1; } + do { + if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + par = this.get_node(par.parent); + tmp = this.get_rules(par); + d++; + } while(par); + } + break; + } + return true; + }; + /** + * used to retrieve the type settings object for a node + * @name get_rules(obj) + * @param {mixed} obj the node to find the rules for + * @return {Object} + * @plugin types + */ + this.get_rules = function (obj) { + obj = this.get_node(obj); + if(!obj) { return false; } + var tmp = this.get_type(obj, true); + if(tmp.max_depth === undefined) { tmp.max_depth = -1; } + if(tmp.max_children === undefined) { tmp.max_children = -1; } + if(tmp.valid_children === undefined) { tmp.valid_children = -1; } + return tmp; + }; + /** + * used to retrieve the type string or settings object for a node + * @name get_type(obj [, rules]) + * @param {mixed} obj the node to find the rules for + * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned + * @return {String|Object} + * @plugin types + */ + this.get_type = function (obj, rules) { + obj = this.get_node(obj); + return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type); + }; + /** + * used to change a node's type + * @name set_type(obj, type) + * @param {mixed} obj the node to change + * @param {String} type the new type + * @plugin types + */ + this.set_type = function (obj, type) { + var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_type(obj[t1], type); + } + return true; + } + t = this.settings.types; + obj = this.get_node(obj); + if(!t[type] || !obj) { return false; } + d = this.get_node(obj, true); + if (d && d.length) { + a = d.children('.jstree-anchor'); + } + old_type = obj.type; + old_icon = this.get_icon(obj); + obj.type = type; + if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) { + this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true); + } + + // remove old type props + if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') { + for (k in t[old_type].li_attr) { + if (t[old_type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], ''); + if (d) { d.removeClass(t[old_type].li_attr[k]); } + } + else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) { + m[obj.id].li_attr[k] = null; + if (d) { d.removeAttr(k); } + } + } + } + } + if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') { + for (k in t[old_type].a_attr) { + if (t[old_type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], ''); + if (a) { a.removeClass(t[old_type].a_attr[k]); } + } + else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) { + if (k === 'href') { + m[obj.id].a_attr[k] = '#'; + if (a) { a.attr('href', '#'); } + } + else { + delete m[obj.id].a_attr[k]; + if (a) { a.removeAttr(k); } + } + } + } + } + } + + // add new props + if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') { + for (k in t[type].li_attr) { + if (t[type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].li_attr[k] === undefined) { + m[obj.id].li_attr[k] = t[type].li_attr[k]; + if (d) { + if (k === 'class') { + d.addClass(t[type].li_attr[k]); + } + else { + d.attr(k, t[type].li_attr[k]); + } + } + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class']; + if (d) { d.addClass(t[type].li_attr[k]); } + } + } + } + } + if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') { + for (k in t[type].a_attr) { + if (t[type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].a_attr[k] === undefined) { + m[obj.id].a_attr[k] = t[type].a_attr[k]; + if (a) { + if (k === 'class') { + a.addClass(t[type].a_attr[k]); + } + else { + a.attr(k, t[type].a_attr[k]); + } + } + } + else if (k === 'href' && m[obj.id].a_attr[k] === '#') { + m[obj.id].a_attr['href'] = t[type].a_attr['href']; + if (a) { a.attr('href', t[type].a_attr['href']); } + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class']; + if (a) { a.addClass(t[type].a_attr[k]); } + } + } + } + } + + return true; + }; + }; + // include the types plugin by default + // $.jstree.defaults.plugins.push("types"); + + +/** + * ### Unique plugin + * + * Enforces that no nodes with the same name can coexist as siblings. + */ + + /** + * stores all defaults for the unique plugin + * @name $.jstree.defaults.unique + * @plugin unique + */ + $.jstree.defaults.unique = { + /** + * Indicates if the comparison should be case sensitive. Default is `false`. + * @name $.jstree.defaults.unique.case_sensitive + * @plugin unique + */ + case_sensitive : false, + /** + * Indicates if white space should be trimmed before the comparison. Default is `false`. + * @name $.jstree.defaults.unique.trim_whitespace + * @plugin unique + */ + trim_whitespace : false, + /** + * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`. + * @name $.jstree.defaults.unique.duplicate + * @plugin unique + */ + duplicate : function (name, counter) { + return name + ' (' + counter + ')'; + } + }; + + $.jstree.plugins.unique = function (options, parent) { + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + if(!par || !par.children) { return true; } + var n = chk === "rename_node" ? pos : obj.text, + c = [], + s = this.settings.unique.case_sensitive, + w = this.settings.unique.trim_whitespace, + m = this._model.data, i, j, t; + for(i = 0, j = par.children.length; i < j; i++) { + t = m[par.children[i]].text; + if (!s) { + t = t.toLowerCase(); + } + if (w) { + t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + c.push(t); + } + if(!s) { n = n.toLowerCase(); } + if (w) { n = n.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } + switch(chk) { + case "delete_node": + return true; + case "rename_node": + t = obj.text || ''; + if (!s) { + t = t.toLowerCase(); + } + if (w) { + t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + i = ($.inArray(n, c) === -1 || (obj.text && t === n)); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "create_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "copy_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "move_node": + i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + } + return true; + }; + this.create_node = function (par, node, pos, callback, is_loaded) { + if(!node || node.text === undefined) { + if(par === null) { + par = $.jstree.root; + } + par = this.get_node(par); + if(!par) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + if(!node) { node = {}; } + var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, w = this.settings.unique.trim_whitespace, cb = this.settings.unique.duplicate, t; + n = tmp = this.get_string('New node'); + dpc = []; + for(i = 0, j = par.children.length; i < j; i++) { + t = m[par.children[i]].text; + if (!s) { + t = t.toLowerCase(); + } + if (w) { + t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + dpc.push(t); + } + i = 1; + t = n; + if (!s) { + t = t.toLowerCase(); + } + if (w) { + t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + while($.inArray(t, dpc) !== -1) { + n = cb.call(this, tmp, (++i)).toString(); + t = n; + if (!s) { + t = t.toLowerCase(); + } + if (w) { + t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + } + node.text = n; + } + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + }; + }; + + // include the unique plugin by default + // $.jstree.defaults.plugins.push("unique"); + + +/** + * ### Wholerow plugin + * + * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers. + */ + + var div = document.createElement('DIV'); + div.setAttribute('unselectable','on'); + div.setAttribute('role','presentation'); + div.className = 'jstree-wholerow'; + div.innerHTML = ' '; + $.jstree.plugins.wholerow = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this.element + .on('ready.jstree set_state.jstree', $.proxy(function () { + this.hide_dots(); + }, this)) + .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { + //div.style.height = this._data.core.li_height + 'px'; + this.get_container_ul().addClass('jstree-wholerow-ul'); + }, this)) + .on("deselect_all.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + }, this)) + .on("changed.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + var tmp = false, i, j; + for(i = 0, j = data.selected.length; i < j; i++) { + tmp = this.get_node(data.selected[i], true); + if(tmp && tmp.length) { + tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + } + } + }, this)) + .on("open_node.jstree", $.proxy(function (e, data) { + this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + }, this)) + .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) { + if(e.type === "hover_node" && this.is_disabled(data.node)) { return; } + this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered'); + }, this)) + .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) { + if (this._data.contextmenu) { + e.preventDefault(); + var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp); + } + }, this)) + /*! + .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) { + if(e.target === e.currentTarget) { + var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor"); + e.target = a[0]; + a.trigger(e); + } + }) + */ + .on("click.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("dblclick.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }, this)) + .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) { + e.stopImmediatePropagation(); + if(!this.is_disabled(e.currentTarget)) { + this.hover_node(e.currentTarget); + } + return false; + }, this)) + .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }; + this.teardown = function () { + if(this.settings.wholerow) { + this.element.find(".jstree-wholerow").remove(); + } + parent.teardown.call(this); + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var tmp = div.cloneNode(true); + //tmp.style.height = this._data.core.li_height + 'px'; + if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; } + if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; } + obj.insertBefore(tmp, obj.childNodes[0]); + } + return obj; + }; + }; + // include the wholerow plugin by default + // $.jstree.defaults.plugins.push("wholerow"); + if(window.customElements && Object && Object.create) { + var proto = Object.create(HTMLElement.prototype); + proto.createdCallback = function () { + var c = { core : {}, plugins : [] }, i; + for(i in $.jstree.plugins) { + if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) { + c.plugins.push(i); + if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) { + c[i] = JSON.parse(this.getAttribute(i)); + } + } + } + for(i in $.jstree.defaults.core) { + if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) { + c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i); + } + } + $(this).jstree(c); + }; + // proto.attributeChangedCallback = function (name, previous, value) { }; + try { + window.customElements.define("vakata-jstree", function() {}, { prototype: proto }); + } catch (ignore) { } + } + +})); \ No newline at end of file diff --git a/src/main/webapp/resources/html/fileUpload.html b/src/main/webapp/resources/html/fileUpload.html index 442199ba..f44d73e4 100644 --- a/src/main/webapp/resources/html/fileUpload.html +++ b/src/main/webapp/resources/html/fileUpload.html @@ -162,7 +162,7 @@ - + diff --git a/src/main/webapp/resources/html/inputDateDialog.html b/src/main/webapp/resources/html/inputDateDialog.html index 759816a9..6d372f3a 100644 --- a/src/main/webapp/resources/html/inputDateDialog.html +++ b/src/main/webapp/resources/html/inputDateDialog.html @@ -72,7 +72,7 @@ - + diff --git a/src/main/webapp/resources/html/inputRsnDialog.html b/src/main/webapp/resources/html/inputRsnDialog.html index fb0d4b11..9ae00a85 100644 --- a/src/main/webapp/resources/html/inputRsnDialog.html +++ b/src/main/webapp/resources/html/inputRsnDialog.html @@ -55,7 +55,7 @@ - + diff --git a/src/main/webapp/resources/html/inputTtlDocNoDialog.html b/src/main/webapp/resources/html/inputTtlDocNoDialog.html index 2b17cfa6..2bd85852 100644 --- a/src/main/webapp/resources/html/inputTtlDocNoDialog.html +++ b/src/main/webapp/resources/html/inputTtlDocNoDialog.html @@ -76,7 +76,7 @@ - + diff --git a/src/main/webapp/resources/html/pdf.html b/src/main/webapp/resources/html/pdf.html index dfcf1a1d..4c64fa4c 100644 --- a/src/main/webapp/resources/html/pdf.html +++ b/src/main/webapp/resources/html/pdf.html @@ -40,7 +40,7 @@ - + diff --git a/src/main/webapp/resources/html/searchAddr.html b/src/main/webapp/resources/html/searchAddr.html index 0583b97b..f66d8c8f 100644 --- a/src/main/webapp/resources/html/searchAddr.html +++ b/src/main/webapp/resources/html/searchAddr.html @@ -113,7 +113,7 @@ - +