Subversion Repository Public Repository

Nextrek

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
    "uid": "4216707AK784EA4859S86BBE1FCA7990F36B",
    "isLoaded": true,
    "lastModificationTime": 0,
    "items": {
        "name": "UIManager",
        "type": "game_script",
        "order": 8,
        "content": "# ===================================================================\n#\n#   Script: UIManager\n#\n#   $$COPYRIGHT$$\n#\n# ===================================================================\n\nclass Formula\n    ###*\n    * Encapsulates a UI formula. A formula can be used in UI layouts to define\n    * property-bindings or to implement a specific behavior.\n    *\n    * @module ui\n    * @class Formula\n    * @memberof ui\n    * @constructor\n    * @param {Function} f - The formula-function. Defines the logic of the formula.\n    * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n    * @param {string} event - An optional event-name to define when the formula should be executed.\n    ###\n    constructor: (f, data, event) ->\n        ###*\n        * Indicates if its the first time the formula is called.\n        * @property onInitialize\n        * @type boolean\n        ###\n        @onInitialize = yes\n        \n        ###*\n        * The formula-function.\n        * @property exec_\n        * @type Function\n        ###\n        @exec_ = f\n         \n        ###*\n        * An optional data-object which can bes accessed inside the formula-function.\n        * @property data\n        * @type Object\n        ###   \n        @data = data\n        \n        ###*\n        * An optional event-name to define when the formula should be executed.\n        * @property event\n        * @type string\n        ### \n        @event = event\n        \n        ###*\n        * An array of custom number-data which can be used for different purposes. The first element\n        * is also used in onChange method to store the old value and check against the new one to detect a change.\n        * @property numbers\n        * @type number[]\n        ### \n        @numbers = new Array(10)\n        @numbers[i] = 0 for i in [0..@numbers.length]\n        \n        ###*\n        * An array of custom string-data which can be used for different purposes. The first element\n        * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n        * @property strings\n        * @type string[]\n        ###\n        @strings = new Array(10)\n        @strings[i] = \"\" for i in [0..@strings.length]\n        \n    \n    ###*\n    * The formula-function. Its a wrapper-function before the first-time call was made.\n    * @method exec\n    ###\n    exec: ->\n       @exec = @exec_\n       r = @exec_.apply(this, arguments)\n       @onInitialize = no\n       \n       return r\n       \n    ###*\n    * Checks if the specified number-value has changed since the last check. It uses\n    * the first entry of the numbers-array to store the value and check against the new one.\n    *\n    * @method onChange\n    * @param {number} numberValue - Number value to check.\n    ###    \n    onChange: (numberValue) ->\n        result = @numbers[0] != numberValue\n        @numbers[0] = numberValue\n        \n        return result\n     \n    ###*\n    * Checks if the specified text-value has changed since the last check. It uses\n    * the first entry of the strings-array to store the value and check against the new one.\n    *\n    * @method onTextChange\n    * @param {string} textValue - Text value to check.\n    ###     \n    onTextChange: (textValue) ->\n        result = @strings[0] != textValue\n        @strings[0] = textValue\n        \n        return result\n        \nui.Formula = Formula\n\nclass Space\n    ###*\n    * Describes a space inside or around something like a margin or padding.\n    *\n    * @module ui\n    * @class Space\n    * @memberof ui\n    * @constructor\n    * @param {number} left - Space at the left in pixels.\n    * @param {number} top - Space at the top in pixels.\n    * @param {number} right - Space at the right in pixels.\n    * @param {number} bottom - Space at the bottom in pixels.\n    ###\n    constructor: (left, top, right, bottom) ->\n        ###*\n        * Space at the left in pixels.\n        * @property left\n        * @type number\n        ###\n        @left = left\n        \n        ###*\n        * Space at the top in pixels.\n        * @property top\n        * @type number\n        ###\n        @top = top\n        \n        ###*\n        * Space at the right in pixels.\n        * @property right\n        * @type number\n        ###\n        @right = right\n        \n        ###*\n        * Space at the bottom in pixels.\n        * @property bottom\n        * @type number\n        ###\n        @bottom = bottom\n      \n    ###*\n    * Sets the coordinates of the space by copying them from a specified space.\n    *\n    * @method setFromObject\n    * @param {Object} space - A space to copy.\n    ###   \n    setFromObject: (space) ->\n        @left = space.left\n        @top = space.top\n        @right = space.right\n        @bottom = space.bottom\n      \n    ###*\n    * Sets the coordinates of the space.\n    *\n    * @method set\n    * @param {number} left - Space at the left in pixels.\n    * @param {number} top - Space at the top in pixels.\n    * @param {number} right - Space at the right in pixels.\n    * @param {number} bottom - Space at the bottom in pixels.\n    ###    \n    set: (left, top, right, bottom) ->\n        @left = left\n        @top = top\n        @right = right\n        @bottom = bottom\n    \n    ###*\n    * Creates a new space object from an array of coordinates.\n    *\n    * @method fromArray\n    * @static\n    * @param {number[]} array - An array of coordinates (left, top right, bottom).\n    ###    \n    @fromArray: (array) -> new ui.Space(array[0], array[1], array[2], array[3])\n        \nui.Space = Space\n\nclass Style\n    ###*\n    * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n    *\n    * @module ui\n    * @class Style\n    * @memberof ui\n    * @constructor\n    * @param {Object} descriptor - A style-descriptor to initialize the style from.\n    * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n    * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n    ###\n    constructor: (descriptor, id, selector) ->\n        ###*\n        * ID number to quickly access this style and link to this style.\n        * @property id\n        * @type number\n        ###\n        @id = id\n        \n        ###*\n        * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n        * children of UI objects where this style is applied.\n        * @property target\n        * @type number\n        ###\n        @target = -1\n        \n        ###*\n        * Selector-ID which controls under which conditions the style becomes active.\n        * @property selector\n        * @type number\n        ###\n        @selector = selector\n        \n        ###*\n        * The font used for the text-display.\n        * @default null\n        * @property font\n        * @type gs.Font\n        ###\n        @font = null\n        \n        ###*\n        * The UI object's image used for visual presentation.\n        * @property image\n        * @type string\n        ###\n        @image = null\n        \n        ###*\n        * The UI object's animations used for visual presentation.\n        * @default null\n        * @property animations\n        * @type Object[]\n        ###\n        @animations = null\n        \n        ###*\n        * The UI object's color.\n        * @property color\n        * @type gs.Color\n        ###\n        @color = null\n        \n        ###*\n        * The UI object's tone.\n        * @property tone\n        * @type gs.Tone\n        ###\n        @tone = null\n        \n        ###*\n        * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n        * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n        * places the object with its lower-right corner.\n        * @property anchor\n        * @type gs.Point\n        ###\n        @anchor = null\n        \n        ###*\n        * The UI object's zoom-setting for x and y axis.\n        * @default new gs.Point(1.0, 1.0)\n        * @property zoom\n        * @type gs.Point\n        ###\n        @zoom = null\n        \n        ###*\n        * The UI object's margin. The margin defines an extra space around the UI object. \n        * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n        * @property margin\n        * @type Object\n        ###\n        @margin = null\n        \n        ###*\n        * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n        * @property padding\n        * @type Object\n        ###\n        @padding = null\n        \n        ###*\n        * The UI object's mask for masking-effects.\n        * @property mask\n        * @type gs.Mask\n        ###\n        @mask = null\n        \n        ###*\n        * The UI object's alignment.\n        * @property alignment\n        * @type ui.Alignment\n        ###\n        @alignment = -1\n        \n        ###*\n        * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n        * @property opacity\n        * @type number\n        ###\n        @opacity = -1\n        \n        ###*\n        * The object's clip-rect for visual presentation.\n        * @default null\n        * @property clipRect\n        * @type gs.Rect\n        * @protected\n        ###\n        @clipRect = null\n        \n        ###*\n        * The corner-size of the frame.\n        * @property frameCornerSize\n        * @type number\n        ###\n        @frameCornerSize = -1\n        \n        ###*\n        * The thickness of the frame.\n        * @property frameThickness\n        * @type number\n        ###\n        @frameThickness = -1\n        \n        ###*\n        * The looping of the image.\n        * @property looping\n        * @type ui.Orientation\n        ###\n        @looping = null\n        \n        ###*\n        * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n        * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n        * should have the largest z-index of all game objects.\n        * @property zIndex\n        * @type number\n        ###\n        @zIndex = -1\n        \n        ###*\n        * The object's alignment on x-axis. Needs to be supported by layout.\n        * @property alignmentX\n        * @type number\n        ###\n        @alignmentX = -1\n        \n        ###*\n        * The object's alignment on y-axis. Needs to be supported by layout.\n        * @property alignmentY\n        * @type number\n        ###\n        @alignmentY = -1\n        \n        ###*\n        * The object's resize behavior.\n        * @property resizable\n        * @type boolean\n        ###\n        @resizable = null\n        \n        ###*\n        * The original style descriptor.\n        * @property descriptor\n        * @type Object\n        ###\n        @descriptor = descriptor\n        \n        if descriptor\n            @setFromDescriptor(descriptor)\n\n    ###*\n    * Initializes the style from a style-descriptor.\n    *\n    * @method setFromDescriptor\n    * @param {Object} descriptor - The style-descriptor.\n    ### \n    setFromDescriptor: (descriptor) ->\n        @descriptor = descriptor\n        @image = descriptor.image\n        @color = gs.Color.fromArray(descriptor.color) if descriptor.color\n        @tone = gs.Tone.fromArray(descriptor.tone) if descriptor.tone\n        @anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]) if descriptor.anchor\n        @zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]) if descriptor.zoom\n        \n        if descriptor.font\n            @setupFont(descriptor)\n            \n        if descriptor.clipRect\n            @clipRect = gs.Rect.fromArray(descriptor.clipRect)\n            \n        @opacity = descriptor.opacity if descriptor.opacity >= 0\n        @alignment = descriptor.alignment if descriptor.alignment >= 0\n        @margin = ui.Space.fromArray(descriptor.margin) if descriptor.margin\n        @padding = ui.Space.fromArray(descriptor.padding) if descriptor.padding\n        @animations = descriptor.animations\n        @frameCornerSize = descriptor.frameCornerSize if descriptor.frameCornerSize\n        @frameThickness = descriptor.frameThickness if descriptor.frameThickness\n        @frame = descriptor.frame if descriptor.frame\n        @looping = descriptor.looping if descriptor.looping\n        @resizable = descriptor.resizable if descriptor.resizable?\n        @zIndex = descriptor.zIndex if descriptor.zIndex\n        @alignmentX = ui.UIManager.alignments[descriptor.alignmentX] if descriptor.alignmentX\n        @alignmentY = ui.UIManager.alignments[descriptor.alignmentY] if descriptor.alignmentY\n        \n    set: (style) ->\n        @image = style.image\n        @color.setFromObject(style.color)\n        @tone.setFromObject(style.tone)\n        @anchor.set(style.anchor.x, style.anchor.y)\n        @zoom.set(style.zoom.x, style.zoom.y)\n        \n        if style.font\n            if !@font then @font = new gs.Font(style.font.name, style.font.size)\n            @font.set(style.font)\n            \n        if style.clipRect\n            if !@clipRect then @clipRect = new gs.Rect()\n            @clipRect.setFromObject(style.clipRect)\n            \n        @opacity = style.opacitz\n        @alignment = style.alignment\n        @margin.setFromObject(style.margin)\n        @padding.setFromObject(style.padding)\n        \n    ###*\n    * Initializes font-data from a style-descriptor.\n    *\n    * @method setupFont\n    * @param {Object} descriptor - The style-descriptor.\n    * @protected\n    ### \n    setupFont: (descriptor) ->\n        if descriptor.font\n            if !@font\n                @font = new Font(descriptor.font.name, descriptor.font.size ? 0)\n            else\n                @font.name = descriptor.font.name\n                @font.size = descriptor.font.size ? 0\n                \n            @font.bold = descriptor.font.bold ? @font.bold\n            @font.italic = descriptor.font.italic ? @font.italic\n            @font.smallCaps = descriptor.font.smallCaps ? @font.smallCaps\n            @font.underline = descriptor.font.underline ? @font.underline\n            @font.strikeThrough = descriptor.font.strikeThrough ? @font.strikeThrough\n            \n            if descriptor.font.color?\n                @font.color.setFromArray(descriptor.font.color)\n            \n            if descriptor.font.border?\n                @font.border = descriptor.font.border ? no\n                @font.borderSize = descriptor.font.borderSize ? 4\n                @font.borderColor.set(0, 0, 0, 255)\n                \n            if descriptor.font.outline?\n                @font.border = descriptor.font.outline ? no\n                @font.borderSize = descriptor.font.outline.size ? 4\n                \n                if descriptor.font.outline.color?\n                    @font.borderColor.setFromArray(descriptor.font.outline.color)\n                else\n                    @font.borderColor.set(0, 0, 0, 255)\n    \n    ###*\n    * Applies the style to a UI object.\n    *\n    * @method apply\n    * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n    ###                \n    apply: (object) ->\n        if not object.activeStyles.contains(this)\n            object.activeStyles.push(this)\n            if @font then object.font?.set(@font)\n            if @color then object.color.set(@color)\n            if @tone then object.tone?.set(@tone)\n            if @image then object.image = @image\n            if @anchor then object.anchor.set(@anchor.x, @anchor.y)\n            if @zoom then object.zoom.set(@zoom.x, @zoom.y)\n            if @padding then object.padding.setFromObject(@padding)\n            if @margin then object.margin.setFromObject(@margin)\n            if @opacity >= 0 then object.opacity = @opacity\n            if @alignment >= 0 then object.alignment = @alignment\n            if @frameThickness >= 0 then object.frameThickness = @frameThickness\n            if @frameCornerSize >= 0 then object.frameCornerSize = @frameCornerSize\n            if @mask then object.mask.set(@mask)\n            if @zIndex >= 0 then object.zIndex = @zIndex\n            if @alignmentX >= 0 then object.alignmentX = @alignmentX\n            if @alignmentY >= 0 then object.alignmentY = @alignmentY\n            if @resizable? then object.resizable = @resizable\n            \n            @applyLooping(object)\n            @applyAnimations(object)\n     \n    ###*\n    * Applies the looping-data of the style to a UI object.\n    *\n    * @method applyLooping\n    * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n    * @protected\n    ###     \n    applyLooping: (object) ->\n        if @looping\n            if !object.visual.looping\n                object.visual.dispose()\n                object.removeComponent(object.visual)\n                object.visual = new gs.Component_TilingSprite()\n                object.addComponent(object.visual)\n            \n            object.visual.looping.vertical = @looping.vertical\n            object.visual.looping.horizontal = @looping.horizontal\n     \n    ###*\n    * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n    * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n    *\n    * @method applyAnimations\n    * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n    * @protected\n    ###        \n    applyAnimations: (object) ->\n        if @animations\n            object.animations = Object.deepCopy(@animations)\n            if !object.findComponentById(\"animationHandler\")\n                object.animationExecutor = new ui.Component_AnimationExecutor()\n                object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n                object.addComponent(object.animationExecutor, \"animationExecutor\")\n                \n      \n    ###*\n    * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n    * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n    * ui.Component_UIBehavior.\n    *\n    * @method revert\n    * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n    ###             \n    revert: (object) ->\n        activeStyles = object.activeStyles\n        if object.activeStyles.contains(this)\n            object.activeStyles.remove(this)\n            \n            if @font then object.font.set(gs.Fonts.TEXT);               (if s.font then object.font.set(s.font); break) for s in activeStyles by -1\n            if @color then object.color.set(Color.WHITE);               (if s.color then object.color.set(s.color); break) for s in activeStyles by -1\n            if @tone then object.tone?.set(0, 0, 0, 0);                 (if s.tone then object.tone?.set(s.tone); break) for s in activeStyles by -1\n            if @image then object.image = null;                         (if s.image then object.image = s.image; break) for s in activeStyles by -1\n            if @anchor then object.anchor.set(0, 0);                    (if s.anchor then object.anchor.setFromObject(s.anchor); break) for s in activeStyles by -1\n            if @zoom then object.zoom.set(1.0, 1.0);                    (if s.zoom then object.zoom.setFromObject(s.zoom); break) for s in activeStyles by -1\n            if @padding then object.padding.set(0, 0, 0, 0);            (if s.padding then object.padding.setFromObject(s.padding); break) for s in activeStyles by -1\n            if @margin then object.margin.set(0, 0, 0, 0);              (if s.margin then object.margin.setFromObject(s.margin); break) for s in activeStyles by -1\n            if @opacity >= 0 then object.opacity = 255;                 (if s.opacity >= 0 then object.opacity = s.opacity; break) for s in activeStyles by -1\n            if @alignment >= 0 then object.alignment = 0;               (if s.alignment >= 0 then object.alignment = s.alignment; break) for s in activeStyles by -1\n            if @frameCornerSize >= 0 then object.frameCornerSize = 16;  (if s.frameCornerSize >= 0 then object.frameCornerSize = s.frameCornerSize; break) for s in activeStyles by -1\n            if @frameThickness >= 0 then object.frameThickness = 16;    (if s.frameThickness >= 0 then object.frameThickness = s.frameThickness; break) for s in activeStyles by -1\n            if @mask then object.mask.set(null);                        (if s.mask then object.mask.set(s.font); break) for s in activeStyles by -1\n            if @zIndex >= 0 then object.zIndex = 0;                     (if s.zIndex >= 0 then object.zIndex = s.zIndex; break) for s in activeStyles by -1\n            if @alignmentX >= 0 then object.alignmentX = 0;             (if s.alignmentX >= 0 then object.alignmentX = s.alignmentX; break) for s in activeStyles by -1\n            if @alignmentY >= 0 then object.alignmentY = 0;             (if s.alignmentY >= 0 then object.alignmentY = s.alignmentY; break) for s in activeStyles by -1\n            if @resizable? then object.resizable = no;                  (if s.resizable? then object.resizable = s.resizable; break) for s in activeStyles by -1\n            \n            @revertAnimations(object)\n            @revertLooping(object)\n                    \n    ###*\n    * Reverts the animation-data changes applied to a UI object by this style.\n    *\n    * @method revertAnimations\n    * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n    ###                 \n    revertAnimations: (object) ->\n        activeStyles = object.activeStyles\n        if @animations\n            object.animations = null;               \n            for s in activeStyles by -1\n                if s.animations\n                    object.animations = Object.deepCopy(s.animations)\n                    if !object.findComponentById(\"animationHandler\")\n                        object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\")\n        \n    ###*\n    * Reverts the looping-data changes applied to a UI object by this style.\n    *\n    * @method revertLooping\n    * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n    ###                 \n    revertLooping: (object) ->\n        activeStyles = object.activeStyles\n        if @looping\n            object.visual.looping.vertical = no\n            object.visual.looping.horizontal = no\n            for s in activeStyles by -1\n                if s.looping\n                    if !object.visual.looping\n                        object.visual.dispose()\n                        object.removeComponent(object.visual)\n                        object.visual = new gs.Component_TilingSprite()\n                        object.addComponent(object.visual)\n                    \n                    object.visual.looping.vertical = s.looping.vertical\n                    object.visual.looping.horizontal = s.looping.horizontal\n            \nui.Style = Style\n\nclass UIManager\n    ###*\n    * Handles the creation of In Game UI elements. For more information about\n    * In-Game UI see help file.\n    *\n    * @module ui\n    * @class UIManager\n    * @memberof ui\n    * @constructor\n    ###\n    constructor: ->\n        ###*\n        * Stores all registered UI layouts by name/id.\n        * @property layouts\n        * @type Object\n        ###\n        @layouts = {}\n        \n        ###*\n        * Stores all registered UI styles by name/id.\n        * @property styles\n        * @type Object\n        ###\n        @styles = {}\n        \n        ###*\n        * Stores all UI styles by number id.\n        * @property stylesById\n        * @type ui.Style[]\n        ###\n        @stylesById = new Array()\n        \n        ###*\n        * Stores all UI styles by style-name.\n        * @property stylesByName\n        * @type Object\n        ###\n        @stylesByName = {}\n        \n        ###*\n        * Stores all registered custom UI types/templates by name/id.\n        * @property customTypes\n        * @type Object\n        ###\n        @customTypes = {}\n        \n        ###*\n        * Stores all registered UI controllers by name/id.\n        * @property customTypes\n        * @type Object\n        ###\n        @controllers = {}\n        \n        ###*\n        * Stores all registered UI data sources by name/id.\n        * @property customTypes\n        * @type Object\n        ###\n        @dataSources = {}\n        \n        ###*\n        * Mapping to table to map alignment names to number values.\n        * @property alignments\n        * @type Object\n        * @protected\n        ###\n        @alignments = { \"left\": 0, \"top\": 0, \"center\": 1, \"bottom\": 2, \"right\": 2, \"0\": 0, \"1\": 1, \"2\": 2 }\n        \n        ###*\n        * Mapping to table to map blend-mode names to number values.\n        * @property blendModes\n        * @type Object\n        * @protected\n        ###\n        @blendModes = { \"normal\": 0, \"add\": 1, \"sub\": 2 }\n        \n        ###*\n        * Mapping to table to map selector names to number values.\n        * @property selectors\n        * @type Object\n        ###\n        @selectors = { normal: 0, hover: 1, selected: 2, enabled: 3, focused: 4 }\n        @defaultPlaceholderParams = {}\n    \n    ###*\n    * Sets up UI Manager, optimizes styles, etc.\n    *\n    * @method setup\n    ###\n    setup: ->\n        @setupStyles()\n        \n    ###*\n    * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n    *\n    * @method setupStyles\n    * @protected\n    ###\n    setupStyles: ->\n        id = 0\n        selectorMap = @selectors\n        for k of @styles\n            subs = k.split(\" \")\n            selector = subs[0].split(\":\")\n            \n            if selectorMap[selector[1]]\n                @stylesById[id] = new ui.Style(@styles[k], id, selectorMap[selector[1]])\n            else\n                @stylesById[id] = new ui.Style(@styles[k], id, 0)\n            \n            if !@stylesByName[selector[0]]\n                @stylesByName[selector[0]] = []\n                \n            @stylesByName[selector[0]].push(@stylesById[id])\n            @styles[k] = @stylesById[id]\n            \n            id++\n        \n        for k of @styles\n            subs = k.split(\" \")\n            if subs.length > 1\n                @stylesByName[subs[1]].push(@styles[k])\n                @styles[k].target = @styles[k.split(\":\")[0]]?.id\n                #@styles[subs[1]].target = @styles[k].id\n                #@styles[k].target = @styles[subs[1]].id\n            \n        return null\n        \n    ###*\n    * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n    * and placeholder formulas are replaced with their evaluated result value.\n    *\n    * @method executePlaceholderFormulas\n    * @param {Object} descriptor - The descriptor.\n    * @param {Object} params - Object containing the placeholder params.\n    * @protected\n    ###    \n    executePlaceholderFormulas: (descriptor, id, params) ->\n        return if not descriptor?\n        keys = Object.keys(descriptor)\n            \n        for k in keys\n            v = descriptor[k]\n            if v?\n                if v instanceof Array\n                    for i, c in v\n                        if i?\n                            if typeof i == \"object\"\n                                @executePlaceholderFormulas(i, id, params)\n                            else if c != \"exec\" and typeof i == \"function\"\n                                window.p = params ||  @defaultPlaceholderParams\n                                window.d = descriptor\n                                v[c] = i()\n                else if typeof v == \"object\"\n                    @executePlaceholderFormulas(v, id, params)\n                else if k != \"exec_\" and typeof v == \"function\"\n                    window.p = params || @defaultPlaceholderParams\n                    window.d = descriptor\n                    descriptor[k] = v()\n        return null\n\n    ###*\n    * Creates a calculation for a specified expression.\n    *\n    * @method createCalcFunction\n    * @param {String} expression - The expression to create a calculation function for.\n    * @return {Function} The calculation function.\n    * @protected\n    ###               \n    createCalcFunction: (expression) ->\n        expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\")\n        return eval(\"(function(v){ return \" + expression + \"})\")\n    \n    ###*\n    * Creates an object from the specified object type. The type has the format\n    * <namespace>.<typename> like vn.Component_Hotspot.\n    *\n    * @method createObject\n    * @param {String} type - The type name.\n    * @return {Object} The created object.\n    * @protected\n    ###             \n    createObject: (type) ->\n        subs = type.split(\".\")\n        return new window[subs[0]][subs[1]]()\n      \n    ###*\n    * Creates an UI object from a specified UI descriptor.\n    *\n    * @method createFromDescriptor\n    * @param {Object} descriptor - The UI object descriptor.\n    * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n    * @return {gs.Object_UIElement} The created UI object.\n    ###   \n    createFromDescriptor: (descriptor, parent) ->\n        control = null\n        \n        for k of @controllers\n            if @controllers[k].type?\n                @controllers[k] = @createObject(@controllers[k].type)\n            \n        @_createFromDescriptor(descriptor, parent)\n    \n    \n    ###*\n    * Creates an image button UI object.\n    *\n    * @method createImageButton\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###  \n    createImageButton: (descriptor) ->\n        control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling) \n                \n        control.behavior.sound = descriptor.sound\n        control.behavior.sounds = descriptor.sounds\n        control.image = descriptor.image\n        control.images = descriptor.images\n        if descriptor.imageFolder?\n            control.imageFolder = descriptor.imageFolder\n            \n        if descriptor.looping?\n            control.visual.dispose()\n            control.removeComponent(control.visual)\n            control.visual = new gs.Component_TilingSprite()\n            control.addComponent(control.visual)\n            \n            control.visual.looping.vertical = descriptor.looping.vertical\n            control.visual.looping.horizontal = descriptor.looping.horizontal\n        if descriptor.color?\n            control.color = Color.fromArray(descriptor.color)\n    \n        return control\n    \n    ###*\n    * Creates an image UI object.\n    *\n    * @method createImage\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createImage: (descriptor) ->\n        control = new ui.Object_Image(descriptor.image, descriptor.imageHandling) \n                \n        if descriptor.imageFolder?\n            control.imageFolder = descriptor.imageFolder\n            \n        if descriptor.looping?\n            control.visual.dispose()\n            control.removeComponent(control.visual)\n            control.visual = new gs.Component_TilingSprite()\n            control.addComponent(control.visual)\n            \n            control.visual.looping.vertical = descriptor.looping.vertical\n            control.visual.looping.horizontal = descriptor.looping.horizontal\n        if descriptor.color?\n            control.color = Color.fromArray(descriptor.color)\n                    \n        return control\n    \n    ###*\n    * Creates an image map UI object.\n    *\n    * @method createImageMap\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###        \n    createImageMap: (descriptor) ->\n        control = new ui.Object_ImageMap()\n        control.hotspots = (descriptor.hotspots||[]).select (h) -> \n            { x: h.rect[0], y: h.rect[1], size: { width: h.rect[2], height: h.rect[3] }, data: { action: 3, actions: h.actions } }\n        control.images = descriptor.images\n        control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n        control.target = SceneManager.scene.behavior\n        control.visual.variableContext = new gs.InterpreterContext(SceneManager.scene.layoutName, SceneManager.scene)\n        \n        return control\n    \n    ###*\n    * Creates a video UI object.\n    *\n    * @method createVideo\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###    \n    createVideo: (descriptor) ->\n        control = new ui.Object_Video()\n        control.video = descriptor.video\n        control.loop = descriptor.loop ? yes\n        \n        return control\n    \n    \n    ###*\n    * Creates a panel UI object.\n    *\n    * @method createPanel\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###       \n    createPanel: (descriptor) ->\n        control = new ui.Object_Panel()\n        control.modal = descriptor.modal ? no\n        if descriptor.color?\n            control.color = Color.fromArray(descriptor.color)\n            \n        return control\n    \n    ###*\n    * Creates a frame UI object.\n    *\n    * @method createFrame\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###           \n    createFrame: (descriptor) ->\n        control = new ui.Object_Frame(descriptor.frameSkin)\n        control.frameThickness = descriptor.frameThickness || 16\n        control.frameCornerSize = descriptor.frameCornerSize || 16\n        control.image = descriptor.image\n        control.images = descriptor.images\n        \n        return control\n    \n    ###*\n    * Creates a three-part image UI object.\n    *\n    * @method createThreePartImage\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createThreePartImage: (descriptor) ->\n        control = new ui.Object_ThreePartImage(descriptor.frameSkin)\n        control.firstPartSize = descriptor.firstPartSize || 16\n        control.middlePartSize = descriptor.middlePartSize || 1\n        control.lastPartSize = descriptor.lastPartSize || 16\n        control.image = descriptor.image\n        control.images = descriptor.images\n        \n        return control\n     \n    ###*\n    * Creates a text UI object.\n    *\n    * @method createText\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createText: (descriptor) ->\n        control = new ui.Object_Text()\n        control.text = lcs(descriptor.text)\n        control.sizeToFit = descriptor.sizeToFit\n        control.formatting = descriptor.formatting\n        control.wordWrap = descriptor.wordWrap ? no\n        control.behavior.format = descriptor.format\n        if descriptor.textPadding\n            control.behavior.padding = ui.Space.fromArray(descriptor.textPadding)\n        if descriptor.resolvePlaceholders?\n            control.resolvePlaceholders = descriptor.resolvePlaceholders\n        if descriptor.color?\n            control.color = Color.fromArray(descriptor.color)\n            \n        return control\n    \n    ###*\n    * Creates a free-layout UI object.\n    *\n    * @method createFreeLayout\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ### \n    createFreeLayout: (descriptor) ->\n        if descriptor.frame?\n            control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1)\n        else\n            control = new ui.Object_FreeLayout(0, 0, 1, 1)\n        control.sizeToFit = descriptor.sizeToFit\n        \n        return control\n    \n    ###*\n    * Creates a stack-layout UI object.\n    *\n    * @method createStackLayout\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createStackLayout: (descriptor) ->\n        if descriptor.frame?\n            control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n        else\n            control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation)\n        control.sizeToFit = descriptor.sizeToFit\n        \n        return control\n    \n    ###*\n    * Creates a spread-layout UI object.\n    *\n    * @method createSpreadLayout\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createSpreadLayout: (descriptor) ->\n        if descriptor.frame?\n            control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)\n        else\n            control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation)\n            \n        return control\n     \n    ###*\n    * Creates a grid-layout UI object.\n    *\n    * @method createGridLayout\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###    \n    createGridLayout: (descriptor) ->\n        if descriptor.frame?\n            control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template)\n        else\n            control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template)\n        control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0]\n        control.sizeToFit = descriptor.sizeToFit\n        \n        return control\n     \n    ###*\n    * Creates a message UI object.\n    *\n    * @method createMessage\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###     \n    createMessage: (descriptor) ->\n        control = new ui.Object_Message() \n        \n        return control\n     \n    ###*\n    * Creates a data-grid UI object.\n    *\n    * @method createDataGrid\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created image button UI object.\n    ###    \n    createDataGrid: (descriptor) ->\n        control = new ui.Object_DataGrid(descriptor)\n        \n        return control\n        \n    ###*\n    * Creates an UI object depending on the object-type of the specified UI descriptor.\n    *\n    * @method createControl\n    * @param {Object} descriptor - The UI object descriptor.\n    * @return {gs.Object_UIElement} The created UI object.\n    * @protected\n    ###  \n    createControl: (descriptor) ->\n        control = null\n        \n        switch descriptor.type\n            when \"ui.ImageButton\"\n                control = @createImageButton(descriptor)\n            when \"ui.Image\"\n                control = @createImage(descriptor)\n            when \"ui.ImageMap\"\n                control = @createImageMap(descriptor)\n            when \"ui.Video\"\n                control = @createVideo(descriptor)\n            when \"ui.Panel\"\n                control = @createPanel(descriptor)\n            when \"ui.Frame\"\n                control = @createFrame(descriptor)\n            when \"ui.ThreePartImage\"\n                control = @createThreePartImage(descriptor)\n            when \"ui.Text\"\n                control = @createText(descriptor)\n            when \"ui.Message\"\n                control = @createMessage(descriptor)\n            when \"ui.DataGrid\"\n                control = @createDataGrid(descriptor)\n            when \"ui.FreeLayout\"\n                control = @createFreeLayout(descriptor)\n            when \"ui.StackLayout\"\n                control = @createStackLayout(descriptor)\n            when \"ui.SpreadLayout\"\n                control = @createSpreadLayout(descriptor)\n            when \"ui.GridLayout\"\n                control = @createGridLayout(descriptor)\n                \n        return control\n    \n    \n    createLayoutRect: (frame, control) ->\n        if !control.layoutRect\n            control.layoutRect = new ui.LayoutRect()\n        control.layoutRect.set(0, 0, 0, 0)\n        \n        if frame?\n            if frame[0]?.length?\n                control.layoutRect.x = @createCalcFunction(frame[0])\n                control.dstRect.x = 0\n            else\n                control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n                \n            if frame[1]?.length?\n                control.layoutRect.y = @createCalcFunction(frame[1])\n                control.dstRect.y = 0\n            else\n                control.dstRect.y = (frame[1] ? control.dstRect.y)\n                \n            if frame[2]?.length?\n                control.layoutRect.width = @createCalcFunction(frame[2])\n                control.dstRect.width = 1\n            else\n                control.dstRect.width = (frame[2] ? control.dstRect.width)\n                \n            if frame[3]?.length?\n                control.layoutRect.height = @createCalcFunction(frame[3])\n                control.dstRect.height = 1\n            else\n                control.dstRect.height = (frame[3] ? control.dstRect.height)\n     \n    \n    ###*\n    * Adds the styles defined in an array of style-names to the specified control.\n    *\n    * @method addControlStyles\n    * @param {Object} control - The control to add the styles to.\n    * @param {string[]} styles - Array of style-names to add.\n    ###     \n    addControlStyles: (control, styles) ->\n        for styleName in styles\n            if @stylesByName[styleName]?\n                for style in @stylesByName[styleName]\n                    control.styles.push(style)\n                    if style.target == -1 and style.selector == 0\n                        style.apply(control)\n    ###*\n    * Creates an UI object from a specified UI descriptor. This method is called\n    * recursively for all child-descriptors.\n    *\n    * @method createControlFromDescriptor\n    * @param {Object} descriptor - The UI object descriptor.\n    * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n    * @param {number} index - The index.\n    * @return {gs.Object_UIElement} The created UI object.\n    * @protected\n    ###        \n    createControlFromDescriptor: (descriptor, parent, index) ->\n        control = null\n        \n        if descriptor.style?\n            descriptor.styles = [descriptor.style]\n            delete descriptor.style\n            \n        descriptor = Object.deepCopy(descriptor)\n        @executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params)\n            \n        control = @createControl(descriptor)\n        \n        if not control?\n            type = Object.deepCopy(@customTypes[descriptor.type])\n            \n            @executePlaceholderFormulas(type, descriptor.id, descriptor.params)\n       \n            typeName = type.type\n            customFields = type.customFields\n            bindings = type.bindings\n            formulas = type.formulas\n            actions = type.actions\n            if type.style?\n                type.styles = [type.style]\n                type.style = null\n                \n            Object.mixin(type, descriptor)\n            if customFields? then Object.mixin(type.customFields, customFields)\n            if bindings? and bindings != type.bindings then type.bindings = type.bindings.concat(bindings)\n            if formulas? and formulas != type.formulas then type.formulas = type.formulas.concat(formulas)\n            if actions? and actions != type.actions then type.actions = actions.concat(type.actions)\n            type.type = typeName\n            \n            return @createControlFromDescriptor(type, parent)\n        else if parent?\n            parent.addObject(control)\n            control.index = index\n        else\n            gs.ObjectManager.current.addObject(control)\n         \n        control.ui = new ui.Component_UIBehavior()\n        control.addComponent(control.ui)\n        \n                \n                    \n        control.params = descriptor.params\n        \n        if descriptor.updateBehavior == \"continuous\"\n            control.updateBehavior = ui.UpdateBehavior.CONTINUOUS\n            \n        if descriptor.inheritProperties\n            control.inheritProperties = yes\n            \n        if descriptor.font?\n            control.font = new Font(descriptor.font.name, descriptor.font.size)\n            control.font.bold = descriptor.font.bold ? control.font.bold\n            control.font.italic = descriptor.font.italic ? control.font.italic\n            control.font.smallCaps = descriptor.font.smallCaps ? control.font.smallCaps\n            control.font.underline = descriptor.font.underline ? control.font.underline\n            control.font.strikeThrough = descriptor.font.strikeThrough ? control.font.strikeThrough\n            \n            if descriptor.font.color?\n                control.font.color = Color.fromArray(descriptor.font.color)\n            if descriptor.font.border?\n                control.font.border = descriptor.font.border ? no\n                control.font.borderSize = descriptor.font.borderSize ? 4\n              #if descriptor.font.border.color\n            #        control.font.borderColor = Color.fromArray(descriptor.font.border.color)\n                control.font.borderColor = new Color(0, 0, 0)\n                \n            if descriptor.font.outline?\n                control.font.border = descriptor.font.outline ? no\n                control.font.borderSize = descriptor.font.outline.size ? 4\n                \n                if descriptor.font.outline.color?\n                    control.font.borderColor = Color.fromArray(descriptor.font.outline.color)\n                else\n                    control.font.borderColor = new Color(0, 0, 0)\n                        \n        if descriptor.components?\n            for c in descriptor.components\n                m = c.module || \"gs\"\n                component = new window[m][c.type](c.params)\n                control.addComponent(component, c.id)\n                control[c.id] = component\n                #component.setup?()\n         \n        control.focusable = descriptor.focusable ? control.focusable       \n        if descriptor.nextKeyObject\n            control.ui.nextKeyObjectId = descriptor.nextKeyObject\n        \n        if descriptor.initialFocus\n            control.ui.focus()\n            \n        actions = Object.deepCopy(if descriptor.action? then [descriptor.action] else descriptor.actions) \n        if actions?\n            for action in actions\n                if action?\n                    action.event = action.event ? \"onAccept\"\n                    if not action.target?\n                        target = if @controllers? then @controllers[descriptor.target] else controller\n                        action.target = target || SceneManager.scene.behavior\n            \n            control.actions = actions\n            \n            if(!control.findComponentById(\"actionHandler\"))\n                control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\")\n        \n        if descriptor.id?\n            control.id = descriptor.id\n            gs.ObjectManager.current.setObjectById(control, control.id)\n            \n        control.descriptor = descriptor\n        control.layoutRect = new Rect()\n        control.layoutRect.set(0, 0, 0, 0)\n        if descriptor.frame?\n            if descriptor.frame[0]?.length?\n                control.layoutRect.x = @createCalcFunction(descriptor.frame[0])\n                control.dstRect.x = 0\n            else\n                control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)\n                \n            if descriptor.frame[1]?.length?\n                control.layoutRect.y = @createCalcFunction(descriptor.frame[1])\n                control.dstRect.y = 0\n            else\n                control.dstRect.y = (descriptor.frame[1] ? control.dstRect.y)\n                \n            if descriptor.frame[2]?.length?\n                control.layoutRect.width = @createCalcFunction(descriptor.frame[2])\n                control.dstRect.width = 1\n            else\n                control.dstRect.width = (descriptor.frame[2] ? control.dstRect.width)\n                \n            if descriptor.frame[3]?.length?\n                control.layoutRect.height = @createCalcFunction(descriptor.frame[3]) #parseInt(descriptor.frame[3].split(\"%\")[0])\n                control.dstRect.height = 1\n            else\n                control.dstRect.height = (descriptor.frame[3] ? control.dstRect.height)\n           \n        if descriptor.sizeToParent?\n            control.sizeToParent = descriptor.sizeToParent\n            \n        if descriptor.blendMode?\n            control.blendMode = @blendModes[descriptor.blendMode]\n            \n        if descriptor.anchor?\n            control.anchor.set(descriptor.anchor[0], descriptor.anchor[1])\n        \n\n        control.opacity = descriptor.opacity ? 255    \n        if descriptor.minimumSize?\n            control.minimumSize = { width: descriptor.minimumSize[0], height: descriptor.minimumSize[1] }\n            \n        if descriptor.resizable? then control.resizable = descriptor.resizable\n        if descriptor.scrollable? then control.scrollable = descriptor.scrollable \n        if descriptor.fixedSize? then control.fixedSize = descriptor.fixedSize\n        if descriptor.draggable?\n            control.draggable = descriptor.draggable\n            control.draggable.step = 0\n            if control.draggable.rect?\n                control.draggable.rect = Rect.fromArray(control.draggable.rect)\n            control.addComponent(new ui.Component_Draggable())\n        \n        if descriptor.bindings?\n            control.bindings = descriptor.bindings\n            control.insertComponent(new ui.Component_BindingHandler(), 0)\n            \n        if descriptor.formulas?\n            control.formulas = descriptor.formulas\n            control.insertComponent(new ui.Component_FormulaHandler(), 0)\n            \n        control.dataField = descriptor.dataField\n        control.enabled = descriptor.enabled ? yes\n        if descriptor.selectable? then control.selectable = descriptor.selectable\n        if descriptor.group? \n            control.group = descriptor.group\n            gs.ObjectManager.current.addToGroup(control, control.group)\n        \n        if descriptor.customFields?\n            control.customFields = Object.deepCopy(descriptor.customFields)\n            \n        if descriptor.margin?\n            control.margin.left = descriptor.margin[0]\n            control.margin.top = descriptor.margin[1]\n            control.margin.right = descriptor.margin[2]\n            control.margin.bottom = descriptor.margin[3]\n            \n        if descriptor.padding?\n            control.padding.left = descriptor.padding[0]\n            control.padding.top = descriptor.padding[1]\n            control.padding.right = descriptor.padding[2]\n            control.padding.bottom = descriptor.padding[3]\n            \n        if descriptor.alignment?\n            control.alignment = @alignments[descriptor.alignment]\n            \n        control.alignmentY = @alignments[descriptor.alignmentY || 0]\n        control.alignmentX = @alignments[descriptor.alignmentX || 0]\n        control.zIndex = descriptor.zIndex || 0\n        control.order = descriptor.order || 0\n        control.chainOrder = (descriptor.chainOrder ? descriptor.zOrder) + (parent?.chainOrder || 0)\n        if descriptor.zoom?\n            control.zoom = x: descriptor.zoom[0] / 100, y: descriptor.zoom[1] / 100\n        #control.dataFields = dataFields\n        #control.controllers = @controllers\n        #control.controller = controller\n        \n        if descriptor.visible?\n            control.visible = descriptor.visible\n        if descriptor.clipRect\n            control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height)\n\n        if descriptor.styles?\n            @addControlStyles(control, descriptor.styles)\n            \n                    \n        if descriptor.template?\n            control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode)\n            data = ui.Component_FormulaHandler.fieldValue(control, control.dataField) #control.dataFields[control.dataField]\n            isNumber = typeof data == \"number\"\n            if data?\n                for i in [0...(data.length ? data)]\n                    if data[i]? or isNumber\n                        valid = yes\n                        if descriptor.dataFilter? and not isNumber\n                            valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter)\n                        if valid or isNumber\n                            child = @createControlFromDescriptor(descriptor.template, control, i)\n                            #child.dataFields = control.dataFields\n                            \n                            if data[i]?.dstRect\n                                child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect)\n                            if (not child.clipRect?) and control.clipRect?\n                                child.clipRect = control.clipRect\n                            #child.parent = control\n                            control.addObject(child)\n                            child.index = i\n                            child.order = (data.length ? data) - i\n                            control.controls.push(child)\n                            \n        \n        if descriptor.controls and descriptor.controls.exec\n            controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls)\n        else\n            controls = descriptor.controls\n            \n        if controls?\n            for item, i in controls\n                childControl = @_createFromDescriptor(item, control, i)\n                if (not childControl.clipRect?) and control.clipRect?\n                    childControl.clipRect = control.clipRect\n                childControl.index = i\n                childControl.origin.x = control.origin.x + control.dstRect.x\n                childControl.origin.y = control.origin.y + control.dstRect.y\n                #childControl.parent = control\n                control.addObject(childControl)\n                control.controls.push(childControl)\n                \n        if control.styles and control.parentsByStyle\n            #for style in control.styles\n            \n            parent = control.parent\n            while parent\n                if parent.styles\n                    for style in parent.styles\n                        if !control.parentsByStyle[style.id]\n                            control.parentsByStyle[style.id] = []\n                        control.parentsByStyle[style.id].push(parent)\n                \n                #while parent\n                    #if parent.controlsByStyle\n                    #    if(!parent.controlsByStyle[style.id])\n                    #        parent.controlsByStyle[style.id] = []\n                    #    parent.controlsByStyle[style.id].push(control)\n                  #  if control.parentsByStyle\n                  #      if !control.parentsByStyle[style.id]\n                  #          control.parentsByStyle[style.id] = []\n                  #      control.parentsByStyle[style.id].push(parent)\n                parent = parent.parent\n                        \n        if descriptor.animations?\n            control.animations = Object.deepCopy(descriptor.animations)\n            control.animationExecutor = new ui.Component_AnimationExecutor()\n            control.addComponent(control.animationExecutor)\n            control.addComponent(new ui.Component_AnimationHandler())\n         \n        control.ui.updateStyle()\n        control.setup()\n        \n        return control\n        \n    ###*\n    * Creates an UI object from a specified UI descriptor.\n    *\n    * @method _createFromDescriptor\n    * @param {Object} descriptor - The UI object descriptor.\n    * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n    * @return {gs.Object_UIElement} The created UI object.\n    * @protected \n    ###   \n    _createFromDescriptor: (descriptor, parent, index) ->     \n        control = @createControlFromDescriptor(descriptor, parent, index)\n        \n        if descriptor.controller?\n            controller = @controllers[descriptor.controller]\n            control.controller = controller\n            control.addComponent(controller)\n                \n        return control\n        \n    createLayoutFromDescriptor: (descriptor, parent, index) ->\n        @_createFromDescriptor(descriptor, parent, index)\n        \n                \n        \nGraphics.width = $PARAMS.resolution.width\nGraphics.height = $PARAMS.resolution.height\nui.UiFactory = new UIManager()\nui.UIManager = ui.UiFactory",
        "parentId": "C0268943K60B3A42B7SA6F1EDDCF2F642FD7",
        "folder": false,
        "compiledContent": "var Formula, Space, Style, UIManager;\n\nFormula = (function() {\n\n  /**\n  * Encapsulates a UI formula. A formula can be used in UI layouts to define\n  * property-bindings or to implement a specific behavior.\n  *\n  * @module ui\n  * @class Formula\n  * @memberof ui\n  * @constructor\n  * @param {Function} f - The formula-function. Defines the logic of the formula.\n  * @param {Object} data - An optional data-object which can be accessed inside the formula-function.\n  * @param {string} event - An optional event-name to define when the formula should be executed.\n   */\n  function Formula(f, data, event) {\n\n    /**\n    * Indicates if its the first time the formula is called.\n    * @property onInitialize\n    * @type boolean\n     */\n    var i, j, l, ref, ref1;\n    this.onInitialize = true;\n\n    /**\n    * The formula-function.\n    * @property exec_\n    * @type Function\n     */\n    this.exec_ = f;\n\n    /**\n    * An optional data-object which can bes accessed inside the formula-function.\n    * @property data\n    * @type Object\n     */\n    this.data = data;\n\n    /**\n    * An optional event-name to define when the formula should be executed.\n    * @property event\n    * @type string\n     */\n    this.event = event;\n\n    /**\n    * An array of custom number-data which can be used for different purposes. The first element\n    * is also used in onChange method to store the old value and check against the new one to detect a change.\n    * @property numbers\n    * @type number[]\n     */\n    this.numbers = new Array(10);\n    for (i = j = 0, ref = this.numbers.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {\n      this.numbers[i] = 0;\n    }\n\n    /**\n    * An array of custom string-data which can be used for different purposes. The first element\n    * is also used in onTextChange method to store the old value and check against the new one to detect a change.\n    * @property strings\n    * @type string[]\n     */\n    this.strings = new Array(10);\n    for (i = l = 0, ref1 = this.strings.length; 0 <= ref1 ? l <= ref1 : l >= ref1; i = 0 <= ref1 ? ++l : --l) {\n      this.strings[i] = \"\";\n    }\n  }\n\n\n  /**\n  * The formula-function. Its a wrapper-function before the first-time call was made.\n  * @method exec\n   */\n\n  Formula.prototype.exec = function() {\n    var r;\n    this.exec = this.exec_;\n    r = this.exec_.apply(this, arguments);\n    this.onInitialize = false;\n    return r;\n  };\n\n\n  /**\n  * Checks if the specified number-value has changed since the last check. It uses\n  * the first entry of the numbers-array to store the value and check against the new one.\n  *\n  * @method onChange\n  * @param {number} numberValue - Number value to check.\n   */\n\n  Formula.prototype.onChange = function(numberValue) {\n    var result;\n    result = this.numbers[0] !== numberValue;\n    this.numbers[0] = numberValue;\n    return result;\n  };\n\n\n  /**\n  * Checks if the specified text-value has changed since the last check. It uses\n  * the first entry of the strings-array to store the value and check against the new one.\n  *\n  * @method onTextChange\n  * @param {string} textValue - Text value to check.\n   */\n\n  Formula.prototype.onTextChange = function(textValue) {\n    var result;\n    result = this.strings[0] !== textValue;\n    this.strings[0] = textValue;\n    return result;\n  };\n\n  return Formula;\n\n})();\n\nui.Formula = Formula;\n\nSpace = (function() {\n\n  /**\n  * Describes a space inside or around something like a margin or padding.\n  *\n  * @module ui\n  * @class Space\n  * @memberof ui\n  * @constructor\n  * @param {number} left - Space at the left in pixels.\n  * @param {number} top - Space at the top in pixels.\n  * @param {number} right - Space at the right in pixels.\n  * @param {number} bottom - Space at the bottom in pixels.\n   */\n  function Space(left, top, right, bottom) {\n\n    /**\n    * Space at the left in pixels.\n    * @property left\n    * @type number\n     */\n    this.left = left;\n\n    /**\n    * Space at the top in pixels.\n    * @property top\n    * @type number\n     */\n    this.top = top;\n\n    /**\n    * Space at the right in pixels.\n    * @property right\n    * @type number\n     */\n    this.right = right;\n\n    /**\n    * Space at the bottom in pixels.\n    * @property bottom\n    * @type number\n     */\n    this.bottom = bottom;\n  }\n\n\n  /**\n  * Sets the coordinates of the space by copying them from a specified space.\n  *\n  * @method setFromObject\n  * @param {Object} space - A space to copy.\n   */\n\n  Space.prototype.setFromObject = function(space) {\n    this.left = space.left;\n    this.top = space.top;\n    this.right = space.right;\n    return this.bottom = space.bottom;\n  };\n\n\n  /**\n  * Sets the coordinates of the space.\n  *\n  * @method set\n  * @param {number} left - Space at the left in pixels.\n  * @param {number} top - Space at the top in pixels.\n  * @param {number} right - Space at the right in pixels.\n  * @param {number} bottom - Space at the bottom in pixels.\n   */\n\n  Space.prototype.set = function(left, top, right, bottom) {\n    this.left = left;\n    this.top = top;\n    this.right = right;\n    return this.bottom = bottom;\n  };\n\n\n  /**\n  * Creates a new space object from an array of coordinates.\n  *\n  * @method fromArray\n  * @static\n  * @param {number[]} array - An array of coordinates (left, top right, bottom).\n   */\n\n  Space.fromArray = function(array) {\n    return new ui.Space(array[0], array[1], array[2], array[3]);\n  };\n\n  return Space;\n\n})();\n\nui.Space = Space;\n\nStyle = (function() {\n\n  /**\n  * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain \"style\" to it.\n  *\n  * @module ui\n  * @class Style\n  * @memberof ui\n  * @constructor\n  * @param {Object} descriptor - A style-descriptor to initialize the style from.\n  * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.\n  * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.\n   */\n  function Style(descriptor, id, selector) {\n\n    /**\n    * ID number to quickly access this style and link to this style.\n    * @property id\n    * @type number\n     */\n    this.id = id;\n\n    /**\n    * Style-ID of target object. This style will only be applied on UI objects with that style ID which are\n    * children of UI objects where this style is applied.\n    * @property target\n    * @type number\n     */\n    this.target = -1;\n\n    /**\n    * Selector-ID which controls under which conditions the style becomes active.\n    * @property selector\n    * @type number\n     */\n    this.selector = selector;\n\n    /**\n    * The font used for the text-display.\n    * @default null\n    * @property font\n    * @type gs.Font\n     */\n    this.font = null;\n\n    /**\n    * The UI object's image used for visual presentation.\n    * @property image\n    * @type string\n     */\n    this.image = null;\n\n    /**\n    * The UI object's animations used for visual presentation.\n    * @default null\n    * @property animations\n    * @type Object[]\n     */\n    this.animations = null;\n\n    /**\n    * The UI object's color.\n    * @property color\n    * @type gs.Color\n     */\n    this.color = null;\n\n    /**\n    * The UI object's tone.\n    * @property tone\n    * @type gs.Tone\n     */\n    this.tone = null;\n\n    /**\n    * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner\n    * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1\n    * places the object with its lower-right corner.\n    * @property anchor\n    * @type gs.Point\n     */\n    this.anchor = null;\n\n    /**\n    * The UI object's zoom-setting for x and y axis.\n    * @default new gs.Point(1.0, 1.0)\n    * @property zoom\n    * @type gs.Point\n     */\n    this.zoom = null;\n\n    /**\n    * The UI object's margin. The margin defines an extra space around the UI object. \n    * The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n    * @property margin\n    * @type Object\n     */\n    this.margin = null;\n\n    /**\n    * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.\n    * @property padding\n    * @type Object\n     */\n    this.padding = null;\n\n    /**\n    * The UI object's mask for masking-effects.\n    * @property mask\n    * @type gs.Mask\n     */\n    this.mask = null;\n\n    /**\n    * The UI object's alignment.\n    * @property alignment\n    * @type ui.Alignment\n     */\n    this.alignment = -1;\n\n    /**\n    * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.\n    * @property opacity\n    * @type number\n     */\n    this.opacity = -1;\n\n    /**\n    * The object's clip-rect for visual presentation.\n    * @default null\n    * @property clipRect\n    * @type gs.Rect\n    * @protected\n     */\n    this.clipRect = null;\n\n    /**\n    * The corner-size of the frame.\n    * @property frameCornerSize\n    * @type number\n     */\n    this.frameCornerSize = -1;\n\n    /**\n    * The thickness of the frame.\n    * @property frameThickness\n    * @type number\n     */\n    this.frameThickness = -1;\n\n    /**\n    * The looping of the image.\n    * @property looping\n    * @type ui.Orientation\n     */\n    this.looping = null;\n\n    /**\n    * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered\n    * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it\n    * should have the largest z-index of all game objects.\n    * @property zIndex\n    * @type number\n     */\n    this.zIndex = -1;\n\n    /**\n    * The object's alignment on x-axis. Needs to be supported by layout.\n    * @property alignmentX\n    * @type number\n     */\n    this.alignmentX = -1;\n\n    /**\n    * The object's alignment on y-axis. Needs to be supported by layout.\n    * @property alignmentY\n    * @type number\n     */\n    this.alignmentY = -1;\n\n    /**\n    * The object's resize behavior.\n    * @property resizable\n    * @type boolean\n     */\n    this.resizable = null;\n\n    /**\n    * The original style descriptor.\n    * @property descriptor\n    * @type Object\n     */\n    this.descriptor = descriptor;\n    if (descriptor) {\n      this.setFromDescriptor(descriptor);\n    }\n  }\n\n\n  /**\n  * Initializes the style from a style-descriptor.\n  *\n  * @method setFromDescriptor\n  * @param {Object} descriptor - The style-descriptor.\n   */\n\n  Style.prototype.setFromDescriptor = function(descriptor) {\n    this.descriptor = descriptor;\n    this.image = descriptor.image;\n    if (descriptor.color) {\n      this.color = gs.Color.fromArray(descriptor.color);\n    }\n    if (descriptor.tone) {\n      this.tone = gs.Tone.fromArray(descriptor.tone);\n    }\n    if (descriptor.anchor) {\n      this.anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]);\n    }\n    if (descriptor.zoom) {\n      this.zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]);\n    }\n    if (descriptor.font) {\n      this.setupFont(descriptor);\n    }\n    if (descriptor.clipRect) {\n      this.clipRect = gs.Rect.fromArray(descriptor.clipRect);\n    }\n    if (descriptor.opacity >= 0) {\n      this.opacity = descriptor.opacity;\n    }\n    if (descriptor.alignment >= 0) {\n      this.alignment = descriptor.alignment;\n    }\n    if (descriptor.margin) {\n      this.margin = ui.Space.fromArray(descriptor.margin);\n    }\n    if (descriptor.padding) {\n      this.padding = ui.Space.fromArray(descriptor.padding);\n    }\n    this.animations = descriptor.animations;\n    if (descriptor.frameCornerSize) {\n      this.frameCornerSize = descriptor.frameCornerSize;\n    }\n    if (descriptor.frameThickness) {\n      this.frameThickness = descriptor.frameThickness;\n    }\n    if (descriptor.frame) {\n      this.frame = descriptor.frame;\n    }\n    if (descriptor.looping) {\n      this.looping = descriptor.looping;\n    }\n    if (descriptor.resizable != null) {\n      this.resizable = descriptor.resizable;\n    }\n    if (descriptor.zIndex) {\n      this.zIndex = descriptor.zIndex;\n    }\n    if (descriptor.alignmentX) {\n      this.alignmentX = ui.UIManager.alignments[descriptor.alignmentX];\n    }\n    if (descriptor.alignmentY) {\n      return this.alignmentY = ui.UIManager.alignments[descriptor.alignmentY];\n    }\n  };\n\n  Style.prototype.set = function(style) {\n    this.image = style.image;\n    this.color.setFromObject(style.color);\n    this.tone.setFromObject(style.tone);\n    this.anchor.set(style.anchor.x, style.anchor.y);\n    this.zoom.set(style.zoom.x, style.zoom.y);\n    if (style.font) {\n      if (!this.font) {\n        this.font = new gs.Font(style.font.name, style.font.size);\n      }\n      this.font.set(style.font);\n    }\n    if (style.clipRect) {\n      if (!this.clipRect) {\n        this.clipRect = new gs.Rect();\n      }\n      this.clipRect.setFromObject(style.clipRect);\n    }\n    this.opacity = style.opacitz;\n    this.alignment = style.alignment;\n    this.margin.setFromObject(style.margin);\n    return this.padding.setFromObject(style.padding);\n  };\n\n\n  /**\n  * Initializes font-data from a style-descriptor.\n  *\n  * @method setupFont\n  * @param {Object} descriptor - The style-descriptor.\n  * @protected\n   */\n\n  Style.prototype.setupFont = function(descriptor) {\n    var ref, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9;\n    if (descriptor.font) {\n      if (!this.font) {\n        this.font = new Font(descriptor.font.name, (ref = descriptor.font.size) != null ? ref : 0);\n      } else {\n        this.font.name = descriptor.font.name;\n        this.font.size = (ref1 = descriptor.font.size) != null ? ref1 : 0;\n      }\n      this.font.bold = (ref2 = descriptor.font.bold) != null ? ref2 : this.font.bold;\n      this.font.italic = (ref3 = descriptor.font.italic) != null ? ref3 : this.font.italic;\n      this.font.smallCaps = (ref4 = descriptor.font.smallCaps) != null ? ref4 : this.font.smallCaps;\n      this.font.underline = (ref5 = descriptor.font.underline) != null ? ref5 : this.font.underline;\n      this.font.strikeThrough = (ref6 = descriptor.font.strikeThrough) != null ? ref6 : this.font.strikeThrough;\n      if (descriptor.font.color != null) {\n        this.font.color.setFromArray(descriptor.font.color);\n      }\n      if (descriptor.font.border != null) {\n        this.font.border = (ref7 = descriptor.font.border) != null ? ref7 : false;\n        this.font.borderSize = (ref8 = descriptor.font.borderSize) != null ? ref8 : 4;\n        this.font.borderColor.set(0, 0, 0, 255);\n      }\n      if (descriptor.font.outline != null) {\n        this.font.border = (ref9 = descriptor.font.outline) != null ? ref9 : false;\n        this.font.borderSize = (ref10 = descriptor.font.outline.size) != null ? ref10 : 4;\n        if (descriptor.font.outline.color != null) {\n          return this.font.borderColor.setFromArray(descriptor.font.outline.color);\n        } else {\n          return this.font.borderColor.set(0, 0, 0, 255);\n        }\n      }\n    }\n  };\n\n\n  /**\n  * Applies the style to a UI object.\n  *\n  * @method apply\n  * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.\n   */\n\n  Style.prototype.apply = function(object) {\n    var ref, ref1;\n    if (!object.activeStyles.contains(this)) {\n      object.activeStyles.push(this);\n      if (this.font) {\n        if ((ref = object.font) != null) {\n          ref.set(this.font);\n        }\n      }\n      if (this.color) {\n        object.color.set(this.color);\n      }\n      if (this.tone) {\n        if ((ref1 = object.tone) != null) {\n          ref1.set(this.tone);\n        }\n      }\n      if (this.image) {\n        object.image = this.image;\n      }\n      if (this.anchor) {\n        object.anchor.set(this.anchor.x, this.anchor.y);\n      }\n      if (this.zoom) {\n        object.zoom.set(this.zoom.x, this.zoom.y);\n      }\n      if (this.padding) {\n        object.padding.setFromObject(this.padding);\n      }\n      if (this.margin) {\n        object.margin.setFromObject(this.margin);\n      }\n      if (this.opacity >= 0) {\n        object.opacity = this.opacity;\n      }\n      if (this.alignment >= 0) {\n        object.alignment = this.alignment;\n      }\n      if (this.frameThickness >= 0) {\n        object.frameThickness = this.frameThickness;\n      }\n      if (this.frameCornerSize >= 0) {\n        object.frameCornerSize = this.frameCornerSize;\n      }\n      if (this.mask) {\n        object.mask.set(this.mask);\n      }\n      if (this.zIndex >= 0) {\n        object.zIndex = this.zIndex;\n      }\n      if (this.alignmentX >= 0) {\n        object.alignmentX = this.alignmentX;\n      }\n      if (this.alignmentY >= 0) {\n        object.alignmentY = this.alignmentY;\n      }\n      if (this.resizable != null) {\n        object.resizable = this.resizable;\n      }\n      this.applyLooping(object);\n      return this.applyAnimations(object);\n    }\n  };\n\n\n  /**\n  * Applies the looping-data of the style to a UI object.\n  *\n  * @method applyLooping\n  * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.\n  * @protected\n   */\n\n  Style.prototype.applyLooping = function(object) {\n    if (this.looping) {\n      if (!object.visual.looping) {\n        object.visual.dispose();\n        object.removeComponent(object.visual);\n        object.visual = new gs.Component_TilingSprite();\n        object.addComponent(object.visual);\n      }\n      object.visual.looping.vertical = this.looping.vertical;\n      return object.visual.looping.horizontal = this.looping.horizontal;\n    }\n  };\n\n\n  /**\n  * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler\n  * component(ui.Component_AnimationHandler) with the id \"animationHandler\" to the UI object if not already exists.\n  *\n  * @method applyAnimations\n  * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.\n  * @protected\n   */\n\n  Style.prototype.applyAnimations = function(object) {\n    if (this.animations) {\n      object.animations = Object.deepCopy(this.animations);\n      if (!object.findComponentById(\"animationHandler\")) {\n        object.animationExecutor = new ui.Component_AnimationExecutor();\n        object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\");\n        return object.addComponent(object.animationExecutor, \"animationExecutor\");\n      }\n    }\n  };\n\n\n  /**\n  * Reverts the changes from a UI object made by this style. However, this resets all styleable properties\n  * were set by this style. So it is necessary to apply all other styles again, but that is already handles in\n  * ui.Component_UIBehavior.\n  *\n  * @method revert\n  * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.\n   */\n\n  Style.prototype.revert = function(object) {\n    var activeStyles, i1, j, j1, k1, l, l1, m1, n, o, p, q, ref, ref1, s, t, u, w, x, y, z;\n    activeStyles = object.activeStyles;\n    if (object.activeStyles.contains(this)) {\n      object.activeStyles.remove(this);\n      if (this.font) {\n        object.font.set(gs.Fonts.TEXT);\n        for (j = activeStyles.length - 1; j >= 0; j += -1) {\n          s = activeStyles[j];\n          if (s.font) {\n            object.font.set(s.font);\n            break;\n          }\n        }\n      }\n      if (this.color) {\n        object.color.set(Color.WHITE);\n        for (l = activeStyles.length - 1; l >= 0; l += -1) {\n          s = activeStyles[l];\n          if (s.color) {\n            object.color.set(s.color);\n            break;\n          }\n        }\n      }\n      if (this.tone) {\n        if ((ref = object.tone) != null) {\n          ref.set(0, 0, 0, 0);\n        }\n        for (n = activeStyles.length - 1; n >= 0; n += -1) {\n          s = activeStyles[n];\n          if (s.tone) {\n            if ((ref1 = object.tone) != null) {\n              ref1.set(s.tone);\n            }\n            break;\n          }\n        }\n      }\n      if (this.image) {\n        object.image = null;\n        for (o = activeStyles.length - 1; o >= 0; o += -1) {\n          s = activeStyles[o];\n          if (s.image) {\n            object.image = s.image;\n            break;\n          }\n        }\n      }\n      if (this.anchor) {\n        object.anchor.set(0, 0);\n        for (p = activeStyles.length - 1; p >= 0; p += -1) {\n          s = activeStyles[p];\n          if (s.anchor) {\n            object.anchor.setFromObject(s.anchor);\n            break;\n          }\n        }\n      }\n      if (this.zoom) {\n        object.zoom.set(1.0, 1.0);\n        for (q = activeStyles.length - 1; q >= 0; q += -1) {\n          s = activeStyles[q];\n          if (s.zoom) {\n            object.zoom.setFromObject(s.zoom);\n            break;\n          }\n        }\n      }\n      if (this.padding) {\n        object.padding.set(0, 0, 0, 0);\n        for (t = activeStyles.length - 1; t >= 0; t += -1) {\n          s = activeStyles[t];\n          if (s.padding) {\n            object.padding.setFromObject(s.padding);\n            break;\n          }\n        }\n      }\n      if (this.margin) {\n        object.margin.set(0, 0, 0, 0);\n        for (u = activeStyles.length - 1; u >= 0; u += -1) {\n          s = activeStyles[u];\n          if (s.margin) {\n            object.margin.setFromObject(s.margin);\n            break;\n          }\n        }\n      }\n      if (this.opacity >= 0) {\n        object.opacity = 255;\n        for (w = activeStyles.length - 1; w >= 0; w += -1) {\n          s = activeStyles[w];\n          if (s.opacity >= 0) {\n            object.opacity = s.opacity;\n            break;\n          }\n        }\n      }\n      if (this.alignment >= 0) {\n        object.alignment = 0;\n        for (x = activeStyles.length - 1; x >= 0; x += -1) {\n          s = activeStyles[x];\n          if (s.alignment >= 0) {\n            object.alignment = s.alignment;\n            break;\n          }\n        }\n      }\n      if (this.frameCornerSize >= 0) {\n        object.frameCornerSize = 16;\n        for (y = activeStyles.length - 1; y >= 0; y += -1) {\n          s = activeStyles[y];\n          if (s.frameCornerSize >= 0) {\n            object.frameCornerSize = s.frameCornerSize;\n            break;\n          }\n        }\n      }\n      if (this.frameThickness >= 0) {\n        object.frameThickness = 16;\n        for (z = activeStyles.length - 1; z >= 0; z += -1) {\n          s = activeStyles[z];\n          if (s.frameThickness >= 0) {\n            object.frameThickness = s.frameThickness;\n            break;\n          }\n        }\n      }\n      if (this.mask) {\n        object.mask.set(null);\n        for (i1 = activeStyles.length - 1; i1 >= 0; i1 += -1) {\n          s = activeStyles[i1];\n          if (s.mask) {\n            object.mask.set(s.font);\n            break;\n          }\n        }\n      }\n      if (this.zIndex >= 0) {\n        object.zIndex = 0;\n        for (j1 = activeStyles.length - 1; j1 >= 0; j1 += -1) {\n          s = activeStyles[j1];\n          if (s.zIndex >= 0) {\n            object.zIndex = s.zIndex;\n            break;\n          }\n        }\n      }\n      if (this.alignmentX >= 0) {\n        object.alignmentX = 0;\n        for (k1 = activeStyles.length - 1; k1 >= 0; k1 += -1) {\n          s = activeStyles[k1];\n          if (s.alignmentX >= 0) {\n            object.alignmentX = s.alignmentX;\n            break;\n          }\n        }\n      }\n      if (this.alignmentY >= 0) {\n        object.alignmentY = 0;\n        for (l1 = activeStyles.length - 1; l1 >= 0; l1 += -1) {\n          s = activeStyles[l1];\n          if (s.alignmentY >= 0) {\n            object.alignmentY = s.alignmentY;\n            break;\n          }\n        }\n      }\n      if (this.resizable != null) {\n        object.resizable = false;\n        for (m1 = activeStyles.length - 1; m1 >= 0; m1 += -1) {\n          s = activeStyles[m1];\n          if (s.resizable != null) {\n            object.resizable = s.resizable;\n            break;\n          }\n        }\n      }\n      this.revertAnimations(object);\n      return this.revertLooping(object);\n    }\n  };\n\n\n  /**\n  * Reverts the animation-data changes applied to a UI object by this style.\n  *\n  * @method revertAnimations\n  * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.\n   */\n\n  Style.prototype.revertAnimations = function(object) {\n    var activeStyles, j, results, s;\n    activeStyles = object.activeStyles;\n    if (this.animations) {\n      object.animations = null;\n      results = [];\n      for (j = activeStyles.length - 1; j >= 0; j += -1) {\n        s = activeStyles[j];\n        if (s.animations) {\n          object.animations = Object.deepCopy(s.animations);\n          if (!object.findComponentById(\"animationHandler\")) {\n            results.push(object.addComponent(new ui.Component_AnimationHandler(), \"animationHandler\"));\n          } else {\n            results.push(void 0);\n          }\n        } else {\n          results.push(void 0);\n        }\n      }\n      return results;\n    }\n  };\n\n\n  /**\n  * Reverts the looping-data changes applied to a UI object by this style.\n  *\n  * @method revertLooping\n  * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.\n   */\n\n  Style.prototype.revertLooping = function(object) {\n    var activeStyles, j, results, s;\n    activeStyles = object.activeStyles;\n    if (this.looping) {\n      object.visual.looping.vertical = false;\n      object.visual.looping.horizontal = false;\n      results = [];\n      for (j = activeStyles.length - 1; j >= 0; j += -1) {\n        s = activeStyles[j];\n        if (s.looping) {\n          if (!object.visual.looping) {\n            object.visual.dispose();\n            object.removeComponent(object.visual);\n            object.visual = new gs.Component_TilingSprite();\n            object.addComponent(object.visual);\n          }\n          object.visual.looping.vertical = s.looping.vertical;\n          results.push(object.visual.looping.horizontal = s.looping.horizontal);\n        } else {\n          results.push(void 0);\n        }\n      }\n      return results;\n    }\n  };\n\n  return Style;\n\n})();\n\nui.Style = Style;\n\nUIManager = (function() {\n\n  /**\n  * Handles the creation of In Game UI elements. For more information about\n  * In-Game UI see help file.\n  *\n  * @module ui\n  * @class UIManager\n  * @memberof ui\n  * @constructor\n   */\n  function UIManager() {\n\n    /**\n    * Stores all registered UI layouts by name/id.\n    * @property layouts\n    * @type Object\n     */\n    this.layouts = {};\n\n    /**\n    * Stores all registered UI styles by name/id.\n    * @property styles\n    * @type Object\n     */\n    this.styles = {};\n\n    /**\n    * Stores all UI styles by number id.\n    * @property stylesById\n    * @type ui.Style[]\n     */\n    this.stylesById = new Array();\n\n    /**\n    * Stores all UI styles by style-name.\n    * @property stylesByName\n    * @type Object\n     */\n    this.stylesByName = {};\n\n    /**\n    * Stores all registered custom UI types/templates by name/id.\n    * @property customTypes\n    * @type Object\n     */\n    this.customTypes = {};\n\n    /**\n    * Stores all registered UI controllers by name/id.\n    * @property customTypes\n    * @type Object\n     */\n    this.controllers = {};\n\n    /**\n    * Stores all registered UI data sources by name/id.\n    * @property customTypes\n    * @type Object\n     */\n    this.dataSources = {};\n\n    /**\n    * Mapping to table to map alignment names to number values.\n    * @property alignments\n    * @type Object\n    * @protected\n     */\n    this.alignments = {\n      \"left\": 0,\n      \"top\": 0,\n      \"center\": 1,\n      \"bottom\": 2,\n      \"right\": 2,\n      \"0\": 0,\n      \"1\": 1,\n      \"2\": 2\n    };\n\n    /**\n    * Mapping to table to map blend-mode names to number values.\n    * @property blendModes\n    * @type Object\n    * @protected\n     */\n    this.blendModes = {\n      \"normal\": 0,\n      \"add\": 1,\n      \"sub\": 2\n    };\n\n    /**\n    * Mapping to table to map selector names to number values.\n    * @property selectors\n    * @type Object\n     */\n    this.selectors = {\n      normal: 0,\n      hover: 1,\n      selected: 2,\n      enabled: 3,\n      focused: 4\n    };\n    this.defaultPlaceholderParams = {};\n  }\n\n\n  /**\n  * Sets up UI Manager, optimizes styles, etc.\n  *\n  * @method setup\n   */\n\n  UIManager.prototype.setup = function() {\n    return this.setupStyles();\n  };\n\n\n  /**\n  * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.\n  *\n  * @method setupStyles\n  * @protected\n   */\n\n  UIManager.prototype.setupStyles = function() {\n    var id, k, ref, selector, selectorMap, subs;\n    id = 0;\n    selectorMap = this.selectors;\n    for (k in this.styles) {\n      subs = k.split(\" \");\n      selector = subs[0].split(\":\");\n      if (selectorMap[selector[1]]) {\n        this.stylesById[id] = new ui.Style(this.styles[k], id, selectorMap[selector[1]]);\n      } else {\n        this.stylesById[id] = new ui.Style(this.styles[k], id, 0);\n      }\n      if (!this.stylesByName[selector[0]]) {\n        this.stylesByName[selector[0]] = [];\n      }\n      this.stylesByName[selector[0]].push(this.stylesById[id]);\n      this.styles[k] = this.stylesById[id];\n      id++;\n    }\n    for (k in this.styles) {\n      subs = k.split(\" \");\n      if (subs.length > 1) {\n        this.stylesByName[subs[1]].push(this.styles[k]);\n        this.styles[k].target = (ref = this.styles[k.split(\":\")[0]]) != null ? ref.id : void 0;\n      }\n    }\n    return null;\n  };\n\n\n  /**\n  * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed\n  * and placeholder formulas are replaced with their evaluated result value.\n  *\n  * @method executePlaceholderFormulas\n  * @param {Object} descriptor - The descriptor.\n  * @param {Object} params - Object containing the placeholder params.\n  * @protected\n   */\n\n  UIManager.prototype.executePlaceholderFormulas = function(descriptor, id, params) {\n    var c, i, j, k, keys, l, len, len1, v;\n    if (descriptor == null) {\n      return;\n    }\n    keys = Object.keys(descriptor);\n    for (j = 0, len = keys.length; j < len; j++) {\n      k = keys[j];\n      v = descriptor[k];\n      if (v != null) {\n        if (v instanceof Array) {\n          for (c = l = 0, len1 = v.length; l < len1; c = ++l) {\n            i = v[c];\n            if (i != null) {\n              if (typeof i === \"object\") {\n                this.executePlaceholderFormulas(i, id, params);\n              } else if (c !== \"exec\" && typeof i === \"function\") {\n                window.p = params || this.defaultPlaceholderParams;\n                window.d = descriptor;\n                v[c] = i();\n              }\n            }\n          }\n        } else if (typeof v === \"object\") {\n          this.executePlaceholderFormulas(v, id, params);\n        } else if (k !== \"exec_\" && typeof v === \"function\") {\n          window.p = params || this.defaultPlaceholderParams;\n          window.d = descriptor;\n          descriptor[k] = v();\n        }\n      }\n    }\n    return null;\n  };\n\n\n  /**\n  * Creates a calculation for a specified expression.\n  *\n  * @method createCalcFunction\n  * @param {String} expression - The expression to create a calculation function for.\n  * @return {Function} The calculation function.\n  * @protected\n   */\n\n  UIManager.prototype.createCalcFunction = function(expression) {\n    expression = expression.replace(/([0-9]+)%/gm, \"($1 / 100 * v)\");\n    return eval(\"(function(v){ return \" + expression + \"})\");\n  };\n\n\n  /**\n  * Creates an object from the specified object type. The type has the format\n  * <namespace>.<typename> like vn.Component_Hotspot.\n  *\n  * @method createObject\n  * @param {String} type - The type name.\n  * @return {Object} The created object.\n  * @protected\n   */\n\n  UIManager.prototype.createObject = function(type) {\n    var subs;\n    subs = type.split(\".\");\n    return new window[subs[0]][subs[1]]();\n  };\n\n\n  /**\n  * Creates an UI object from a specified UI descriptor.\n  *\n  * @method createFromDescriptor\n  * @param {Object} descriptor - The UI object descriptor.\n  * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n  * @return {gs.Object_UIElement} The created UI object.\n   */\n\n  UIManager.prototype.createFromDescriptor = function(descriptor, parent) {\n    var control, k;\n    control = null;\n    for (k in this.controllers) {\n      if (this.controllers[k].type != null) {\n        this.controllers[k] = this.createObject(this.controllers[k].type);\n      }\n    }\n    return this._createFromDescriptor(descriptor, parent);\n  };\n\n\n  /**\n  * Creates an image button UI object.\n  *\n  * @method createImageButton\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createImageButton = function(descriptor) {\n    var control;\n    control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling);\n    control.behavior.sound = descriptor.sound;\n    control.behavior.sounds = descriptor.sounds;\n    control.image = descriptor.image;\n    control.images = descriptor.images;\n    if (descriptor.imageFolder != null) {\n      control.imageFolder = descriptor.imageFolder;\n    }\n    if (descriptor.looping != null) {\n      control.visual.dispose();\n      control.removeComponent(control.visual);\n      control.visual = new gs.Component_TilingSprite();\n      control.addComponent(control.visual);\n      control.visual.looping.vertical = descriptor.looping.vertical;\n      control.visual.looping.horizontal = descriptor.looping.horizontal;\n    }\n    if (descriptor.color != null) {\n      control.color = Color.fromArray(descriptor.color);\n    }\n    return control;\n  };\n\n\n  /**\n  * Creates an image UI object.\n  *\n  * @method createImage\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createImage = function(descriptor) {\n    var control;\n    control = new ui.Object_Image(descriptor.image, descriptor.imageHandling);\n    if (descriptor.imageFolder != null) {\n      control.imageFolder = descriptor.imageFolder;\n    }\n    if (descriptor.looping != null) {\n      control.visual.dispose();\n      control.removeComponent(control.visual);\n      control.visual = new gs.Component_TilingSprite();\n      control.addComponent(control.visual);\n      control.visual.looping.vertical = descriptor.looping.vertical;\n      control.visual.looping.horizontal = descriptor.looping.horizontal;\n    }\n    if (descriptor.color != null) {\n      control.color = Color.fromArray(descriptor.color);\n    }\n    return control;\n  };\n\n\n  /**\n  * Creates an image map UI object.\n  *\n  * @method createImageMap\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createImageMap = function(descriptor) {\n    var control;\n    control = new ui.Object_ImageMap();\n    control.hotspots = (descriptor.hotspots || []).select(function(h) {\n      return {\n        x: h.rect[0],\n        y: h.rect[1],\n        size: {\n          width: h.rect[2],\n          height: h.rect[3]\n        },\n        data: {\n          action: 3,\n          actions: h.actions\n        }\n      };\n    });\n    control.images = descriptor.images;\n    control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n    control.target = SceneManager.scene.behavior;\n    control.visual.variableContext = new gs.InterpreterContext(SceneManager.scene.layoutName, SceneManager.scene);\n    return control;\n  };\n\n\n  /**\n  * Creates a video UI object.\n  *\n  * @method createVideo\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createVideo = function(descriptor) {\n    var control, ref;\n    control = new ui.Object_Video();\n    control.video = descriptor.video;\n    control.loop = (ref = descriptor.loop) != null ? ref : true;\n    return control;\n  };\n\n\n  /**\n  * Creates a panel UI object.\n  *\n  * @method createPanel\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createPanel = function(descriptor) {\n    var control, ref;\n    control = new ui.Object_Panel();\n    control.modal = (ref = descriptor.modal) != null ? ref : false;\n    if (descriptor.color != null) {\n      control.color = Color.fromArray(descriptor.color);\n    }\n    return control;\n  };\n\n\n  /**\n  * Creates a frame UI object.\n  *\n  * @method createFrame\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createFrame = function(descriptor) {\n    var control;\n    control = new ui.Object_Frame(descriptor.frameSkin);\n    control.frameThickness = descriptor.frameThickness || 16;\n    control.frameCornerSize = descriptor.frameCornerSize || 16;\n    control.image = descriptor.image;\n    control.images = descriptor.images;\n    return control;\n  };\n\n\n  /**\n  * Creates a three-part image UI object.\n  *\n  * @method createThreePartImage\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createThreePartImage = function(descriptor) {\n    var control;\n    control = new ui.Object_ThreePartImage(descriptor.frameSkin);\n    control.firstPartSize = descriptor.firstPartSize || 16;\n    control.middlePartSize = descriptor.middlePartSize || 1;\n    control.lastPartSize = descriptor.lastPartSize || 16;\n    control.image = descriptor.image;\n    control.images = descriptor.images;\n    return control;\n  };\n\n\n  /**\n  * Creates a text UI object.\n  *\n  * @method createText\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createText = function(descriptor) {\n    var control, ref;\n    control = new ui.Object_Text();\n    control.text = lcs(descriptor.text);\n    control.sizeToFit = descriptor.sizeToFit;\n    control.formatting = descriptor.formatting;\n    control.wordWrap = (ref = descriptor.wordWrap) != null ? ref : false;\n    control.behavior.format = descriptor.format;\n    if (descriptor.textPadding) {\n      control.behavior.padding = ui.Space.fromArray(descriptor.textPadding);\n    }\n    if (descriptor.resolvePlaceholders != null) {\n      control.resolvePlaceholders = descriptor.resolvePlaceholders;\n    }\n    if (descriptor.color != null) {\n      control.color = Color.fromArray(descriptor.color);\n    }\n    return control;\n  };\n\n\n  /**\n  * Creates a free-layout UI object.\n  *\n  * @method createFreeLayout\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createFreeLayout = function(descriptor) {\n    var control;\n    if (descriptor.frame != null) {\n      control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1);\n    } else {\n      control = new ui.Object_FreeLayout(0, 0, 1, 1);\n    }\n    control.sizeToFit = descriptor.sizeToFit;\n    return control;\n  };\n\n\n  /**\n  * Creates a stack-layout UI object.\n  *\n  * @method createStackLayout\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createStackLayout = function(descriptor) {\n    var control;\n    if (descriptor.frame != null) {\n      control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n    } else {\n      control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation);\n    }\n    control.sizeToFit = descriptor.sizeToFit;\n    return control;\n  };\n\n\n  /**\n  * Creates a spread-layout UI object.\n  *\n  * @method createSpreadLayout\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createSpreadLayout = function(descriptor) {\n    var control;\n    if (descriptor.frame != null) {\n      control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation);\n    } else {\n      control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation);\n    }\n    return control;\n  };\n\n\n  /**\n  * Creates a grid-layout UI object.\n  *\n  * @method createGridLayout\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createGridLayout = function(descriptor) {\n    var control;\n    if (descriptor.frame != null) {\n      control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template);\n    } else {\n      control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template);\n    }\n    control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0];\n    control.sizeToFit = descriptor.sizeToFit;\n    return control;\n  };\n\n\n  /**\n  * Creates a message UI object.\n  *\n  * @method createMessage\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createMessage = function(descriptor) {\n    var control;\n    control = new ui.Object_Message();\n    return control;\n  };\n\n\n  /**\n  * Creates a data-grid UI object.\n  *\n  * @method createDataGrid\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created image button UI object.\n   */\n\n  UIManager.prototype.createDataGrid = function(descriptor) {\n    var control;\n    control = new ui.Object_DataGrid(descriptor);\n    return control;\n  };\n\n\n  /**\n  * Creates an UI object depending on the object-type of the specified UI descriptor.\n  *\n  * @method createControl\n  * @param {Object} descriptor - The UI object descriptor.\n  * @return {gs.Object_UIElement} The created UI object.\n  * @protected\n   */\n\n  UIManager.prototype.createControl = function(descriptor) {\n    var control;\n    control = null;\n    switch (descriptor.type) {\n      case \"ui.ImageButton\":\n        control = this.createImageButton(descriptor);\n        break;\n      case \"ui.Image\":\n        control = this.createImage(descriptor);\n        break;\n      case \"ui.ImageMap\":\n        control = this.createImageMap(descriptor);\n        break;\n      case \"ui.Video\":\n        control = this.createVideo(descriptor);\n        break;\n      case \"ui.Panel\":\n        control = this.createPanel(descriptor);\n        break;\n      case \"ui.Frame\":\n        control = this.createFrame(descriptor);\n        break;\n      case \"ui.ThreePartImage\":\n        control = this.createThreePartImage(descriptor);\n        break;\n      case \"ui.Text\":\n        control = this.createText(descriptor);\n        break;\n      case \"ui.Message\":\n        control = this.createMessage(descriptor);\n        break;\n      case \"ui.DataGrid\":\n        control = this.createDataGrid(descriptor);\n        break;\n      case \"ui.FreeLayout\":\n        control = this.createFreeLayout(descriptor);\n        break;\n      case \"ui.StackLayout\":\n        control = this.createStackLayout(descriptor);\n        break;\n      case \"ui.SpreadLayout\":\n        control = this.createSpreadLayout(descriptor);\n        break;\n      case \"ui.GridLayout\":\n        control = this.createGridLayout(descriptor);\n    }\n    return control;\n  };\n\n  UIManager.prototype.createLayoutRect = function(frame, control) {\n    var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;\n    if (!control.layoutRect) {\n      control.layoutRect = new ui.LayoutRect();\n    }\n    control.layoutRect.set(0, 0, 0, 0);\n    if (frame != null) {\n      if (((ref = frame[0]) != null ? ref.length : void 0) != null) {\n        control.layoutRect.x = this.createCalcFunction(frame[0]);\n        control.dstRect.x = 0;\n      } else {\n        control.dstRect.x = (ref1 = descriptor.frame[0]) != null ? ref1 : control.dstRect.x;\n      }\n      if (((ref2 = frame[1]) != null ? ref2.length : void 0) != null) {\n        control.layoutRect.y = this.createCalcFunction(frame[1]);\n        control.dstRect.y = 0;\n      } else {\n        control.dstRect.y = (ref3 = frame[1]) != null ? ref3 : control.dstRect.y;\n      }\n      if (((ref4 = frame[2]) != null ? ref4.length : void 0) != null) {\n        control.layoutRect.width = this.createCalcFunction(frame[2]);\n        control.dstRect.width = 1;\n      } else {\n        control.dstRect.width = (ref5 = frame[2]) != null ? ref5 : control.dstRect.width;\n      }\n      if (((ref6 = frame[3]) != null ? ref6.length : void 0) != null) {\n        control.layoutRect.height = this.createCalcFunction(frame[3]);\n        return control.dstRect.height = 1;\n      } else {\n        return control.dstRect.height = (ref7 = frame[3]) != null ? ref7 : control.dstRect.height;\n      }\n    }\n  };\n\n\n  /**\n  * Adds the styles defined in an array of style-names to the specified control.\n  *\n  * @method addControlStyles\n  * @param {Object} control - The control to add the styles to.\n  * @param {string[]} styles - Array of style-names to add.\n   */\n\n  UIManager.prototype.addControlStyles = function(control, styles) {\n    var j, len, results, style, styleName;\n    results = [];\n    for (j = 0, len = styles.length; j < len; j++) {\n      styleName = styles[j];\n      if (this.stylesByName[styleName] != null) {\n        results.push((function() {\n          var l, len1, ref, results1;\n          ref = this.stylesByName[styleName];\n          results1 = [];\n          for (l = 0, len1 = ref.length; l < len1; l++) {\n            style = ref[l];\n            control.styles.push(style);\n            if (style.target === -1 && style.selector === 0) {\n              results1.push(style.apply(control));\n            } else {\n              results1.push(void 0);\n            }\n          }\n          return results1;\n        }).call(this));\n      } else {\n        results.push(void 0);\n      }\n    }\n    return results;\n  };\n\n\n  /**\n  * Creates an UI object from a specified UI descriptor. This method is called\n  * recursively for all child-descriptors.\n  *\n  * @method createControlFromDescriptor\n  * @param {Object} descriptor - The UI object descriptor.\n  * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n  * @param {number} index - The index.\n  * @return {gs.Object_UIElement} The created UI object.\n  * @protected\n   */\n\n  UIManager.prototype.createControlFromDescriptor = function(descriptor, parent, index) {\n    var action, actions, bindings, c, child, childControl, component, control, controls, customFields, data, formulas, i, isNumber, item, j, l, len, len1, len2, len3, m, n, o, p, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, ref19, ref2, ref20, ref21, ref22, ref23, ref24, ref25, ref26, ref27, ref3, ref4, ref5, ref6, ref7, ref8, ref9, style, target, type, typeName, valid;\n    control = null;\n    if (descriptor.style != null) {\n      descriptor.styles = [descriptor.style];\n      delete descriptor.style;\n    }\n    descriptor = Object.deepCopy(descriptor);\n    this.executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params);\n    control = this.createControl(descriptor);\n    if (control == null) {\n      type = Object.deepCopy(this.customTypes[descriptor.type]);\n      this.executePlaceholderFormulas(type, descriptor.id, descriptor.params);\n      typeName = type.type;\n      customFields = type.customFields;\n      bindings = type.bindings;\n      formulas = type.formulas;\n      actions = type.actions;\n      if (type.style != null) {\n        type.styles = [type.style];\n        type.style = null;\n      }\n      Object.mixin(type, descriptor);\n      if (customFields != null) {\n        Object.mixin(type.customFields, customFields);\n      }\n      if ((bindings != null) && bindings !== type.bindings) {\n        type.bindings = type.bindings.concat(bindings);\n      }\n      if ((formulas != null) && formulas !== type.formulas) {\n        type.formulas = type.formulas.concat(formulas);\n      }\n      if ((actions != null) && actions !== type.actions) {\n        type.actions = actions.concat(type.actions);\n      }\n      type.type = typeName;\n      return this.createControlFromDescriptor(type, parent);\n    } else if (parent != null) {\n      parent.addObject(control);\n      control.index = index;\n    } else {\n      gs.ObjectManager.current.addObject(control);\n    }\n    control.ui = new ui.Component_UIBehavior();\n    control.addComponent(control.ui);\n    control.params = descriptor.params;\n    if (descriptor.updateBehavior === \"continuous\") {\n      control.updateBehavior = ui.UpdateBehavior.CONTINUOUS;\n    }\n    if (descriptor.inheritProperties) {\n      control.inheritProperties = true;\n    }\n    if (descriptor.font != null) {\n      control.font = new Font(descriptor.font.name, descriptor.font.size);\n      control.font.bold = (ref = descriptor.font.bold) != null ? ref : control.font.bold;\n      control.font.italic = (ref1 = descriptor.font.italic) != null ? ref1 : control.font.italic;\n      control.font.smallCaps = (ref2 = descriptor.font.smallCaps) != null ? ref2 : control.font.smallCaps;\n      control.font.underline = (ref3 = descriptor.font.underline) != null ? ref3 : control.font.underline;\n      control.font.strikeThrough = (ref4 = descriptor.font.strikeThrough) != null ? ref4 : control.font.strikeThrough;\n      if (descriptor.font.color != null) {\n        control.font.color = Color.fromArray(descriptor.font.color);\n      }\n      if (descriptor.font.border != null) {\n        control.font.border = (ref5 = descriptor.font.border) != null ? ref5 : false;\n        control.font.borderSize = (ref6 = descriptor.font.borderSize) != null ? ref6 : 4;\n        control.font.borderColor = new Color(0, 0, 0);\n      }\n      if (descriptor.font.outline != null) {\n        control.font.border = (ref7 = descriptor.font.outline) != null ? ref7 : false;\n        control.font.borderSize = (ref8 = descriptor.font.outline.size) != null ? ref8 : 4;\n        if (descriptor.font.outline.color != null) {\n          control.font.borderColor = Color.fromArray(descriptor.font.outline.color);\n        } else {\n          control.font.borderColor = new Color(0, 0, 0);\n        }\n      }\n    }\n    if (descriptor.components != null) {\n      ref9 = descriptor.components;\n      for (j = 0, len = ref9.length; j < len; j++) {\n        c = ref9[j];\n        m = c.module || \"gs\";\n        component = new window[m][c.type](c.params);\n        control.addComponent(component, c.id);\n        control[c.id] = component;\n      }\n    }\n    control.focusable = (ref10 = descriptor.focusable) != null ? ref10 : control.focusable;\n    if (descriptor.nextKeyObject) {\n      control.ui.nextKeyObjectId = descriptor.nextKeyObject;\n    }\n    if (descriptor.initialFocus) {\n      control.ui.focus();\n    }\n    actions = Object.deepCopy(descriptor.action != null ? [descriptor.action] : descriptor.actions);\n    if (actions != null) {\n      for (l = 0, len1 = actions.length; l < len1; l++) {\n        action = actions[l];\n        if (action != null) {\n          action.event = (ref11 = action.event) != null ? ref11 : \"onAccept\";\n          if (action.target == null) {\n            target = this.controllers != null ? this.controllers[descriptor.target] : controller;\n            action.target = target || SceneManager.scene.behavior;\n          }\n        }\n      }\n      control.actions = actions;\n      if (!control.findComponentById(\"actionHandler\")) {\n        control.insertComponent(new ui.Component_ActionHandler(), 1, \"actionHandler\");\n      }\n    }\n    if (descriptor.id != null) {\n      control.id = descriptor.id;\n      gs.ObjectManager.current.setObjectById(control, control.id);\n    }\n    control.descriptor = descriptor;\n    control.layoutRect = new Rect();\n    control.layoutRect.set(0, 0, 0, 0);\n    if (descriptor.frame != null) {\n      if (((ref12 = descriptor.frame[0]) != null ? ref12.length : void 0) != null) {\n        control.layoutRect.x = this.createCalcFunction(descriptor.frame[0]);\n        control.dstRect.x = 0;\n      } else {\n        control.dstRect.x = (ref13 = descriptor.frame[0]) != null ? ref13 : control.dstRect.x;\n      }\n      if (((ref14 = descriptor.frame[1]) != null ? ref14.length : void 0) != null) {\n        control.layoutRect.y = this.createCalcFunction(descriptor.frame[1]);\n        control.dstRect.y = 0;\n      } else {\n        control.dstRect.y = (ref15 = descriptor.frame[1]) != null ? ref15 : control.dstRect.y;\n      }\n      if (((ref16 = descriptor.frame[2]) != null ? ref16.length : void 0) != null) {\n        control.layoutRect.width = this.createCalcFunction(descriptor.frame[2]);\n        control.dstRect.width = 1;\n      } else {\n        control.dstRect.width = (ref17 = descriptor.frame[2]) != null ? ref17 : control.dstRect.width;\n      }\n      if (((ref18 = descriptor.frame[3]) != null ? ref18.length : void 0) != null) {\n        control.layoutRect.height = this.createCalcFunction(descriptor.frame[3]);\n        control.dstRect.height = 1;\n      } else {\n        control.dstRect.height = (ref19 = descriptor.frame[3]) != null ? ref19 : control.dstRect.height;\n      }\n    }\n    if (descriptor.sizeToParent != null) {\n      control.sizeToParent = descriptor.sizeToParent;\n    }\n    if (descriptor.blendMode != null) {\n      control.blendMode = this.blendModes[descriptor.blendMode];\n    }\n    if (descriptor.anchor != null) {\n      control.anchor.set(descriptor.anchor[0], descriptor.anchor[1]);\n    }\n    control.opacity = (ref20 = descriptor.opacity) != null ? ref20 : 255;\n    if (descriptor.minimumSize != null) {\n      control.minimumSize = {\n        width: descriptor.minimumSize[0],\n        height: descriptor.minimumSize[1]\n      };\n    }\n    if (descriptor.resizable != null) {\n      control.resizable = descriptor.resizable;\n    }\n    if (descriptor.scrollable != null) {\n      control.scrollable = descriptor.scrollable;\n    }\n    if (descriptor.fixedSize != null) {\n      control.fixedSize = descriptor.fixedSize;\n    }\n    if (descriptor.draggable != null) {\n      control.draggable = descriptor.draggable;\n      control.draggable.step = 0;\n      if (control.draggable.rect != null) {\n        control.draggable.rect = Rect.fromArray(control.draggable.rect);\n      }\n      control.addComponent(new ui.Component_Draggable());\n    }\n    if (descriptor.bindings != null) {\n      control.bindings = descriptor.bindings;\n      control.insertComponent(new ui.Component_BindingHandler(), 0);\n    }\n    if (descriptor.formulas != null) {\n      control.formulas = descriptor.formulas;\n      control.insertComponent(new ui.Component_FormulaHandler(), 0);\n    }\n    control.dataField = descriptor.dataField;\n    control.enabled = (ref21 = descriptor.enabled) != null ? ref21 : true;\n    if (descriptor.selectable != null) {\n      control.selectable = descriptor.selectable;\n    }\n    if (descriptor.group != null) {\n      control.group = descriptor.group;\n      gs.ObjectManager.current.addToGroup(control, control.group);\n    }\n    if (descriptor.customFields != null) {\n      control.customFields = Object.deepCopy(descriptor.customFields);\n    }\n    if (descriptor.margin != null) {\n      control.margin.left = descriptor.margin[0];\n      control.margin.top = descriptor.margin[1];\n      control.margin.right = descriptor.margin[2];\n      control.margin.bottom = descriptor.margin[3];\n    }\n    if (descriptor.padding != null) {\n      control.padding.left = descriptor.padding[0];\n      control.padding.top = descriptor.padding[1];\n      control.padding.right = descriptor.padding[2];\n      control.padding.bottom = descriptor.padding[3];\n    }\n    if (descriptor.alignment != null) {\n      control.alignment = this.alignments[descriptor.alignment];\n    }\n    control.alignmentY = this.alignments[descriptor.alignmentY || 0];\n    control.alignmentX = this.alignments[descriptor.alignmentX || 0];\n    control.zIndex = descriptor.zIndex || 0;\n    control.order = descriptor.order || 0;\n    control.chainOrder = ((ref22 = descriptor.chainOrder) != null ? ref22 : descriptor.zOrder) + ((parent != null ? parent.chainOrder : void 0) || 0);\n    if (descriptor.zoom != null) {\n      control.zoom = {\n        x: descriptor.zoom[0] / 100,\n        y: descriptor.zoom[1] / 100\n      };\n    }\n    if (descriptor.visible != null) {\n      control.visible = descriptor.visible;\n    }\n    if (descriptor.clipRect) {\n      control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height);\n    }\n    if (descriptor.styles != null) {\n      this.addControlStyles(control, descriptor.styles);\n    }\n    if (descriptor.template != null) {\n      control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode);\n      data = ui.Component_FormulaHandler.fieldValue(control, control.dataField);\n      isNumber = typeof data === \"number\";\n      if (data != null) {\n        for (i = n = 0, ref23 = (ref24 = data.length) != null ? ref24 : data; 0 <= ref23 ? n < ref23 : n > ref23; i = 0 <= ref23 ? ++n : --n) {\n          if ((data[i] != null) || isNumber) {\n            valid = true;\n            if ((descriptor.dataFilter != null) && !isNumber) {\n              valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter);\n            }\n            if (valid || isNumber) {\n              child = this.createControlFromDescriptor(descriptor.template, control, i);\n              if ((ref25 = data[i]) != null ? ref25.dstRect : void 0) {\n                child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect);\n              }\n              if ((child.clipRect == null) && (control.clipRect != null)) {\n                child.clipRect = control.clipRect;\n              }\n              control.addObject(child);\n              child.index = i;\n              child.order = ((ref26 = data.length) != null ? ref26 : data) - i;\n              control.controls.push(child);\n            }\n          }\n        }\n      }\n    }\n    if (descriptor.controls && descriptor.controls.exec) {\n      controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls);\n    } else {\n      controls = descriptor.controls;\n    }\n    if (controls != null) {\n      for (i = o = 0, len2 = controls.length; o < len2; i = ++o) {\n        item = controls[i];\n        childControl = this._createFromDescriptor(item, control, i);\n        if ((childControl.clipRect == null) && (control.clipRect != null)) {\n          childControl.clipRect = control.clipRect;\n        }\n        childControl.index = i;\n        childControl.origin.x = control.origin.x + control.dstRect.x;\n        childControl.origin.y = control.origin.y + control.dstRect.y;\n        control.addObject(childControl);\n        control.controls.push(childControl);\n      }\n    }\n    if (control.styles && control.parentsByStyle) {\n      parent = control.parent;\n      while (parent) {\n        if (parent.styles) {\n          ref27 = parent.styles;\n          for (p = 0, len3 = ref27.length; p < len3; p++) {\n            style = ref27[p];\n            if (!control.parentsByStyle[style.id]) {\n              control.parentsByStyle[style.id] = [];\n            }\n            control.parentsByStyle[style.id].push(parent);\n          }\n        }\n        parent = parent.parent;\n      }\n    }\n    if (descriptor.animations != null) {\n      control.animations = Object.deepCopy(descriptor.animations);\n      control.animationExecutor = new ui.Component_AnimationExecutor();\n      control.addComponent(control.animationExecutor);\n      control.addComponent(new ui.Component_AnimationHandler());\n    }\n    control.ui.updateStyle();\n    control.setup();\n    return control;\n  };\n\n\n  /**\n  * Creates an UI object from a specified UI descriptor.\n  *\n  * @method _createFromDescriptor\n  * @param {Object} descriptor - The UI object descriptor.\n  * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).\n  * @return {gs.Object_UIElement} The created UI object.\n  * @protected\n   */\n\n  UIManager.prototype._createFromDescriptor = function(descriptor, parent, index) {\n    var control, controller;\n    control = this.createControlFromDescriptor(descriptor, parent, index);\n    if (descriptor.controller != null) {\n      controller = this.controllers[descriptor.controller];\n      control.controller = controller;\n      control.addComponent(controller);\n    }\n    return control;\n  };\n\n  UIManager.prototype.createLayoutFromDescriptor = function(descriptor, parent, index) {\n    return this._createFromDescriptor(descriptor, parent, index);\n  };\n\n  return UIManager;\n\n})();\n\nGraphics.width = $PARAMS.resolution.width;\n\nGraphics.height = $PARAMS.resolution.height;\n\nui.UiFactory = new UIManager();\n\nui.UIManager = ui.UiFactory;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7Ozs7OztFQVlhLGlCQUFDLENBQUQsRUFBSSxJQUFKLEVBQVUsS0FBVjs7QUFDVDs7Ozs7QUFBQSxRQUFBO0lBS0EsSUFBQyxDQUFBLFlBQUQsR0FBZ0I7O0FBRWhCOzs7OztJQUtBLElBQUMsQ0FBQSxLQUFELEdBQVM7O0FBRVQ7Ozs7O0lBS0EsSUFBQyxDQUFBLElBQUQsR0FBUTs7QUFFUjs7Ozs7SUFLQSxJQUFDLENBQUEsS0FBRCxHQUFTOztBQUVUOzs7Ozs7SUFNQSxJQUFDLENBQUEsT0FBRCxHQUFlLElBQUEsS0FBQSxDQUFNLEVBQU47QUFDZixTQUF5Qiw4RkFBekI7TUFBQSxJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBQWQ7O0FBRUE7Ozs7OztJQU1BLElBQUMsQ0FBQSxPQUFELEdBQWUsSUFBQSxLQUFBLENBQU0sRUFBTjtBQUNmLFNBQTBCLG1HQUExQjtNQUFBLElBQUMsQ0FBQSxPQUFRLENBQUEsQ0FBQSxDQUFULEdBQWM7QUFBZDtFQTdDUzs7O0FBZ0RiOzs7OztvQkFJQSxJQUFBLEdBQU0sU0FBQTtBQUNILFFBQUE7SUFBQSxJQUFDLENBQUEsSUFBRCxHQUFRLElBQUMsQ0FBQTtJQUNULENBQUEsR0FBSSxJQUFDLENBQUEsS0FBSyxDQUFDLEtBQVAsQ0FBYSxJQUFiLEVBQW1CLFNBQW5CO0lBQ0osSUFBQyxDQUFBLFlBQUQsR0FBZ0I7QUFFaEIsV0FBTztFQUxKOzs7QUFPTjs7Ozs7Ozs7b0JBT0EsUUFBQSxHQUFVLFNBQUMsV0FBRDtBQUNOLFFBQUE7SUFBQSxNQUFBLEdBQVMsSUFBQyxDQUFBLE9BQVEsQ0FBQSxDQUFBLENBQVQsS0FBZTtJQUN4QixJQUFDLENBQUEsT0FBUSxDQUFBLENBQUEsQ0FBVCxHQUFjO0FBRWQsV0FBTztFQUpEOzs7QUFNVjs7Ozs7Ozs7b0JBT0Es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QUMsVUFBWDtNQUMxQixPQUFPLENBQUMsVUFBUixHQUFxQjtNQUNyQixPQUFPLENBQUMsWUFBUixDQUFxQixVQUFyQixFQUhKOztBQUtBLFdBQU87RUFSWTs7c0JBVXZCLDBCQUFBLEdBQTRCLFNBQUMsVUFBRCxFQUFhLE1BQWIsRUFBcUIsS0FBckI7V0FDeEIsSUFBQyxDQUFBLHFCQUFELENBQXVCLFVBQXZCLEVBQW1DLE1BQW5DLEVBQTJDLEtBQTNDO0VBRHdCOzs7Ozs7QUFLaEMsUUFBUSxDQUFDLEtBQVQsR0FBaUIsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7QUFDcEMsUUFBUSxDQUFDLE1BQVQsR0FBa0IsT0FBTyxDQUFDLFVBQVUsQ0FBQzs7QUFDckMsRUFBRSxDQUFDLFNBQUgsR0FBbUIsSUFBQSxTQUFBLENBQUE7O0FBQ25CLEVBQUUsQ0FBQyxTQUFILEdBQWUsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4jXG4jICAgU2NyaXB0OiBVSU1hbmFnZXJcbiNcbiMgICAkJENPUFlSSUdIVCQkXG4jXG4jID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuY2xhc3MgRm9ybXVsYVxuICAgICMjIypcbiAgICAqIEVuY2Fwc3VsYXRlcyBhIFVJIGZvcm11bGEuIEEgZm9ybXVsYSBjYW4gYmUgdXNlZCBpbiBVSSBsYXlvdXRzIHRvIGRlZmluZVxuICAgICogcHJvcGVydHktYmluZGluZ3Mgb3IgdG8gaW1wbGVtZW50IGEgc3BlY2lmaWMgYmVoYXZpb3IuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIEZvcm11bGFcbiAgICAqIEBtZW1iZXJvZiB1aVxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmIC0gVGhlIGZvcm11bGEtZnVuY3Rpb24uIERlZmluZXMgdGhlIGxvZ2ljIG9mIHRoZSBmb3JtdWxhLlxuICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgLSBBbiBvcHRpb25hbCBkYXRhLW9iamVjdCB3aGljaCBjYW4gYmUgYWNjZXNzZWQgaW5zaWRlIHRoZSBmb3JtdWxhLWZ1bmN0aW9uLlxuICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gQW4gb3B0aW9uYWwgZXZlbnQtbmFtZSB0byBkZWZpbmUgd2hlbiB0aGUgZm9ybXVsYSBzaG91bGQgYmUgZXhlY3V0ZWQuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChmLCBkYXRhLCBldmVudCkgLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIEluZGljYXRlcyBpZiBpdHMgdGhlIGZpcnN0IHRpbWUgdGhlIGZvcm11bGEgaXMgY2FsbGVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBvbkluaXRpYWxpemVcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICMjI1xuICAgICAgICBAb25Jbml0aWFsaXplID0geWVzXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGZvcm11bGEtZnVuY3Rpb24uXG4gICAgICAgICogQHByb3BlcnR5IGV4ZWNfXG4gICAgICAgICogQHR5cGUgRnVuY3Rpb25cbiAgICAgICAgIyMjXG4gICAgICAgIEBleGVjXyA9IGZcbiAgICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQW4gb3B0aW9uYWwgZGF0YS1vYmplY3Qgd2hpY2ggY2FuIGJlcyBhY2Nlc3NlZCBpbnNpZGUgdGhlIGZvcm11bGEtZnVuY3Rpb24uXG4gICAgICAgICogQHByb3BlcnR5IGRhdGFcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjICAgXG4gICAgICAgIEBkYXRhID0gZGF0YVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIG9wdGlvbmFsIGV2ZW50LW5hbWUgdG8gZGVmaW5lIHdoZW4gdGhlIGZvcm11bGEgc2hvdWxkIGJlIGV4ZWN1dGVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBldmVudFxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAjIyMgXG4gICAgICAgIEBldmVudCA9IGV2ZW50XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQW4gYXJyYXkgb2YgY3VzdG9tIG51bWJlci1kYXRhIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBkaWZmZXJlbnQgcHVycG9zZXMuIFRoZSBmaXJzdCBlbGVtZW50XG4gICAgICAgICogaXMgYWxzbyB1c2VkIGluIG9uQ2hhbmdlIG1ldGhvZCB0byBzdG9yZSB0aGUgb2xkIHZhbHVlIGFuZCBjaGVjayBhZ2FpbnN0IHRoZSBuZXcgb25lIHRvIGRldGVjdCBhIGNoYW5nZS5cbiAgICAgICAgKiBAcHJvcGVydHkgbnVtYmVyc1xuICAgICAgICAqIEB0eXBlIG51bWJlcltdXG4gICAgICAgICMjIyBcbiAgICAgICAgQG51bWJlcnMgPSBuZXcgQXJyYXkoMTApXG4gICAgICAgIEBudW1iZXJzW2ldID0gMCBmb3IgaSBpbiBbMC4uQG51bWJlcnMubGVuZ3RoXVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFuIGFycmF5IG9mIGN1c3RvbSBzdHJpbmctZGF0YSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgZGlmZmVyZW50IHB1cnBvc2VzLiBUaGUgZmlyc3QgZWxlbWVudFxuICAgICAgICAqIGlzIGFsc28gdXNlZCBpbiBvblRleHRDaGFuZ2UgbWV0aG9kIHRvIHN0b3JlIHRoZSBvbGQgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUgdG8gZGV0ZWN0IGEgY2hhbmdlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHJpbmdzXG4gICAgICAgICogQHR5cGUgc3RyaW5nW11cbiAgICAgICAgIyMjXG4gICAgICAgIEBzdHJpbmdzID0gbmV3IEFycmF5KDEwKVxuICAgICAgICBAc3RyaW5nc1tpXSA9IFwiXCIgZm9yIGkgaW4gWzAuLkBzdHJpbmdzLmxlbmd0aF1cbiAgICAgICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogVGhlIGZvcm11bGEtZnVuY3Rpb24uIEl0cyBhIHdyYXBwZXItZnVuY3Rpb24gYmVmb3JlIHRoZSBmaXJzdC10aW1lIGNhbGwgd2FzIG1hZGUuXG4gICAgKiBAbWV0aG9kIGV4ZWNcbiAgICAjIyNcbiAgICBleGVjOiAtPlxuICAgICAgIEBleGVjID0gQGV4ZWNfXG4gICAgICAgciA9IEBleGVjXy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgQG9uSW5pdGlhbGl6ZSA9IG5vXG4gICAgICAgXG4gICAgICAgcmV0dXJuIHJcbiAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBudW1iZXItdmFsdWUgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgY2hlY2suIEl0IHVzZXNcbiAgICAqIHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgbnVtYmVycy1hcnJheSB0byBzdG9yZSB0aGUgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUuXG4gICAgKlxuICAgICogQG1ldGhvZCBvbkNoYW5nZVxuICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlclZhbHVlIC0gTnVtYmVyIHZhbHVlIHRvIGNoZWNrLlxuICAgICMjIyAgICBcbiAgICBvbkNoYW5nZTogKG51bWJlclZhbHVlKSAtPlxuICAgICAgICByZXN1bHQgPSBAbnVtYmVyc1swXSAhPSBudW1iZXJWYWx1ZVxuICAgICAgICBAbnVtYmVyc1swXSA9IG51bWJlclZhbHVlXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgIFxuICAgICMjIypcbiAgICAqIENoZWNrcyBpZiB0aGUgc3BlY2lmaWVkIHRleHQtdmFsdWUgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgY2hlY2suIEl0IHVzZXNcbiAgICAqIHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgc3RyaW5ncy1hcnJheSB0byBzdG9yZSB0aGUgdmFsdWUgYW5kIGNoZWNrIGFnYWluc3QgdGhlIG5ldyBvbmUuXG4gICAgKlxuICAgICogQG1ldGhvZCBvblRleHRDaGFuZ2VcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0VmFsdWUgLSBUZXh0IHZhbHVlIHRvIGNoZWNrLlxuICAgICMjIyAgICAgXG4gICAgb25UZXh0Q2hhbmdlOiAodGV4dFZhbHVlKSAtPlxuICAgICAgICByZXN1bHQgPSBAc3RyaW5nc1swXSAhPSB0ZXh0VmFsdWVcbiAgICAgICAgQHN0cmluZ3NbMF0gPSB0ZXh0VmFsdWVcbiAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgXG51aS5Gb3JtdWxhID0gRm9ybXVsYVxuXG5jbGFzcyBTcGFjZVxuICAgICMjIypcbiAgICAqIERlc2NyaWJlcyBhIHNwYWNlIGluc2lkZSBvciBhcm91bmQgc29tZXRoaW5nIGxpa2UgYSBtYXJnaW4gb3IgcGFkZGluZy5cbiAgICAqXG4gICAgKiBAbW9kdWxlIHVpXG4gICAgKiBAY2xhc3MgU3BhY2VcbiAgICAqIEBtZW1iZXJvZiB1aVxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGVmdCAtIFNwYWNlIGF0IHRoZSBsZWZ0IGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgLSBTcGFjZSBhdCB0aGUgdG9wIGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSByaWdodCAtIFNwYWNlIGF0IHRoZSByaWdodCBpbiBwaXhlbHMuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gYm90dG9tIC0gU3BhY2UgYXQgdGhlIGJvdHRvbSBpbiBwaXhlbHMuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20pIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgbGVmdCBpbiBwaXhlbHMuXG4gICAgICAgICogQHByb3BlcnR5IGxlZnRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBsZWZ0ID0gbGVmdFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFNwYWNlIGF0IHRoZSB0b3AgaW4gcGl4ZWxzLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0b3BcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB0b3AgPSB0b3BcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgcmlnaHQgaW4gcGl4ZWxzLlxuICAgICAgICAqIEBwcm9wZXJ0eSByaWdodFxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQHJpZ2h0ID0gcmlnaHRcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTcGFjZSBhdCB0aGUgYm90dG9tIGluIHBpeGVscy5cbiAgICAgICAgKiBAcHJvcGVydHkgYm90dG9tXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAYm90dG9tID0gYm90dG9tXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgc3BhY2UgYnkgY29weWluZyB0aGVtIGZyb20gYSBzcGVjaWZpZWQgc3BhY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXRGcm9tT2JqZWN0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gc3BhY2UgLSBBIHNwYWNlIHRvIGNvcHkuXG4gICAgIyMjICAgXG4gICAgc2V0RnJvbU9iamVjdDogKHNwYWNlKSAtPlxuICAgICAgICBAbGVmdCA9IHNwYWNlLmxlZnRcbiAgICAgICAgQHRvcCA9IHNwYWNlLnRvcFxuICAgICAgICBAcmlnaHQgPSBzcGFjZS5yaWdodFxuICAgICAgICBAYm90dG9tID0gc3BhY2UuYm90dG9tXG4gICAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgc3BhY2UuXG4gICAgKlxuICAgICogQG1ldGhvZCBzZXRcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0IC0gU3BhY2UgYXQgdGhlIGxlZnQgaW4gcGl4ZWxzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHRvcCAtIFNwYWNlIGF0IHRoZSB0b3AgaW4gcGl4ZWxzLlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IC0gU3BhY2UgYXQgdGhlIHJpZ2h0IGluIHBpeGVscy5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBib3R0b20gLSBTcGFjZSBhdCB0aGUgYm90dG9tIGluIHBpeGVscy5cbiAgICAjIyMgICAgXG4gICAgc2V0OiAobGVmdCwgdG9wLCByaWdodCwgYm90dG9tKSAtPlxuICAgICAgICBAbGVmdCA9IGxlZnRcbiAgICAgICAgQHRvcCA9IHRvcFxuICAgICAgICBAcmlnaHQgPSByaWdodFxuICAgICAgICBAYm90dG9tID0gYm90dG9tXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIG5ldyBzcGFjZSBvYmplY3QgZnJvbSBhbiBhcnJheSBvZiBjb29yZGluYXRlcy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGZyb21BcnJheVxuICAgICogQHN0YXRpY1xuICAgICogQHBhcmFtIHtudW1iZXJbXX0gYXJyYXkgLSBBbiBhcnJheSBvZiBjb29yZGluYXRlcyAobGVmdCwgdG9wIHJpZ2h0LCBib3R0b20pLlxuICAgICMjIyAgICBcbiAgICBAZnJvbUFycmF5OiAoYXJyYXkpIC0+IG5ldyB1aS5TcGFjZShhcnJheVswXSwgYXJyYXlbMV0sIGFycmF5WzJdLCBhcnJheVszXSlcbiAgICAgICAgXG51aS5TcGFjZSA9IFNwYWNlXG5cbmNsYXNzIFN0eWxlXG4gICAgIyMjKlxuICAgICogQSBVSSBzdHlsZSBjYW4gYXBwbGllZCB0byBhIFVJIG9iamVjdCB0byBtb2RpZnkgaXQgcHJvcGVydGllcyBsaWtlIGNvbG9yLCBpbWFnZSwgZXRjLiB0byBnaXZlIGEgY2VydGFpbiBcInN0eWxlXCIgdG8gaXQuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIFN0eWxlXG4gICAgKiBAbWVtYmVyb2YgdWlcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBBIHN0eWxlLWRlc2NyaXB0b3IgdG8gaW5pdGlhbGl6ZSB0aGUgc3R5bGUgZnJvbS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBpZCAtIEEgdW5pcXVlIG51bWVyaWMgSUQgdG8gYWNjZXNzIHRoZSBzdHlsZSB0aHJvdWdoIFVJTWFuYWdlci5zdHlsZXNCeUlkIGNvbGxlY3Rpb24uXG4gICAgKiBAcGFyYW0ge251bWJlcn0gc2VsZWN0b3IgLSBBIHNlbGVjdG9yIElEIHdoaWNoIGNvbnRyb2xzIHVuZGVyIHdoaWNoIGNvbmRpdGlvbnMgdGhlIHN0eWxlcyB3aWxsIGJlIGFwcGxpZWQuXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IChkZXNjcmlwdG9yLCBpZCwgc2VsZWN0b3IpIC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBJRCBudW1iZXIgdG8gcXVpY2tseSBhY2Nlc3MgdGhpcyBzdHlsZSBhbmQgbGluayB0byB0aGlzIHN0eWxlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBpZFxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQGlkID0gaWRcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdHlsZS1JRCBvZiB0YXJnZXQgb2JqZWN0LiBUaGlzIHN0eWxlIHdpbGwgb25seSBiZSBhcHBsaWVkIG9uIFVJIG9iamVjdHMgd2l0aCB0aGF0IHN0eWxlIElEIHdoaWNoIGFyZVxuICAgICAgICAqIGNoaWxkcmVuIG9mIFVJIG9iamVjdHMgd2hlcmUgdGhpcyBzdHlsZSBpcyBhcHBsaWVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0YXJnZXRcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB0YXJnZXQgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFNlbGVjdG9yLUlEIHdoaWNoIGNvbnRyb2xzIHVuZGVyIHdoaWNoIGNvbmRpdGlvbnMgdGhlIHN0eWxlIGJlY29tZXMgYWN0aXZlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzZWxlY3RvclxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQHNlbGVjdG9yID0gc2VsZWN0b3JcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgZm9udCB1c2VkIGZvciB0aGUgdGV4dC1kaXNwbGF5LlxuICAgICAgICAqIEBkZWZhdWx0IG51bGxcbiAgICAgICAgKiBAcHJvcGVydHkgZm9udFxuICAgICAgICAqIEB0eXBlIGdzLkZvbnRcbiAgICAgICAgIyMjXG4gICAgICAgIEBmb250ID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBpbWFnZSB1c2VkIGZvciB2aXN1YWwgcHJlc2VudGF0aW9uLlxuICAgICAgICAqIEBwcm9wZXJ0eSBpbWFnZVxuICAgICAgICAqIEB0eXBlIHN0cmluZ1xuICAgICAgICAjIyNcbiAgICAgICAgQGltYWdlID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBhbmltYXRpb25zIHVzZWQgZm9yIHZpc3VhbCBwcmVzZW50YXRpb24uXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIEBwcm9wZXJ0eSBhbmltYXRpb25zXG4gICAgICAgICogQHR5cGUgT2JqZWN0W11cbiAgICAgICAgIyMjXG4gICAgICAgIEBhbmltYXRpb25zID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBjb2xvci5cbiAgICAgICAgKiBAcHJvcGVydHkgY29sb3JcbiAgICAgICAgKiBAdHlwZSBncy5Db2xvclxuICAgICAgICAjIyNcbiAgICAgICAgQGNvbG9yID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyB0b25lLlxuICAgICAgICAqIEBwcm9wZXJ0eSB0b25lXG4gICAgICAgICogQHR5cGUgZ3MuVG9uZVxuICAgICAgICAjIyNcbiAgICAgICAgQHRvbmUgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIGFuY2hvci1wb2ludC4gRm9yIGV4YW1wbGU6IEFuIGFuY2hvci1wb2ludCB3aXRoIDAsMCBwbGFjZXMgdGhlIG9iamVjdCB3aXRoIGl0cyB0b3AtbGVmdCBjb3JuZXJcbiAgICAgICAgKiBhdCBpdHMgcG9zaXRpb24gYnV0IHdpdGggYW4gMC41LCAwLjUgYW5jaG9yLXBvaW50IHRoZSBvYmplY3QgaXMgcGxhY2VkIHdpdGggaXRzIGNlbnRlci4gQW4gYW5jaG9yLXBvaW50IG9mIDEsMVxuICAgICAgICAqIHBsYWNlcyB0aGUgb2JqZWN0IHdpdGggaXRzIGxvd2VyLXJpZ2h0IGNvcm5lci5cbiAgICAgICAgKiBAcHJvcGVydHkgYW5jaG9yXG4gICAgICAgICogQHR5cGUgZ3MuUG9pbnRcbiAgICAgICAgIyMjXG4gICAgICAgIEBhbmNob3IgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIHpvb20tc2V0dGluZyBmb3IgeCBhbmQgeSBheGlzLlxuICAgICAgICAqIEBkZWZhdWx0IG5ldyBncy5Qb2ludCgxLjAsIDEuMClcbiAgICAgICAgKiBAcHJvcGVydHkgem9vbVxuICAgICAgICAqIEB0eXBlIGdzLlBvaW50XG4gICAgICAgICMjI1xuICAgICAgICBAem9vbSA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgbWFyZ2luLiBUaGUgbWFyZ2luIGRlZmluZXMgYW4gZXh0cmEgc3BhY2UgYXJvdW5kIHRoZSBVSSBvYmplY3QuIFxuICAgICAgICAqIFRoZSBkZWZhdWx0IGlzIHsgbGVmdDogMCwgdG9wOiAwLCByaWdodDogMCwgYm90dG9tOiAwIH0uXG4gICAgICAgICogQHByb3BlcnR5IG1hcmdpblxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQG1hcmdpbiA9IG51bGxcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgVUkgb2JqZWN0J3MgcGFkZGluZy4gVGhlIGRlZmF1bHQgaXMgeyBsZWZ0OiAwLCB0b3A6IDAsIHJpZ2h0OiAwLCBib3R0b206IDAgfS5cbiAgICAgICAgKiBAcHJvcGVydHkgcGFkZGluZ1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHBhZGRpbmcgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIG1hc2sgZm9yIG1hc2tpbmctZWZmZWN0cy5cbiAgICAgICAgKiBAcHJvcGVydHkgbWFza1xuICAgICAgICAqIEB0eXBlIGdzLk1hc2tcbiAgICAgICAgIyMjXG4gICAgICAgIEBtYXNrID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBVSSBvYmplY3QncyBhbGlnbm1lbnQuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudFxuICAgICAgICAqIEB0eXBlIHVpLkFsaWdubWVudFxuICAgICAgICAjIyNcbiAgICAgICAgQGFsaWdubWVudCA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIFVJIG9iamVjdCdzIG9wYWNpdHkgdG8gY29udHJvbCB0cmFuc3BhcmVuY3kuIEZvciBleGFtcGxlOiAwID0gVHJhbnNwYXJlbnQsIDI1NSA9IE9wYXF1ZSwgMTI4ID0gU2VtaS1UcmFuc3BhcmVudC5cbiAgICAgICAgKiBAcHJvcGVydHkgb3BhY2l0eVxuICAgICAgICAqIEB0eXBlIG51bWJlclxuICAgICAgICAjIyNcbiAgICAgICAgQG9wYWNpdHkgPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyBjbGlwLXJlY3QgZm9yIHZpc3VhbCBwcmVzZW50YXRpb24uXG4gICAgICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAgICAqIEBwcm9wZXJ0eSBjbGlwUmVjdFxuICAgICAgICAqIEB0eXBlIGdzLlJlY3RcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjI1xuICAgICAgICBAY2xpcFJlY3QgPSBudWxsXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGNvcm5lci1zaXplIG9mIHRoZSBmcmFtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgZnJhbWVDb3JuZXJTaXplXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAZnJhbWVDb3JuZXJTaXplID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgdGhpY2tuZXNzIG9mIHRoZSBmcmFtZS5cbiAgICAgICAgKiBAcHJvcGVydHkgZnJhbWVUaGlja25lc3NcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBmcmFtZVRoaWNrbmVzcyA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIGxvb3Bpbmcgb2YgdGhlIGltYWdlLlxuICAgICAgICAqIEBwcm9wZXJ0eSBsb29waW5nXG4gICAgICAgICogQHR5cGUgdWkuT3JpZW50YXRpb25cbiAgICAgICAgIyMjXG4gICAgICAgIEBsb29waW5nID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyB6LWluZGV4IGNvbnRyb2xzIHJlbmRlcmluZy1vcmRlci9pbWFnZS1vdmVybGFwcGluZy4gQW4gb2JqZWN0IHdpdGggYSBzbWFsbGVyIHotaW5kZXggaXMgcmVuZGVyZWRcbiAgICAgICAgKiBiZWZvcmUgYW4gb2JqZWN0IHdpdGggYSBsYXJnZXIgaW5kZXguIEZvciBleGFtcGxlOiBUbyBtYWtlIHN1cmUgYSBnYW1lIG9iamVjdCBpcyBhbHdheXMgb24gdG9wIG9mIHRoZSBzY3JlZW4sIGl0XG4gICAgICAgICogc2hvdWxkIGhhdmUgdGhlIGxhcmdlc3Qgei1pbmRleCBvZiBhbGwgZ2FtZSBvYmplY3RzLlxuICAgICAgICAqIEBwcm9wZXJ0eSB6SW5kZXhcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEB6SW5kZXggPSAtMVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvYmplY3QncyBhbGlnbm1lbnQgb24geC1heGlzLiBOZWVkcyB0byBiZSBzdXBwb3J0ZWQgYnkgbGF5b3V0LlxuICAgICAgICAqIEBwcm9wZXJ0eSBhbGlnbm1lbnRYXG4gICAgICAgICogQHR5cGUgbnVtYmVyXG4gICAgICAgICMjI1xuICAgICAgICBAYWxpZ25tZW50WCA9IC0xXG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogVGhlIG9iamVjdCdzIGFsaWdubWVudCBvbiB5LWF4aXMuIE5lZWRzIHRvIGJlIHN1cHBvcnRlZCBieSBsYXlvdXQuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudFlcbiAgICAgICAgKiBAdHlwZSBudW1iZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBhbGlnbm1lbnRZID0gLTFcbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBUaGUgb2JqZWN0J3MgcmVzaXplIGJlaGF2aW9yLlxuICAgICAgICAqIEBwcm9wZXJ0eSByZXNpemFibGVcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICMjI1xuICAgICAgICBAcmVzaXphYmxlID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFRoZSBvcmlnaW5hbCBzdHlsZSBkZXNjcmlwdG9yLlxuICAgICAgICAqIEBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3JcbiAgICAgICAgICAgIEBzZXRGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yKVxuXG4gICAgIyMjKlxuICAgICogSW5pdGlhbGl6ZXMgdGhlIHN0eWxlIGZyb20gYSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0RnJvbURlc2NyaXB0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIHN0eWxlLWRlc2NyaXB0b3IuXG4gICAgIyMjIFxuICAgIHNldEZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgQGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yXG4gICAgICAgIEBpbWFnZSA9IGRlc2NyaXB0b3IuaW1hZ2VcbiAgICAgICAgQGNvbG9yID0gZ3MuQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuY29sb3IpIGlmIGRlc2NyaXB0b3IuY29sb3JcbiAgICAgICAgQHRvbmUgPSBncy5Ub25lLmZyb21BcnJheShkZXNjcmlwdG9yLnRvbmUpIGlmIGRlc2NyaXB0b3IudG9uZVxuICAgICAgICBAYW5jaG9yID0gbmV3IGdzLlBvaW50KGRlc2NyaXB0b3IuYW5jaG9yWzBdLCBkZXNjcmlwdG9yLmFuY2hvclsxXSkgaWYgZGVzY3JpcHRvci5hbmNob3JcbiAgICAgICAgQHpvb20gPSBuZXcgZ3MuUG9pbnQoZGVzY3JpcHRvci56b29tWzBdLCBkZXNjcmlwdG9yLnpvb21bMV0pIGlmIGRlc2NyaXB0b3Iuem9vbVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250XG4gICAgICAgICAgICBAc2V0dXBGb250KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jbGlwUmVjdFxuICAgICAgICAgICAgQGNsaXBSZWN0ID0gZ3MuUmVjdC5mcm9tQXJyYXkoZGVzY3JpcHRvci5jbGlwUmVjdClcbiAgICAgICAgICAgIFxuICAgICAgICBAb3BhY2l0eSA9IGRlc2NyaXB0b3Iub3BhY2l0eSBpZiBkZXNjcmlwdG9yLm9wYWNpdHkgPj0gMFxuICAgICAgICBAYWxpZ25tZW50ID0gZGVzY3JpcHRvci5hbGlnbm1lbnQgaWYgZGVzY3JpcHRvci5hbGlnbm1lbnQgPj0gMFxuICAgICAgICBAbWFyZ2luID0gdWkuU3BhY2UuZnJvbUFycmF5KGRlc2NyaXB0b3IubWFyZ2luKSBpZiBkZXNjcmlwdG9yLm1hcmdpblxuICAgICAgICBAcGFkZGluZyA9IHVpLlNwYWNlLmZyb21BcnJheShkZXNjcmlwdG9yLnBhZGRpbmcpIGlmIGRlc2NyaXB0b3IucGFkZGluZ1xuICAgICAgICBAYW5pbWF0aW9ucyA9IGRlc2NyaXB0b3IuYW5pbWF0aW9uc1xuICAgICAgICBAZnJhbWVDb3JuZXJTaXplID0gZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemUgaWYgZGVzY3JpcHRvci5mcmFtZUNvcm5lclNpemVcbiAgICAgICAgQGZyYW1lVGhpY2tuZXNzID0gZGVzY3JpcHRvci5mcmFtZVRoaWNrbmVzcyBpZiBkZXNjcmlwdG9yLmZyYW1lVGhpY2tuZXNzXG4gICAgICAgIEBmcmFtZSA9IGRlc2NyaXB0b3IuZnJhbWUgaWYgZGVzY3JpcHRvci5mcmFtZVxuICAgICAgICBAbG9vcGluZyA9IGRlc2NyaXB0b3IubG9vcGluZyBpZiBkZXNjcmlwdG9yLmxvb3BpbmdcbiAgICAgICAgQHJlc2l6YWJsZSA9IGRlc2NyaXB0b3IucmVzaXphYmxlIGlmIGRlc2NyaXB0b3IucmVzaXphYmxlP1xuICAgICAgICBAekluZGV4ID0gZGVzY3JpcHRvci56SW5kZXggaWYgZGVzY3JpcHRvci56SW5kZXhcbiAgICAgICAgQGFsaWdubWVudFggPSB1aS5VSU1hbmFnZXIuYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFhdIGlmIGRlc2NyaXB0b3IuYWxpZ25tZW50WFxuICAgICAgICBAYWxpZ25tZW50WSA9IHVpLlVJTWFuYWdlci5hbGlnbm1lbnRzW2Rlc2NyaXB0b3IuYWxpZ25tZW50WV0gaWYgZGVzY3JpcHRvci5hbGlnbm1lbnRZXG4gICAgICAgIFxuICAgIHNldDogKHN0eWxlKSAtPlxuICAgICAgICBAaW1hZ2UgPSBzdHlsZS5pbWFnZVxuICAgICAgICBAY29sb3Iuc2V0RnJvbU9iamVjdChzdHlsZS5jb2xvcilcbiAgICAgICAgQHRvbmUuc2V0RnJvbU9iamVjdChzdHlsZS50b25lKVxuICAgICAgICBAYW5jaG9yLnNldChzdHlsZS5hbmNob3IueCwgc3R5bGUuYW5jaG9yLnkpXG4gICAgICAgIEB6b29tLnNldChzdHlsZS56b29tLngsIHN0eWxlLnpvb20ueSlcbiAgICAgICAgXG4gICAgICAgIGlmIHN0eWxlLmZvbnRcbiAgICAgICAgICAgIGlmICFAZm9udCB0aGVuIEBmb250ID0gbmV3IGdzLkZvbnQoc3R5bGUuZm9udC5uYW1lLCBzdHlsZS5mb250LnNpemUpXG4gICAgICAgICAgICBAZm9udC5zZXQoc3R5bGUuZm9udClcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBzdHlsZS5jbGlwUmVjdFxuICAgICAgICAgICAgaWYgIUBjbGlwUmVjdCB0aGVuIEBjbGlwUmVjdCA9IG5ldyBncy5SZWN0KClcbiAgICAgICAgICAgIEBjbGlwUmVjdC5zZXRGcm9tT2JqZWN0KHN0eWxlLmNsaXBSZWN0KVxuICAgICAgICAgICAgXG4gICAgICAgIEBvcGFjaXR5ID0gc3R5bGUub3BhY2l0elxuICAgICAgICBAYWxpZ25tZW50ID0gc3R5bGUuYWxpZ25tZW50XG4gICAgICAgIEBtYXJnaW4uc2V0RnJvbU9iamVjdChzdHlsZS5tYXJnaW4pXG4gICAgICAgIEBwYWRkaW5nLnNldEZyb21PYmplY3Qoc3R5bGUucGFkZGluZylcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogSW5pdGlhbGl6ZXMgZm9udC1kYXRhIGZyb20gYSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0dXBGb250XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBzdHlsZS1kZXNjcmlwdG9yLlxuICAgICogQHByb3RlY3RlZFxuICAgICMjIyBcbiAgICBzZXR1cEZvbnQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnRcbiAgICAgICAgICAgIGlmICFAZm9udFxuICAgICAgICAgICAgICAgIEBmb250ID0gbmV3IEZvbnQoZGVzY3JpcHRvci5mb250Lm5hbWUsIGRlc2NyaXB0b3IuZm9udC5zaXplID8gMClcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBAZm9udC5uYW1lID0gZGVzY3JpcHRvci5mb250Lm5hbWVcbiAgICAgICAgICAgICAgICBAZm9udC5zaXplID0gZGVzY3JpcHRvci5mb250LnNpemUgPyAwXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAZm9udC5ib2xkID0gZGVzY3JpcHRvci5mb250LmJvbGQgPyBAZm9udC5ib2xkXG4gICAgICAgICAgICBAZm9udC5pdGFsaWMgPSBkZXNjcmlwdG9yLmZvbnQuaXRhbGljID8gQGZvbnQuaXRhbGljXG4gICAgICAgICAgICBAZm9udC5zbWFsbENhcHMgPSBkZXNjcmlwdG9yLmZvbnQuc21hbGxDYXBzID8gQGZvbnQuc21hbGxDYXBzXG4gICAgICAgICAgICBAZm9udC51bmRlcmxpbmUgPSBkZXNjcmlwdG9yLmZvbnQudW5kZXJsaW5lID8gQGZvbnQudW5kZXJsaW5lXG4gICAgICAgICAgICBAZm9udC5zdHJpa2VUaHJvdWdoID0gZGVzY3JpcHRvci5mb250LnN0cmlrZVRocm91Z2ggPyBAZm9udC5zdHJpa2VUaHJvdWdoXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5jb2xvcj9cbiAgICAgICAgICAgICAgICBAZm9udC5jb2xvci5zZXRGcm9tQXJyYXkoZGVzY3JpcHRvci5mb250LmNvbG9yKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyP1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlciA9IGRlc2NyaXB0b3IuZm9udC5ib3JkZXIgPyBub1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlclNpemUgPSBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyU2l6ZSA/IDRcbiAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXQoMCwgMCwgMCwgMjU1KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mb250Lm91dGxpbmU/XG4gICAgICAgICAgICAgICAgQGZvbnQuYm9yZGVyID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUgPyBub1xuICAgICAgICAgICAgICAgIEBmb250LmJvcmRlclNpemUgPSBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5zaXplID8gNFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yP1xuICAgICAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXRGcm9tQXJyYXkoZGVzY3JpcHRvci5mb250Lm91dGxpbmUuY29sb3IpXG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBAZm9udC5ib3JkZXJDb2xvci5zZXQoMCwgMCwgMCwgMjU1KVxuICAgIFxuICAgICMjIypcbiAgICAqIEFwcGxpZXMgdGhlIHN0eWxlIHRvIGEgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgYXBwbHlcbiAgICAqIEBwYXJhbSB7dWkuT2JqZWN0X1VJRWxlbWVudH0gb2JqZWN0IC0gVGhlIFVJIG9iamVjdCB3aGVyZSB0aGUgc3R5bGUgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgIyMjICAgICAgICAgICAgICAgIFxuICAgIGFwcGx5OiAob2JqZWN0KSAtPlxuICAgICAgICBpZiBub3Qgb2JqZWN0LmFjdGl2ZVN0eWxlcy5jb250YWlucyh0aGlzKVxuICAgICAgICAgICAgb2JqZWN0LmFjdGl2ZVN0eWxlcy5wdXNoKHRoaXMpXG4gICAgICAgICAgICBpZiBAZm9udCB0aGVuIG9iamVjdC5mb250Py5zZXQoQGZvbnQpXG4gICAgICAgICAgICBpZiBAY29sb3IgdGhlbiBvYmplY3QuY29sb3Iuc2V0KEBjb2xvcilcbiAgICAgICAgICAgIGlmIEB0b25lIHRoZW4gb2JqZWN0LnRvbmU/LnNldChAdG9uZSlcbiAgICAgICAgICAgIGlmIEBpbWFnZSB0aGVuIG9iamVjdC5pbWFnZSA9IEBpbWFnZVxuICAgICAgICAgICAgaWYgQGFuY2hvciB0aGVuIG9iamVjdC5hbmNob3Iuc2V0KEBhbmNob3IueCwgQGFuY2hvci55KVxuICAgICAgICAgICAgaWYgQHpvb20gdGhlbiBvYmplY3Quem9vbS5zZXQoQHpvb20ueCwgQHpvb20ueSlcbiAgICAgICAgICAgIGlmIEBwYWRkaW5nIHRoZW4gb2JqZWN0LnBhZGRpbmcuc2V0RnJvbU9iamVjdChAcGFkZGluZylcbiAgICAgICAgICAgIGlmIEBtYXJnaW4gdGhlbiBvYmplY3QubWFyZ2luLnNldEZyb21PYmplY3QoQG1hcmdpbilcbiAgICAgICAgICAgIGlmIEBvcGFjaXR5ID49IDAgdGhlbiBvYmplY3Qub3BhY2l0eSA9IEBvcGFjaXR5XG4gICAgICAgICAgICBpZiBAYWxpZ25tZW50ID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50ID0gQGFsaWdubWVudFxuICAgICAgICAgICAgaWYgQGZyYW1lVGhpY2tuZXNzID49IDAgdGhlbiBvYmplY3QuZnJhbWVUaGlja25lc3MgPSBAZnJhbWVUaGlja25lc3NcbiAgICAgICAgICAgIGlmIEBmcmFtZUNvcm5lclNpemUgPj0gMCB0aGVuIG9iamVjdC5mcmFtZUNvcm5lclNpemUgPSBAZnJhbWVDb3JuZXJTaXplXG4gICAgICAgICAgICBpZiBAbWFzayB0aGVuIG9iamVjdC5tYXNrLnNldChAbWFzaylcbiAgICAgICAgICAgIGlmIEB6SW5kZXggPj0gMCB0aGVuIG9iamVjdC56SW5kZXggPSBAekluZGV4XG4gICAgICAgICAgICBpZiBAYWxpZ25tZW50WCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudFggPSBAYWxpZ25tZW50WFxuICAgICAgICAgICAgaWYgQGFsaWdubWVudFkgPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRZID0gQGFsaWdubWVudFlcbiAgICAgICAgICAgIGlmIEByZXNpemFibGU/IHRoZW4gb2JqZWN0LnJlc2l6YWJsZSA9IEByZXNpemFibGVcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGFwcGx5TG9vcGluZyhvYmplY3QpXG4gICAgICAgICAgICBAYXBwbHlBbmltYXRpb25zKG9iamVjdClcbiAgICAgXG4gICAgIyMjKlxuICAgICogQXBwbGllcyB0aGUgbG9vcGluZy1kYXRhIG9mIHRoZSBzdHlsZSB0byBhIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFwcGx5TG9vcGluZ1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBsb29waW5nLWRhdGEgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICBcbiAgICBhcHBseUxvb3Bpbmc6IChvYmplY3QpIC0+XG4gICAgICAgIGlmIEBsb29waW5nXG4gICAgICAgICAgICBpZiAhb2JqZWN0LnZpc3VhbC5sb29waW5nXG4gICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICBvYmplY3QucmVtb3ZlQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbCA9IG5ldyBncy5Db21wb25lbnRfVGlsaW5nU3ByaXRlKClcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIG9iamVjdC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IEBsb29waW5nLnZlcnRpY2FsXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IEBsb29waW5nLmhvcml6b250YWxcbiAgICAgXG4gICAgIyMjKlxuICAgICogQXBwbGllcyB0aGUgYW5pbWF0aW9uLWRhdGEgb2YgdGhlIHN0eWxlIHRvIGEgVUkgb2JqZWN0LiBUaGlzIGF1dG9tYXRpY2FsbHkgYWRkcyBhbiBhbmltYXRpb24taGFuZGxlclxuICAgICogY29tcG9uZW50KHVpLkNvbXBvbmVudF9BbmltYXRpb25IYW5kbGVyKSB3aXRoIHRoZSBpZCBcImFuaW1hdGlvbkhhbmRsZXJcIiB0byB0aGUgVUkgb2JqZWN0IGlmIG5vdCBhbHJlYWR5IGV4aXN0cy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFwcGx5QW5pbWF0aW9uc1xuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBhbmltYXRpb24tZGF0YSBzaG91bGQgYmUgYXBwbGllZCB0by5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgIFxuICAgIGFwcGx5QW5pbWF0aW9uczogKG9iamVjdCkgLT5cbiAgICAgICAgaWYgQGFuaW1hdGlvbnNcbiAgICAgICAgICAgIG9iamVjdC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KEBhbmltYXRpb25zKVxuICAgICAgICAgICAgaWYgIW9iamVjdC5maW5kQ29tcG9uZW50QnlJZChcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICBvYmplY3QuYW5pbWF0aW9uRXhlY3V0b3IgPSBuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkV4ZWN1dG9yKClcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQW5pbWF0aW9uSGFuZGxlcigpLCBcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC5hbmltYXRpb25FeGVjdXRvciwgXCJhbmltYXRpb25FeGVjdXRvclwiKVxuICAgICAgICAgICAgICAgIFxuICAgICAgXG4gICAgIyMjKlxuICAgICogUmV2ZXJ0cyB0aGUgY2hhbmdlcyBmcm9tIGEgVUkgb2JqZWN0IG1hZGUgYnkgdGhpcyBzdHlsZS4gSG93ZXZlciwgdGhpcyByZXNldHMgYWxsIHN0eWxlYWJsZSBwcm9wZXJ0aWVzXG4gICAgKiB3ZXJlIHNldCBieSB0aGlzIHN0eWxlLiBTbyBpdCBpcyBuZWNlc3NhcnkgdG8gYXBwbHkgYWxsIG90aGVyIHN0eWxlcyBhZ2FpbiwgYnV0IHRoYXQgaXMgYWxyZWFkeSBoYW5kbGVzIGluXG4gICAgKiB1aS5Db21wb25lbnRfVUlCZWhhdmlvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHJldmVydFxuICAgICogQHBhcmFtIHt1aS5PYmplY3RfVUlFbGVtZW50fSBvYmplY3QgLSBUaGUgVUkgb2JqZWN0IHdoZXJlIHRoZSBzdHlsZSBzaG91bGQgYmUgcmV2ZXJ0ZWQuXG4gICAgIyMjICAgICAgICAgICAgIFxuICAgIHJldmVydDogKG9iamVjdCkgLT5cbiAgICAgICAgYWN0aXZlU3R5bGVzID0gb2JqZWN0LmFjdGl2ZVN0eWxlc1xuICAgICAgICBpZiBvYmplY3QuYWN0aXZlU3R5bGVzLmNvbnRhaW5zKHRoaXMpXG4gICAgICAgICAgICBvYmplY3QuYWN0aXZlU3R5bGVzLnJlbW92ZSh0aGlzKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBAZm9udCB0aGVuIG9iamVjdC5mb250LnNldChncy5Gb250cy5URVhUKTsgICAgICAgICAgICAgICAoaWYgcy5mb250IHRoZW4gb2JqZWN0LmZvbnQuc2V0KHMuZm9udCk7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBjb2xvciB0aGVuIG9iamVjdC5jb2xvci5zZXQoQ29sb3IuV0hJVEUpOyAgICAgICAgICAgICAgIChpZiBzLmNvbG9yIHRoZW4gb2JqZWN0LmNvbG9yLnNldChzLmNvbG9yKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQHRvbmUgdGhlbiBvYmplY3QudG9uZT8uc2V0KDAsIDAsIDAsIDApOyAgICAgICAgICAgICAgICAgKGlmIHMudG9uZSB0aGVuIG9iamVjdC50b25lPy5zZXQocy50b25lKTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGltYWdlIHRoZW4gb2JqZWN0LmltYWdlID0gbnVsbDsgICAgICAgICAgICAgICAgICAgICAgICAgKGlmIHMuaW1hZ2UgdGhlbiBvYmplY3QuaW1hZ2UgPSBzLmltYWdlOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAYW5jaG9yIHRoZW4gb2JqZWN0LmFuY2hvci5zZXQoMCwgMCk7ICAgICAgICAgICAgICAgICAgICAoaWYgcy5hbmNob3IgdGhlbiBvYmplY3QuYW5jaG9yLnNldEZyb21PYmplY3Qocy5hbmNob3IpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAem9vbSB0aGVuIG9iamVjdC56b29tLnNldCgxLjAsIDEuMCk7ICAgICAgICAgICAgICAgICAgICAoaWYgcy56b29tIHRoZW4gb2JqZWN0Lnpvb20uc2V0RnJvbU9iamVjdChzLnpvb20pOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAcGFkZGluZyB0aGVuIG9iamVjdC5wYWRkaW5nLnNldCgwLCAwLCAwLCAwKTsgICAgICAgICAgICAoaWYgcy5wYWRkaW5nIHRoZW4gb2JqZWN0LnBhZGRpbmcuc2V0RnJvbU9iamVjdChzLnBhZGRpbmcpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAbWFyZ2luIHRoZW4gb2JqZWN0Lm1hcmdpbi5zZXQoMCwgMCwgMCwgMCk7ICAgICAgICAgICAgICAoaWYgcy5tYXJnaW4gdGhlbiBvYmplY3QubWFyZ2luLnNldEZyb21PYmplY3Qocy5tYXJnaW4pOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAb3BhY2l0eSA+PSAwIHRoZW4gb2JqZWN0Lm9wYWNpdHkgPSAyNTU7ICAgICAgICAgICAgICAgICAoaWYgcy5vcGFjaXR5ID49IDAgdGhlbiBvYmplY3Qub3BhY2l0eSA9IHMub3BhY2l0eTsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGFsaWdubWVudCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudCA9IDA7ICAgICAgICAgICAgICAgKGlmIHMuYWxpZ25tZW50ID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50ID0gcy5hbGlnbm1lbnQ7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBmcmFtZUNvcm5lclNpemUgPj0gMCB0aGVuIG9iamVjdC5mcmFtZUNvcm5lclNpemUgPSAxNjsgIChpZiBzLmZyYW1lQ29ybmVyU2l6ZSA+PSAwIHRoZW4gb2JqZWN0LmZyYW1lQ29ybmVyU2l6ZSA9IHMuZnJhbWVDb3JuZXJTaXplOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAZnJhbWVUaGlja25lc3MgPj0gMCB0aGVuIG9iamVjdC5mcmFtZVRoaWNrbmVzcyA9IDE2OyAgICAoaWYgcy5mcmFtZVRoaWNrbmVzcyA+PSAwIHRoZW4gb2JqZWN0LmZyYW1lVGhpY2tuZXNzID0gcy5mcmFtZVRoaWNrbmVzczsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQG1hc2sgdGhlbiBvYmplY3QubWFzay5zZXQobnVsbCk7ICAgICAgICAgICAgICAgICAgICAgICAgKGlmIHMubWFzayB0aGVuIG9iamVjdC5tYXNrLnNldChzLmZvbnQpOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAekluZGV4ID49IDAgdGhlbiBvYmplY3QuekluZGV4ID0gMDsgICAgICAgICAgICAgICAgICAgICAoaWYgcy56SW5kZXggPj0gMCB0aGVuIG9iamVjdC56SW5kZXggPSBzLnpJbmRleDsgYnJlYWspIGZvciBzIGluIGFjdGl2ZVN0eWxlcyBieSAtMVxuICAgICAgICAgICAgaWYgQGFsaWdubWVudFggPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRYID0gMDsgICAgICAgICAgICAgKGlmIHMuYWxpZ25tZW50WCA+PSAwIHRoZW4gb2JqZWN0LmFsaWdubWVudFggPSBzLmFsaWdubWVudFg7IGJyZWFrKSBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgIGlmIEBhbGlnbm1lbnRZID49IDAgdGhlbiBvYmplY3QuYWxpZ25tZW50WSA9IDA7ICAgICAgICAgICAgIChpZiBzLmFsaWdubWVudFkgPj0gMCB0aGVuIG9iamVjdC5hbGlnbm1lbnRZID0gcy5hbGlnbm1lbnRZOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBpZiBAcmVzaXphYmxlPyB0aGVuIG9iamVjdC5yZXNpemFibGUgPSBubzsgICAgICAgICAgICAgICAgICAoaWYgcy5yZXNpemFibGU/IHRoZW4gb2JqZWN0LnJlc2l6YWJsZSA9IHMucmVzaXphYmxlOyBicmVhaykgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEByZXZlcnRBbmltYXRpb25zKG9iamVjdClcbiAgICAgICAgICAgIEByZXZlcnRMb29waW5nKG9iamVjdClcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogUmV2ZXJ0cyB0aGUgYW5pbWF0aW9uLWRhdGEgY2hhbmdlcyBhcHBsaWVkIHRvIGEgVUkgb2JqZWN0IGJ5IHRoaXMgc3R5bGUuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXZlcnRBbmltYXRpb25zXG4gICAgKiBAcGFyYW0ge3VpLk9iamVjdF9VSUVsZW1lbnR9IG9iamVjdCAtIFRoZSBVSSBvYmplY3Qgd2hlcmUgdGhlIGFuaW1hdGlvbi1kYXRhIGNoYW5nZXMgc2hvdWxkIGJlIHJldmVydGVkLlxuICAgICMjIyAgICAgICAgICAgICAgICAgXG4gICAgcmV2ZXJ0QW5pbWF0aW9uczogKG9iamVjdCkgLT5cbiAgICAgICAgYWN0aXZlU3R5bGVzID0gb2JqZWN0LmFjdGl2ZVN0eWxlc1xuICAgICAgICBpZiBAYW5pbWF0aW9uc1xuICAgICAgICAgICAgb2JqZWN0LmFuaW1hdGlvbnMgPSBudWxsOyAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgZm9yIHMgaW4gYWN0aXZlU3R5bGVzIGJ5IC0xXG4gICAgICAgICAgICAgICAgaWYgcy5hbmltYXRpb25zXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KHMuYW5pbWF0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgaWYgIW9iamVjdC5maW5kQ29tcG9uZW50QnlJZChcImFuaW1hdGlvbkhhbmRsZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5hZGRDb21wb25lbnQobmV3IHVpLkNvbXBvbmVudF9BbmltYXRpb25IYW5kbGVyKCksIFwiYW5pbWF0aW9uSGFuZGxlclwiKVxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBSZXZlcnRzIHRoZSBsb29waW5nLWRhdGEgY2hhbmdlcyBhcHBsaWVkIHRvIGEgVUkgb2JqZWN0IGJ5IHRoaXMgc3R5bGUuXG4gICAgKlxuICAgICogQG1ldGhvZCByZXZlcnRMb29waW5nXG4gICAgKiBAcGFyYW0ge3VpLk9iamVjdF9VSUVsZW1lbnR9IG9iamVjdCAtIFRoZSBVSSBvYmplY3Qgd2hlcmUgdGhlIGxvb3BpbmctZGF0YSBjaGFuZ2VzIHNob3VsZCBiZSByZXZlcnRlZC5cbiAgICAjIyMgICAgICAgICAgICAgICAgIFxuICAgIHJldmVydExvb3Bpbmc6IChvYmplY3QpIC0+XG4gICAgICAgIGFjdGl2ZVN0eWxlcyA9IG9iamVjdC5hY3RpdmVTdHlsZXNcbiAgICAgICAgaWYgQGxvb3BpbmdcbiAgICAgICAgICAgIG9iamVjdC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IG5vXG4gICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IG5vXG4gICAgICAgICAgICBmb3IgcyBpbiBhY3RpdmVTdHlsZXMgYnkgLTFcbiAgICAgICAgICAgICAgICBpZiBzLmxvb3BpbmdcbiAgICAgICAgICAgICAgICAgICAgaWYgIW9iamVjdC52aXN1YWwubG9vcGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5yZW1vdmVDb21wb25lbnQob2JqZWN0LnZpc3VhbClcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC52aXN1YWwgPSBuZXcgZ3MuQ29tcG9uZW50X1RpbGluZ1Nwcml0ZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuYWRkQ29tcG9uZW50KG9iamVjdC52aXN1YWwpXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBvYmplY3QudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBzLmxvb3BpbmcudmVydGljYWxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZpc3VhbC5sb29waW5nLmhvcml6b250YWwgPSBzLmxvb3BpbmcuaG9yaXpvbnRhbFxuICAgICAgICAgICAgXG51aS5TdHlsZSA9IFN0eWxlXG5cbmNsYXNzIFVJTWFuYWdlclxuICAgICMjIypcbiAgICAqIEhhbmRsZXMgdGhlIGNyZWF0aW9uIG9mIEluIEdhbWUgVUkgZWxlbWVudHMuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0XG4gICAgKiBJbi1HYW1lIFVJIHNlZSBoZWxwIGZpbGUuXG4gICAgKlxuICAgICogQG1vZHVsZSB1aVxuICAgICogQGNsYXNzIFVJTWFuYWdlclxuICAgICogQG1lbWJlcm9mIHVpXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAjIyNcbiAgICBjb25zdHJ1Y3RvcjogLT5cbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBVSSBsYXlvdXRzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGxheW91dHNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBsYXlvdXRzID0ge31cbiAgICAgICAgXG4gICAgICAgICMjIypcbiAgICAgICAgKiBTdG9yZXMgYWxsIHJlZ2lzdGVyZWQgVUkgc3R5bGVzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IHN0eWxlc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCBVSSBzdHlsZXMgYnkgbnVtYmVyIGlkLlxuICAgICAgICAqIEBwcm9wZXJ0eSBzdHlsZXNCeUlkXG4gICAgICAgICogQHR5cGUgdWkuU3R5bGVbXVxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlc0J5SWQgPSBuZXcgQXJyYXkoKVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgVUkgc3R5bGVzIGJ5IHN0eWxlLW5hbWUuXG4gICAgICAgICogQHByb3BlcnR5IHN0eWxlc0J5TmFtZVxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHN0eWxlc0J5TmFtZSA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCByZWdpc3RlcmVkIGN1c3RvbSBVSSB0eXBlcy90ZW1wbGF0ZXMgYnkgbmFtZS9pZC5cbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tVHlwZXNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBjdXN0b21UeXBlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogU3RvcmVzIGFsbCByZWdpc3RlcmVkIFVJIGNvbnRyb2xsZXJzIGJ5IG5hbWUvaWQuXG4gICAgICAgICogQHByb3BlcnR5IGN1c3RvbVR5cGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICMjI1xuICAgICAgICBAY29udHJvbGxlcnMgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgcmVnaXN0ZXJlZCBVSSBkYXRhIHNvdXJjZXMgYnkgbmFtZS9pZC5cbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tVHlwZXNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgIyMjXG4gICAgICAgIEBkYXRhU291cmNlcyA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogTWFwcGluZyB0byB0YWJsZSB0byBtYXAgYWxpZ25tZW50IG5hbWVzIHRvIG51bWJlciB2YWx1ZXMuXG4gICAgICAgICogQHByb3BlcnR5IGFsaWdubWVudHNcbiAgICAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgICAgKiBAcHJvdGVjdGVkXG4gICAgICAgICMjI1xuICAgICAgICBAYWxpZ25tZW50cyA9IHsgXCJsZWZ0XCI6IDAsIFwidG9wXCI6IDAsIFwiY2VudGVyXCI6IDEsIFwiYm90dG9tXCI6IDIsIFwicmlnaHRcIjogMiwgXCIwXCI6IDAsIFwiMVwiOiAxLCBcIjJcIjogMiB9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogTWFwcGluZyB0byB0YWJsZSB0byBtYXAgYmxlbmQtbW9kZSBuYW1lcyB0byBudW1iZXIgdmFsdWVzLlxuICAgICAgICAqIEBwcm9wZXJ0eSBibGVuZE1vZGVzXG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyNcbiAgICAgICAgQGJsZW5kTW9kZXMgPSB7IFwibm9ybWFsXCI6IDAsIFwiYWRkXCI6IDEsIFwic3ViXCI6IDIgfVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIE1hcHBpbmcgdG8gdGFibGUgdG8gbWFwIHNlbGVjdG9yIG5hbWVzIHRvIG51bWJlciB2YWx1ZXMuXG4gICAgICAgICogQHByb3BlcnR5IHNlbGVjdG9yc1xuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAjIyNcbiAgICAgICAgQHNlbGVjdG9ycyA9IHsgbm9ybWFsOiAwLCBob3ZlcjogMSwgc2VsZWN0ZWQ6IDIsIGVuYWJsZWQ6IDMsIGZvY3VzZWQ6IDQgfVxuICAgICAgICBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zID0ge31cbiAgICBcbiAgICAjIyMqXG4gICAgKiBTZXRzIHVwIFVJIE1hbmFnZXIsIG9wdGltaXplcyBzdHlsZXMsIGV0Yy5cbiAgICAqXG4gICAgKiBAbWV0aG9kIHNldHVwXG4gICAgIyMjXG4gICAgc2V0dXA6IC0+XG4gICAgICAgIEBzZXR1cFN0eWxlcygpXG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIFNldHMgdXAgdGhlIFVJIHN0eWxlcyBieSB3cmFwcGluZyB0aGVtIGludG8gdWkuU3R5bGUgb2JqZWN0cyBhbmQgb3B0aW1pemluZyB0aGUgYWNjZXNzLlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0dXBTdHlsZXNcbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyNcbiAgICBzZXR1cFN0eWxlczogLT5cbiAgICAgICAgaWQgPSAwXG4gICAgICAgIHNlbGVjdG9yTWFwID0gQHNlbGVjdG9yc1xuICAgICAgICBmb3IgayBvZiBAc3R5bGVzXG4gICAgICAgICAgICBzdWJzID0gay5zcGxpdChcIiBcIilcbiAgICAgICAgICAgIHNlbGVjdG9yID0gc3Vic1swXS5zcGxpdChcIjpcIilcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgc2VsZWN0b3JNYXBbc2VsZWN0b3JbMV1dXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5SWRbaWRdID0gbmV3IHVpLlN0eWxlKEBzdHlsZXNba10sIGlkLCBzZWxlY3Rvck1hcFtzZWxlY3RvclsxXV0pXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgQHN0eWxlc0J5SWRbaWRdID0gbmV3IHVpLlN0eWxlKEBzdHlsZXNba10sIGlkLCAwKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAhQHN0eWxlc0J5TmFtZVtzZWxlY3RvclswXV1cbiAgICAgICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3NlbGVjdG9yWzBdXSA9IFtdXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3NlbGVjdG9yWzBdXS5wdXNoKEBzdHlsZXNCeUlkW2lkXSlcbiAgICAgICAgICAgIEBzdHlsZXNba10gPSBAc3R5bGVzQnlJZFtpZF1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWQrK1xuICAgICAgICBcbiAgICAgICAgZm9yIGsgb2YgQHN0eWxlc1xuICAgICAgICAgICAgc3VicyA9IGsuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgICBpZiBzdWJzLmxlbmd0aCA+IDFcbiAgICAgICAgICAgICAgICBAc3R5bGVzQnlOYW1lW3N1YnNbMV1dLnB1c2goQHN0eWxlc1trXSlcbiAgICAgICAgICAgICAgICBAc3R5bGVzW2tdLnRhcmdldCA9IEBzdHlsZXNbay5zcGxpdChcIjpcIilbMF1dPy5pZFxuICAgICAgICAgICAgICAgICNAc3R5bGVzW3N1YnNbMV1dLnRhcmdldCA9IEBzdHlsZXNba10uaWRcbiAgICAgICAgICAgICAgICAjQHN0eWxlc1trXS50YXJnZXQgPSBAc3R5bGVzW3N1YnNbMV1dLmlkXG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogRXhlY3V0ZXMgYWxsIHBsYWNlaG9sZGVyIGZvcm11bGFzIGluIHRoZSBzcGVjaWZpZWQgZGVzY3JpcHRvci4gVGhlIGRlc2NyaXB0b3Igd2lsbCBiZSBjaGFuZ2VkXG4gICAgKiBhbmQgcGxhY2Vob2xkZXIgZm9ybXVsYXMgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIgZXZhbHVhdGVkIHJlc3VsdCB2YWx1ZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBkZXNjcmlwdG9yLlxuICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIE9iamVjdCBjb250YWluaW5nIHRoZSBwbGFjZWhvbGRlciBwYXJhbXMuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgIFxuICAgIGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzOiAoZGVzY3JpcHRvciwgaWQsIHBhcmFtcykgLT5cbiAgICAgICAgcmV0dXJuIGlmIG5vdCBkZXNjcmlwdG9yP1xuICAgICAgICBrZXlzID0gT2JqZWN0LmtleXMoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIFxuICAgICAgICBmb3IgayBpbiBrZXlzXG4gICAgICAgICAgICB2ID0gZGVzY3JpcHRvcltrXVxuICAgICAgICAgICAgaWYgdj9cbiAgICAgICAgICAgICAgICBpZiB2IGluc3RhbmNlb2YgQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgZm9yIGksIGMgaW4gdlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgaT9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiB0eXBlb2YgaSA9PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhcyhpLCBpZCwgcGFyYW1zKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgYyAhPSBcImV4ZWNcIiBhbmQgdHlwZW9mIGkgPT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5wID0gcGFyYW1zIHx8ICBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5kID0gZGVzY3JpcHRvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2W2NdID0gaSgpXG4gICAgICAgICAgICAgICAgZWxzZSBpZiB0eXBlb2YgdiA9PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgIEBleGVjdXRlUGxhY2Vob2xkZXJGb3JtdWxhcyh2LCBpZCwgcGFyYW1zKVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgayAhPSBcImV4ZWNfXCIgYW5kIHR5cGVvZiB2ID09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cucCA9IHBhcmFtcyB8fCBAZGVmYXVsdFBsYWNlaG9sZGVyUGFyYW1zXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5kID0gZGVzY3JpcHRvclxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yW2tdID0gdigpXG4gICAgICAgIHJldHVybiBudWxsXG5cbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgY2FsY3VsYXRpb24gZm9yIGEgc3BlY2lmaWVkIGV4cHJlc3Npb24uXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVDYWxjRnVuY3Rpb25cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBleHByZXNzaW9uIC0gVGhlIGV4cHJlc3Npb24gdG8gY3JlYXRlIGEgY2FsY3VsYXRpb24gZnVuY3Rpb24gZm9yLlxuICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBjYWxjdWxhdGlvbiBmdW5jdGlvbi5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgICBcbiAgICBjcmVhdGVDYWxjRnVuY3Rpb246IChleHByZXNzaW9uKSAtPlxuICAgICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5yZXBsYWNlKC8oWzAtOV0rKSUvZ20sIFwiKCQxIC8gMTAwICogdilcIilcbiAgICAgICAgcmV0dXJuIGV2YWwoXCIoZnVuY3Rpb24odil7IHJldHVybiBcIiArIGV4cHJlc3Npb24gKyBcIn0pXCIpXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBvYmplY3QgZnJvbSB0aGUgc3BlY2lmaWVkIG9iamVjdCB0eXBlLiBUaGUgdHlwZSBoYXMgdGhlIGZvcm1hdFxuICAgICogPG5hbWVzcGFjZT4uPHR5cGVuYW1lPiBsaWtlIHZuLkNvbXBvbmVudF9Ib3RzcG90LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlT2JqZWN0XG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG5hbWUuXG4gICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgICAgICAgICAgICAgXG4gICAgY3JlYXRlT2JqZWN0OiAodHlwZSkgLT5cbiAgICAgICAgc3VicyA9IHR5cGUuc3BsaXQoXCIuXCIpXG4gICAgICAgIHJldHVybiBuZXcgd2luZG93W3N1YnNbMF1dW3N1YnNbMV1dKClcbiAgICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gVUkgb2JqZWN0IGZyb20gYSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUZyb21EZXNjcmlwdG9yXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEBwYXJhbSB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gcGFyZW50IC0gVGhlIFVJIHBhcmVudCBvYmplY3QuIChBIGxheW91dCBmb3IgZXhhbXBsZSkuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBVSSBvYmplY3QuXG4gICAgIyMjICAgXG4gICAgY3JlYXRlRnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yLCBwYXJlbnQpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBudWxsXG4gICAgICAgIFxuICAgICAgICBmb3IgayBvZiBAY29udHJvbGxlcnNcbiAgICAgICAgICAgIGlmIEBjb250cm9sbGVyc1trXS50eXBlP1xuICAgICAgICAgICAgICAgIEBjb250cm9sbGVyc1trXSA9IEBjcmVhdGVPYmplY3QoQGNvbnRyb2xsZXJzW2tdLnR5cGUpXG4gICAgICAgICAgICBcbiAgICAgICAgQF9jcmVhdGVGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLCBwYXJlbnQpXG4gICAgXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlSW1hZ2VCdXR0b25cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgIFxuICAgIGNyZWF0ZUltYWdlQnV0dG9uOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfSG90c3BvdChkZXNjcmlwdG9yLmltYWdlLCBkZXNjcmlwdG9yLmltYWdlSGFuZGxpbmcpIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmJlaGF2aW9yLnNvdW5kID0gZGVzY3JpcHRvci5zb3VuZFxuICAgICAgICBjb250cm9sLmJlaGF2aW9yLnNvdW5kcyA9IGRlc2NyaXB0b3Iuc291bmRzXG4gICAgICAgIGNvbnRyb2wuaW1hZ2UgPSBkZXNjcmlwdG9yLmltYWdlXG4gICAgICAgIGNvbnRyb2wuaW1hZ2VzID0gZGVzY3JpcHRvci5pbWFnZXNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5pbWFnZUZvbGRlcj9cbiAgICAgICAgICAgIGNvbnRyb2wuaW1hZ2VGb2xkZXIgPSBkZXNjcmlwdG9yLmltYWdlRm9sZGVyXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5sb29waW5nP1xuICAgICAgICAgICAgY29udHJvbC52aXN1YWwuZGlzcG9zZSgpXG4gICAgICAgICAgICBjb250cm9sLnJlbW92ZUNvbXBvbmVudChjb250cm9sLnZpc3VhbClcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsID0gbmV3IGdzLkNvbXBvbmVudF9UaWxpbmdTcHJpdGUoKVxuICAgICAgICAgICAgY29udHJvbC5hZGRDb21wb25lbnQoY29udHJvbC52aXN1YWwpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcudmVydGljYWwgPSBkZXNjcmlwdG9yLmxvb3BpbmcudmVydGljYWxcbiAgICAgICAgICAgIGNvbnRyb2wudmlzdWFsLmxvb3BpbmcuaG9yaXpvbnRhbCA9IGRlc2NyaXB0b3IubG9vcGluZy5ob3Jpem9udGFsXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuY29sb3I/XG4gICAgICAgICAgICBjb250cm9sLmNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuY29sb3IpXG4gICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVJbWFnZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgXG4gICAgY3JlYXRlSW1hZ2U6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9JbWFnZShkZXNjcmlwdG9yLmltYWdlLCBkZXNjcmlwdG9yLmltYWdlSGFuZGxpbmcpIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmltYWdlRm9sZGVyP1xuICAgICAgICAgICAgY29udHJvbC5pbWFnZUZvbGRlciA9IGRlc2NyaXB0b3IuaW1hZ2VGb2xkZXJcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmxvb3Bpbmc/XG4gICAgICAgICAgICBjb250cm9sLnZpc3VhbC5kaXNwb3NlKClcbiAgICAgICAgICAgIGNvbnRyb2wucmVtb3ZlQ29tcG9uZW50KGNvbnRyb2wudmlzdWFsKVxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwgPSBuZXcgZ3MuQ29tcG9uZW50X1RpbGluZ1Nwcml0ZSgpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb250cm9sLnZpc3VhbClcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwubG9vcGluZy52ZXJ0aWNhbCA9IGRlc2NyaXB0b3IubG9vcGluZy52ZXJ0aWNhbFxuICAgICAgICAgICAgY29udHJvbC52aXN1YWwubG9vcGluZy5ob3Jpem9udGFsID0gZGVzY3JpcHRvci5sb29waW5nLmhvcml6b250YWxcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBpbWFnZSBtYXAgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlSW1hZ2VNYXBcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgICAgIFxuICAgIGNyZWF0ZUltYWdlTWFwOiAoZGVzY3JpcHRvcikgLT5cbiAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfSW1hZ2VNYXAoKVxuICAgICAgICBjb250cm9sLmhvdHNwb3RzID0gKGRlc2NyaXB0b3IuaG90c3BvdHN8fFtdKS5zZWxlY3QgKGgpIC0+IFxuICAgICAgICAgICAgeyB4OiBoLnJlY3RbMF0sIHk6IGgucmVjdFsxXSwgc2l6ZTogeyB3aWR0aDogaC5yZWN0WzJdLCBoZWlnaHQ6IGgucmVjdFszXSB9LCBkYXRhOiB7IGFjdGlvbjogMywgYWN0aW9uczogaC5hY3Rpb25zIH0gfVxuICAgICAgICBjb250cm9sLmltYWdlcyA9IGRlc2NyaXB0b3IuaW1hZ2VzXG4gICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQWN0aW9uSGFuZGxlcigpLCAxLCBcImFjdGlvbkhhbmRsZXJcIilcbiAgICAgICAgY29udHJvbC50YXJnZXQgPSBTY2VuZU1hbmFnZXIuc2NlbmUuYmVoYXZpb3JcbiAgICAgICAgY29udHJvbC52aXN1YWwudmFyaWFibGVDb250ZXh0ID0gbmV3IGdzLkludGVycHJldGVyQ29udGV4dChTY2VuZU1hbmFnZXIuc2NlbmUubGF5b3V0TmFtZSwgU2NlbmVNYW5hZ2VyLnNjZW5lKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgdmlkZW8gVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlVmlkZW9cbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlVmlkZW86IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9WaWRlbygpXG4gICAgICAgIGNvbnRyb2wudmlkZW8gPSBkZXNjcmlwdG9yLnZpZGVvXG4gICAgICAgIGNvbnRyb2wubG9vcCA9IGRlc2NyaXB0b3IubG9vcCA/IHllc1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgcGFuZWwgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlUGFuZWxcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgICAgXG4gICAgY3JlYXRlUGFuZWw6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9QYW5lbCgpXG4gICAgICAgIGNvbnRyb2wubW9kYWwgPSBkZXNjcmlwdG9yLm1vZGFsID8gbm9cbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBmcmFtZSBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVGcmFtZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgICAgICAgXG4gICAgY3JlYXRlRnJhbWU6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9GcmFtZShkZXNjcmlwdG9yLmZyYW1lU2tpbilcbiAgICAgICAgY29udHJvbC5mcmFtZVRoaWNrbmVzcyA9IGRlc2NyaXB0b3IuZnJhbWVUaGlja25lc3MgfHwgMTZcbiAgICAgICAgY29udHJvbC5mcmFtZUNvcm5lclNpemUgPSBkZXNjcmlwdG9yLmZyYW1lQ29ybmVyU2l6ZSB8fCAxNlxuICAgICAgICBjb250cm9sLmltYWdlID0gZGVzY3JpcHRvci5pbWFnZVxuICAgICAgICBjb250cm9sLmltYWdlcyA9IGRlc2NyaXB0b3IuaW1hZ2VzXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSB0aHJlZS1wYXJ0IGltYWdlIFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVRocmVlUGFydEltYWdlXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVUaHJlZVBhcnRJbWFnZTogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1RocmVlUGFydEltYWdlKGRlc2NyaXB0b3IuZnJhbWVTa2luKVxuICAgICAgICBjb250cm9sLmZpcnN0UGFydFNpemUgPSBkZXNjcmlwdG9yLmZpcnN0UGFydFNpemUgfHwgMTZcbiAgICAgICAgY29udHJvbC5taWRkbGVQYXJ0U2l6ZSA9IGRlc2NyaXB0b3IubWlkZGxlUGFydFNpemUgfHwgMVxuICAgICAgICBjb250cm9sLmxhc3RQYXJ0U2l6ZSA9IGRlc2NyaXB0b3IubGFzdFBhcnRTaXplIHx8IDE2XG4gICAgICAgIGNvbnRyb2wuaW1hZ2UgPSBkZXNjcmlwdG9yLmltYWdlXG4gICAgICAgIGNvbnRyb2wuaW1hZ2VzID0gZGVzY3JpcHRvci5pbWFnZXNcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSB0ZXh0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVRleHRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgIFxuICAgIGNyZWF0ZVRleHQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9UZXh0KClcbiAgICAgICAgY29udHJvbC50ZXh0ID0gbGNzKGRlc2NyaXB0b3IudGV4dClcbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBjb250cm9sLmZvcm1hdHRpbmcgPSBkZXNjcmlwdG9yLmZvcm1hdHRpbmdcbiAgICAgICAgY29udHJvbC53b3JkV3JhcCA9IGRlc2NyaXB0b3Iud29yZFdyYXAgPyBub1xuICAgICAgICBjb250cm9sLmJlaGF2aW9yLmZvcm1hdCA9IGRlc2NyaXB0b3IuZm9ybWF0XG4gICAgICAgIGlmIGRlc2NyaXB0b3IudGV4dFBhZGRpbmdcbiAgICAgICAgICAgIGNvbnRyb2wuYmVoYXZpb3IucGFkZGluZyA9IHVpLlNwYWNlLmZyb21BcnJheShkZXNjcmlwdG9yLnRleHRQYWRkaW5nKVxuICAgICAgICBpZiBkZXNjcmlwdG9yLnJlc29sdmVQbGFjZWhvbGRlcnM/XG4gICAgICAgICAgICBjb250cm9sLnJlc29sdmVQbGFjZWhvbGRlcnMgPSBkZXNjcmlwdG9yLnJlc29sdmVQbGFjZWhvbGRlcnNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb2xvcj9cbiAgICAgICAgICAgIGNvbnRyb2wuY29sb3IgPSBDb2xvci5mcm9tQXJyYXkoZGVzY3JpcHRvci5jb2xvcilcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBmcmVlLWxheW91dCBVSSBvYmplY3QuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVGcmVlTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjIFxuICAgIGNyZWF0ZUZyZWVMYXlvdXQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfRnJlZUxheW91dChkZXNjcmlwdG9yLmZyYW1lWzBdIHx8IDAsIGRlc2NyaXB0b3IuZnJhbWVbMV0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsyXSB8fCAxLCBkZXNjcmlwdG9yLmZyYW1lWzNdIHx8IDEpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X0ZyZWVMYXlvdXQoMCwgMCwgMSwgMSlcbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgc3RhY2stbGF5b3V0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZVN0YWNrTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVTdGFja0xheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9TdGFja0xheW91dChkZXNjcmlwdG9yLmZyYW1lWzBdIHx8IDAsIGRlc2NyaXB0b3IuZnJhbWVbMV0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsyXSB8fCAxLCBkZXNjcmlwdG9yLmZyYW1lWzNdIHx8IDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X1N0YWNrTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgIGNvbnRyb2wuc2l6ZVRvRml0ID0gZGVzY3JpcHRvci5zaXplVG9GaXRcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIHNwcmVhZC1sYXlvdXQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlU3ByZWFkTGF5b3V0XG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIGltYWdlIGJ1dHRvbiBVSSBvYmplY3QuXG4gICAgIyMjICAgICBcbiAgICBjcmVhdGVTcHJlYWRMYXlvdXQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfU3ByZWFkTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0gfHwgMCwgZGVzY3JpcHRvci5mcmFtZVsxXSB8fCAwLCBkZXNjcmlwdG9yLmZyYW1lWzJdIHx8IDEsIGRlc2NyaXB0b3IuZnJhbWVbM10gfHwgMSwgZGVzY3JpcHRvci5vcmllbnRhdGlvbilcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29udHJvbCA9IG5ldyB1aS5PYmplY3RfU3ByZWFkTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iub3JpZW50YXRpb24pXG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIGdyaWQtbGF5b3V0IFVJIG9iamVjdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUdyaWRMYXlvdXRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlR3JpZExheW91dDogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWU/XG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9HcmlkTGF5b3V0KGRlc2NyaXB0b3IuZnJhbWVbMF0sIGRlc2NyaXB0b3IuZnJhbWVbMV0sIGRlc2NyaXB0b3IuZnJhbWVbMl0sIGRlc2NyaXB0b3IuZnJhbWVbM10sIGRlc2NyaXB0b3Iucm93cywgZGVzY3JpcHRvci5jb2x1bW5zLCBkZXNjcmlwdG9yLnRlbXBsYXRlKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9HcmlkTGF5b3V0KDAsIDAsIDEsIDEsIGRlc2NyaXB0b3Iucm93cywgZGVzY3JpcHRvci5jb2x1bW5zLCBkZXNjcmlwdG9yLnRlbXBsYXRlKVxuICAgICAgICBjb250cm9sLmNlbGxTcGFjaW5nID0gZGVzY3JpcHRvci5jZWxsU3BhY2luZyB8fCBbMCwgMCwgMCwgMF1cbiAgICAgICAgY29udHJvbC5zaXplVG9GaXQgPSBkZXNjcmlwdG9yLnNpemVUb0ZpdFxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhIG1lc3NhZ2UgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlTWVzc2FnZVxuICAgICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgLSBUaGUgVUkgb2JqZWN0IGRlc2NyaXB0b3IuXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBpbWFnZSBidXR0b24gVUkgb2JqZWN0LlxuICAgICMjIyAgICAgXG4gICAgY3JlYXRlTWVzc2FnZTogKGRlc2NyaXB0b3IpIC0+XG4gICAgICAgIGNvbnRyb2wgPSBuZXcgdWkuT2JqZWN0X01lc3NhZ2UoKSBcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBjb250cm9sXG4gICAgIFxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYSBkYXRhLWdyaWQgVUkgb2JqZWN0LlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlRGF0YUdyaWRcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHJldHVybiB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gVGhlIGNyZWF0ZWQgaW1hZ2UgYnV0dG9uIFVJIG9iamVjdC5cbiAgICAjIyMgICAgXG4gICAgY3JlYXRlRGF0YUdyaWQ6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbmV3IHVpLk9iamVjdF9EYXRhR3JpZChkZXNjcmlwdG9yKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICAgICAgXG4gICAgIyMjKlxuICAgICogQ3JlYXRlcyBhbiBVSSBvYmplY3QgZGVwZW5kaW5nIG9uIHRoZSBvYmplY3QtdHlwZSBvZiB0aGUgc3BlY2lmaWVkIFVJIGRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBjcmVhdGVDb250cm9sXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIFVJIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWRcbiAgICAjIyMgIFxuICAgIGNyZWF0ZUNvbnRyb2w6IChkZXNjcmlwdG9yKSAtPlxuICAgICAgICBjb250cm9sID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgc3dpdGNoIGRlc2NyaXB0b3IudHlwZVxuICAgICAgICAgICAgd2hlbiBcInVpLkltYWdlQnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUltYWdlQnV0dG9uKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuSW1hZ2VcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlSW1hZ2UoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5JbWFnZU1hcFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVJbWFnZU1hcChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlZpZGVvXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVZpZGVvKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuUGFuZWxcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlUGFuZWwoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5GcmFtZVwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVGcmFtZShkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlRocmVlUGFydEltYWdlXCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZVRocmVlUGFydEltYWdlKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuVGV4dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVUZXh0KGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVNZXNzYWdlKGRlc2NyaXB0b3IpXG4gICAgICAgICAgICB3aGVuIFwidWkuRGF0YUdyaWRcIlxuICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlRGF0YUdyaWQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5GcmVlTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUZyZWVMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5TdGFja0xheW91dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVTdGFja0xheW91dChkZXNjcmlwdG9yKVxuICAgICAgICAgICAgd2hlbiBcInVpLlNwcmVhZExheW91dFwiXG4gICAgICAgICAgICAgICAgY29udHJvbCA9IEBjcmVhdGVTcHJlYWRMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgIHdoZW4gXCJ1aS5HcmlkTGF5b3V0XCJcbiAgICAgICAgICAgICAgICBjb250cm9sID0gQGNyZWF0ZUdyaWRMYXlvdXQoZGVzY3JpcHRvcilcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xcbiAgICBcbiAgICBcbiAgICBjcmVhdGVMYXlvdXRSZWN0OiAoZnJhbWUsIGNvbnRyb2wpIC0+XG4gICAgICAgIGlmICFjb250cm9sLmxheW91dFJlY3RcbiAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdCA9IG5ldyB1aS5MYXlvdXRSZWN0KClcbiAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnNldCgwLCAwLCAwLCAwKVxuICAgICAgICBcbiAgICAgICAgaWYgZnJhbWU/XG4gICAgICAgICAgICBpZiBmcmFtZVswXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC54ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihmcmFtZVswXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueCA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueCA9IChkZXNjcmlwdG9yLmZyYW1lWzBdID8gY29udHJvbC5kc3RSZWN0LngpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBmcmFtZVsxXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC55ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihmcmFtZVsxXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IChmcmFtZVsxXSA/IGNvbnRyb2wuZHN0UmVjdC55KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZnJhbWVbMl0/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3Qud2lkdGggPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzJdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3Qud2lkdGggPSAoZnJhbWVbMl0gPyBjb250cm9sLmRzdFJlY3Qud2lkdGgpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBmcmFtZVszXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC5oZWlnaHQgPSBAY3JlYXRlQ2FsY0Z1bmN0aW9uKGZyYW1lWzNdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQgPSAxXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LmhlaWdodCA9IChmcmFtZVszXSA/IGNvbnRyb2wuZHN0UmVjdC5oZWlnaHQpXG4gICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIEFkZHMgdGhlIHN0eWxlcyBkZWZpbmVkIGluIGFuIGFycmF5IG9mIHN0eWxlLW5hbWVzIHRvIHRoZSBzcGVjaWZpZWQgY29udHJvbC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFkZENvbnRyb2xTdHlsZXNcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250cm9sIC0gVGhlIGNvbnRyb2wgdG8gYWRkIHRoZSBzdHlsZXMgdG8uXG4gICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBzdHlsZXMgLSBBcnJheSBvZiBzdHlsZS1uYW1lcyB0byBhZGQuXG4gICAgIyMjICAgICBcbiAgICBhZGRDb250cm9sU3R5bGVzOiAoY29udHJvbCwgc3R5bGVzKSAtPlxuICAgICAgICBmb3Igc3R5bGVOYW1lIGluIHN0eWxlc1xuICAgICAgICAgICAgaWYgQHN0eWxlc0J5TmFtZVtzdHlsZU5hbWVdP1xuICAgICAgICAgICAgICAgIGZvciBzdHlsZSBpbiBAc3R5bGVzQnlOYW1lW3N0eWxlTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5zdHlsZXMucHVzaChzdHlsZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgc3R5bGUudGFyZ2V0ID09IC0xIGFuZCBzdHlsZS5zZWxlY3RvciA9PSAwXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5hcHBseShjb250cm9sKVxuICAgICMjIypcbiAgICAqIENyZWF0ZXMgYW4gVUkgb2JqZWN0IGZyb20gYSBzcGVjaWZpZWQgVUkgZGVzY3JpcHRvci4gVGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gICAgKiByZWN1cnNpdmVseSBmb3IgYWxsIGNoaWxkLWRlc2NyaXB0b3JzLlxuICAgICpcbiAgICAqIEBtZXRob2QgY3JlYXRlQ29udHJvbEZyb21EZXNjcmlwdG9yXG4gICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciAtIFRoZSBVSSBvYmplY3QgZGVzY3JpcHRvci5cbiAgICAqIEBwYXJhbSB7Z3MuT2JqZWN0X1VJRWxlbWVudH0gcGFyZW50IC0gVGhlIFVJIHBhcmVudCBvYmplY3QuIChBIGxheW91dCBmb3IgZXhhbXBsZSkuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBUaGUgaW5kZXguXG4gICAgKiBAcmV0dXJuIHtncy5PYmplY3RfVUlFbGVtZW50fSBUaGUgY3JlYXRlZCBVSSBvYmplY3QuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgIyMjICAgICAgICBcbiAgICBjcmVhdGVDb250cm9sRnJvbURlc2NyaXB0b3I6IChkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KSAtPlxuICAgICAgICBjb250cm9sID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zdHlsZT9cbiAgICAgICAgICAgIGRlc2NyaXB0b3Iuc3R5bGVzID0gW2Rlc2NyaXB0b3Iuc3R5bGVdXG4gICAgICAgICAgICBkZWxldGUgZGVzY3JpcHRvci5zdHlsZVxuICAgICAgICAgICAgXG4gICAgICAgIGRlc2NyaXB0b3IgPSBPYmplY3QuZGVlcENvcHkoZGVzY3JpcHRvcilcbiAgICAgICAgQGV4ZWN1dGVQbGFjZWhvbGRlckZvcm11bGFzKGRlc2NyaXB0b3IsIGRlc2NyaXB0b3IuaWQsIGRlc2NyaXB0b3IucGFyYW1zKVxuICAgICAgICAgICAgXG4gICAgICAgIGNvbnRyb2wgPSBAY3JlYXRlQ29udHJvbChkZXNjcmlwdG9yKVxuICAgICAgICBcbiAgICAgICAgaWYgbm90IGNvbnRyb2w/XG4gICAgICAgICAgICB0eXBlID0gT2JqZWN0LmRlZXBDb3B5KEBjdXN0b21UeXBlc1tkZXNjcmlwdG9yLnR5cGVdKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBAZXhlY3V0ZVBsYWNlaG9sZGVyRm9ybXVsYXModHlwZSwgZGVzY3JpcHRvci5pZCwgZGVzY3JpcHRvci5wYXJhbXMpXG4gICAgICAgXG4gICAgICAgICAgICB0eXBlTmFtZSA9IHR5cGUudHlwZVxuICAgICAgICAgICAgY3VzdG9tRmllbGRzID0gdHlwZS5jdXN0b21GaWVsZHNcbiAgICAgICAgICAgIGJpbmRpbmdzID0gdHlwZS5iaW5kaW5nc1xuICAgICAgICAgICAgZm9ybXVsYXMgPSB0eXBlLmZvcm11bGFzXG4gICAgICAgICAgICBhY3Rpb25zID0gdHlwZS5hY3Rpb25zXG4gICAgICAgICAgICBpZiB0eXBlLnN0eWxlP1xuICAgICAgICAgICAgICAgIHR5cGUuc3R5bGVzID0gW3R5cGUuc3R5bGVdXG4gICAgICAgICAgICAgICAgdHlwZS5zdHlsZSA9IG51bGxcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIE9iamVjdC5taXhpbih0eXBlLCBkZXNjcmlwdG9yKVxuICAgICAgICAgICAgaWYgY3VzdG9tRmllbGRzPyB0aGVuIE9iamVjdC5taXhpbih0eXBlLmN1c3RvbUZpZWxkcywgY3VzdG9tRmllbGRzKVxuICAgICAgICAgICAgaWYgYmluZGluZ3M/IGFuZCBiaW5kaW5ncyAhPSB0eXBlLmJpbmRpbmdzIHRoZW4gdHlwZS5iaW5kaW5ncyA9IHR5cGUuYmluZGluZ3MuY29uY2F0KGJpbmRpbmdzKVxuICAgICAgICAgICAgaWYgZm9ybXVsYXM/IGFuZCBmb3JtdWxhcyAhPSB0eXBlLmZvcm11bGFzIHRoZW4gdHlwZS5mb3JtdWxhcyA9IHR5cGUuZm9ybXVsYXMuY29uY2F0KGZvcm11bGFzKVxuICAgICAgICAgICAgaWYgYWN0aW9ucz8gYW5kIGFjdGlvbnMgIT0gdHlwZS5hY3Rpb25zIHRoZW4gdHlwZS5hY3Rpb25zID0gYWN0aW9ucy5jb25jYXQodHlwZS5hY3Rpb25zKVxuICAgICAgICAgICAgdHlwZS50eXBlID0gdHlwZU5hbWVcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcmV0dXJuIEBjcmVhdGVDb250cm9sRnJvbURlc2NyaXB0b3IodHlwZSwgcGFyZW50KVxuICAgICAgICBlbHNlIGlmIHBhcmVudD9cbiAgICAgICAgICAgIHBhcmVudC5hZGRPYmplY3QoY29udHJvbClcbiAgICAgICAgICAgIGNvbnRyb2wuaW5kZXggPSBpbmRleFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQuYWRkT2JqZWN0KGNvbnRyb2wpXG4gICAgICAgICBcbiAgICAgICAgY29udHJvbC51aSA9IG5ldyB1aS5Db21wb25lbnRfVUlCZWhhdmlvcigpXG4gICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2wudWkpXG4gICAgICAgIFxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgY29udHJvbC5wYXJhbXMgPSBkZXNjcmlwdG9yLnBhcmFtc1xuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci51cGRhdGVCZWhhdmlvciA9PSBcImNvbnRpbnVvdXNcIlxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVCZWhhdmlvciA9IHVpLlVwZGF0ZUJlaGF2aW9yLkNPTlRJTlVPVVNcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmluaGVyaXRQcm9wZXJ0aWVzXG4gICAgICAgICAgICBjb250cm9sLmluaGVyaXRQcm9wZXJ0aWVzID0geWVzXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb250P1xuICAgICAgICAgICAgY29udHJvbC5mb250ID0gbmV3IEZvbnQoZGVzY3JpcHRvci5mb250Lm5hbWUsIGRlc2NyaXB0b3IuZm9udC5zaXplKVxuICAgICAgICAgICAgY29udHJvbC5mb250LmJvbGQgPSBkZXNjcmlwdG9yLmZvbnQuYm9sZCA/IGNvbnRyb2wuZm9udC5ib2xkXG4gICAgICAgICAgICBjb250cm9sLmZvbnQuaXRhbGljID0gZGVzY3JpcHRvci5mb250Lml0YWxpYyA/IGNvbnRyb2wuZm9udC5pdGFsaWNcbiAgICAgICAgICAgIGNvbnRyb2wuZm9udC5zbWFsbENhcHMgPSBkZXNjcmlwdG9yLmZvbnQuc21hbGxDYXBzID8gY29udHJvbC5mb250LnNtYWxsQ2Fwc1xuICAgICAgICAgICAgY29udHJvbC5mb250LnVuZGVybGluZSA9IGRlc2NyaXB0b3IuZm9udC51bmRlcmxpbmUgPyBjb250cm9sLmZvbnQudW5kZXJsaW5lXG4gICAgICAgICAgICBjb250cm9sLmZvbnQuc3RyaWtlVGhyb3VnaCA9IGRlc2NyaXB0b3IuZm9udC5zdHJpa2VUaHJvdWdoID8gY29udHJvbC5mb250LnN0cmlrZVRocm91Z2hcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mb250LmNvbG9yP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5jb2xvciA9IENvbG9yLmZyb21BcnJheShkZXNjcmlwdG9yLmZvbnQuY29sb3IpXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXIgPSBkZXNjcmlwdG9yLmZvbnQuYm9yZGVyID8gbm9cbiAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyU2l6ZSA9IGRlc2NyaXB0b3IuZm9udC5ib3JkZXJTaXplID8gNFxuICAgICAgICAgICAgICAjaWYgZGVzY3JpcHRvci5mb250LmJvcmRlci5jb2xvclxuICAgICAgICAgICAgIyAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5ib3JkZXIuY29sb3IpXG4gICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gbmV3IENvbG9yKDAsIDAsIDApXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQub3V0bGluZT9cbiAgICAgICAgICAgICAgICBjb250cm9sLmZvbnQuYm9yZGVyID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUgPyBub1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuZm9udC5ib3JkZXJTaXplID0gZGVzY3JpcHRvci5mb250Lm91dGxpbmUuc2l6ZSA/IDRcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZvbnQub3V0bGluZS5jb2xvcj9cbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gQ29sb3IuZnJvbUFycmF5KGRlc2NyaXB0b3IuZm9udC5vdXRsaW5lLmNvbG9yKVxuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5mb250LmJvcmRlckNvbG9yID0gbmV3IENvbG9yKDAsIDAsIDApXG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb21wb25lbnRzP1xuICAgICAgICAgICAgZm9yIGMgaW4gZGVzY3JpcHRvci5jb21wb25lbnRzXG4gICAgICAgICAgICAgICAgbSA9IGMubW9kdWxlIHx8IFwiZ3NcIlxuICAgICAgICAgICAgICAgIGNvbXBvbmVudCA9IG5ldyB3aW5kb3dbbV1bYy50eXBlXShjLnBhcmFtcylcbiAgICAgICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb21wb25lbnQsIGMuaWQpXG4gICAgICAgICAgICAgICAgY29udHJvbFtjLmlkXSA9IGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICNjb21wb25lbnQuc2V0dXA/KClcbiAgICAgICAgIFxuICAgICAgICBjb250cm9sLmZvY3VzYWJsZSA9IGRlc2NyaXB0b3IuZm9jdXNhYmxlID8gY29udHJvbC5mb2N1c2FibGUgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IubmV4dEtleU9iamVjdFxuICAgICAgICAgICAgY29udHJvbC51aS5uZXh0S2V5T2JqZWN0SWQgPSBkZXNjcmlwdG9yLm5leHRLZXlPYmplY3RcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaW5pdGlhbEZvY3VzXG4gICAgICAgICAgICBjb250cm9sLnVpLmZvY3VzKClcbiAgICAgICAgICAgIFxuICAgICAgICBhY3Rpb25zID0gT2JqZWN0LmRlZXBDb3B5KGlmIGRlc2NyaXB0b3IuYWN0aW9uPyB0aGVuIFtkZXNjcmlwdG9yLmFjdGlvbl0gZWxzZSBkZXNjcmlwdG9yLmFjdGlvbnMpIFxuICAgICAgICBpZiBhY3Rpb25zP1xuICAgICAgICAgICAgZm9yIGFjdGlvbiBpbiBhY3Rpb25zXG4gICAgICAgICAgICAgICAgaWYgYWN0aW9uP1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb24uZXZlbnQgPSBhY3Rpb24uZXZlbnQgPyBcIm9uQWNjZXB0XCJcbiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGFjdGlvbi50YXJnZXQ/XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBpZiBAY29udHJvbGxlcnM/IHRoZW4gQGNvbnRyb2xsZXJzW2Rlc2NyaXB0b3IudGFyZ2V0XSBlbHNlIGNvbnRyb2xsZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbi50YXJnZXQgPSB0YXJnZXQgfHwgU2NlbmVNYW5hZ2VyLnNjZW5lLmJlaGF2aW9yXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnRyb2wuYWN0aW9ucyA9IGFjdGlvbnNcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYoIWNvbnRyb2wuZmluZENvbXBvbmVudEJ5SWQoXCJhY3Rpb25IYW5kbGVyXCIpKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuaW5zZXJ0Q29tcG9uZW50KG5ldyB1aS5Db21wb25lbnRfQWN0aW9uSGFuZGxlcigpLCAxLCBcImFjdGlvbkhhbmRsZXJcIilcbiAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuaWQ/XG4gICAgICAgICAgICBjb250cm9sLmlkID0gZGVzY3JpcHRvci5pZFxuICAgICAgICAgICAgZ3MuT2JqZWN0TWFuYWdlci5jdXJyZW50LnNldE9iamVjdEJ5SWQoY29udHJvbCwgY29udHJvbC5pZClcbiAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yXG4gICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdCA9IG5ldyBSZWN0KClcbiAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LnNldCgwLCAwLCAwLCAwKVxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lP1xuICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5mcmFtZVswXT8ubGVuZ3RoP1xuICAgICAgICAgICAgICAgIGNvbnRyb2wubGF5b3V0UmVjdC54ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzBdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gMFxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC54ID0gKGRlc2NyaXB0b3IuZnJhbWVbMF0gPyBjb250cm9sLmRzdFJlY3QueClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWVbMV0/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3QueSA9IEBjcmVhdGVDYWxjRnVuY3Rpb24oZGVzY3JpcHRvci5mcmFtZVsxXSlcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IDBcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QueSA9IChkZXNjcmlwdG9yLmZyYW1lWzFdID8gY29udHJvbC5kc3RSZWN0LnkpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiBkZXNjcmlwdG9yLmZyYW1lWzJdPy5sZW5ndGg/XG4gICAgICAgICAgICAgICAgY29udHJvbC5sYXlvdXRSZWN0LndpZHRoID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzJdKVxuICAgICAgICAgICAgICAgIGNvbnRyb2wuZHN0UmVjdC53aWR0aCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3Qud2lkdGggPSAoZGVzY3JpcHRvci5mcmFtZVsyXSA/IGNvbnRyb2wuZHN0UmVjdC53aWR0aClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIGRlc2NyaXB0b3IuZnJhbWVbM10/Lmxlbmd0aD9cbiAgICAgICAgICAgICAgICBjb250cm9sLmxheW91dFJlY3QuaGVpZ2h0ID0gQGNyZWF0ZUNhbGNGdW5jdGlvbihkZXNjcmlwdG9yLmZyYW1lWzNdKSAjcGFyc2VJbnQoZGVzY3JpcHRvci5mcmFtZVszXS5zcGxpdChcIiVcIilbMF0pXG4gICAgICAgICAgICAgICAgY29udHJvbC5kc3RSZWN0LmhlaWdodCA9IDFcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250cm9sLmRzdFJlY3QuaGVpZ2h0ID0gKGRlc2NyaXB0b3IuZnJhbWVbM10gPyBjb250cm9sLmRzdFJlY3QuaGVpZ2h0KVxuICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zaXplVG9QYXJlbnQ/XG4gICAgICAgICAgICBjb250cm9sLnNpemVUb1BhcmVudCA9IGRlc2NyaXB0b3Iuc2l6ZVRvUGFyZW50XG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5ibGVuZE1vZGU/XG4gICAgICAgICAgICBjb250cm9sLmJsZW5kTW9kZSA9IEBibGVuZE1vZGVzW2Rlc2NyaXB0b3IuYmxlbmRNb2RlXVxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuYW5jaG9yP1xuICAgICAgICAgICAgY29udHJvbC5hbmNob3Iuc2V0KGRlc2NyaXB0b3IuYW5jaG9yWzBdLCBkZXNjcmlwdG9yLmFuY2hvclsxXSlcbiAgICAgICAgXG5cbiAgICAgICAgY29udHJvbC5vcGFjaXR5ID0gZGVzY3JpcHRvci5vcGFjaXR5ID8gMjU1ICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLm1pbmltdW1TaXplP1xuICAgICAgICAgICAgY29udHJvbC5taW5pbXVtU2l6ZSA9IHsgd2lkdGg6IGRlc2NyaXB0b3IubWluaW11bVNpemVbMF0sIGhlaWdodDogZGVzY3JpcHRvci5taW5pbXVtU2l6ZVsxXSB9XG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5yZXNpemFibGU/IHRoZW4gY29udHJvbC5yZXNpemFibGUgPSBkZXNjcmlwdG9yLnJlc2l6YWJsZVxuICAgICAgICBpZiBkZXNjcmlwdG9yLnNjcm9sbGFibGU/IHRoZW4gY29udHJvbC5zY3JvbGxhYmxlID0gZGVzY3JpcHRvci5zY3JvbGxhYmxlIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLmZpeGVkU2l6ZT8gdGhlbiBjb250cm9sLmZpeGVkU2l6ZSA9IGRlc2NyaXB0b3IuZml4ZWRTaXplXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuZHJhZ2dhYmxlP1xuICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUgPSBkZXNjcmlwdG9yLmRyYWdnYWJsZVxuICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUuc3RlcCA9IDBcbiAgICAgICAgICAgIGlmIGNvbnRyb2wuZHJhZ2dhYmxlLnJlY3Q/XG4gICAgICAgICAgICAgICAgY29udHJvbC5kcmFnZ2FibGUucmVjdCA9IFJlY3QuZnJvbUFycmF5KGNvbnRyb2wuZHJhZ2dhYmxlLnJlY3QpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0RyYWdnYWJsZSgpKVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5iaW5kaW5ncz9cbiAgICAgICAgICAgIGNvbnRyb2wuYmluZGluZ3MgPSBkZXNjcmlwdG9yLmJpbmRpbmdzXG4gICAgICAgICAgICBjb250cm9sLmluc2VydENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0JpbmRpbmdIYW5kbGVyKCksIDApXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5mb3JtdWxhcz9cbiAgICAgICAgICAgIGNvbnRyb2wuZm9ybXVsYXMgPSBkZXNjcmlwdG9yLmZvcm11bGFzXG4gICAgICAgICAgICBjb250cm9sLmluc2VydENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0Zvcm11bGFIYW5kbGVyKCksIDApXG4gICAgICAgICAgICBcbiAgICAgICAgY29udHJvbC5kYXRhRmllbGQgPSBkZXNjcmlwdG9yLmRhdGFGaWVsZFxuICAgICAgICBjb250cm9sLmVuYWJsZWQgPSBkZXNjcmlwdG9yLmVuYWJsZWQgPyB5ZXNcbiAgICAgICAgaWYgZGVzY3JpcHRvci5zZWxlY3RhYmxlPyB0aGVuIGNvbnRyb2wuc2VsZWN0YWJsZSA9IGRlc2NyaXB0b3Iuc2VsZWN0YWJsZVxuICAgICAgICBpZiBkZXNjcmlwdG9yLmdyb3VwPyBcbiAgICAgICAgICAgIGNvbnRyb2wuZ3JvdXAgPSBkZXNjcmlwdG9yLmdyb3VwXG4gICAgICAgICAgICBncy5PYmplY3RNYW5hZ2VyLmN1cnJlbnQuYWRkVG9Hcm91cChjb250cm9sLCBjb250cm9sLmdyb3VwKVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jdXN0b21GaWVsZHM/XG4gICAgICAgICAgICBjb250cm9sLmN1c3RvbUZpZWxkcyA9IE9iamVjdC5kZWVwQ29weShkZXNjcmlwdG9yLmN1c3RvbUZpZWxkcylcbiAgICAgICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLm1hcmdpbj9cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLmxlZnQgPSBkZXNjcmlwdG9yLm1hcmdpblswXVxuICAgICAgICAgICAgY29udHJvbC5tYXJnaW4udG9wID0gZGVzY3JpcHRvci5tYXJnaW5bMV1cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLnJpZ2h0ID0gZGVzY3JpcHRvci5tYXJnaW5bMl1cbiAgICAgICAgICAgIGNvbnRyb2wubWFyZ2luLmJvdHRvbSA9IGRlc2NyaXB0b3IubWFyZ2luWzNdXG4gICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5wYWRkaW5nP1xuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLmxlZnQgPSBkZXNjcmlwdG9yLnBhZGRpbmdbMF1cbiAgICAgICAgICAgIGNvbnRyb2wucGFkZGluZy50b3AgPSBkZXNjcmlwdG9yLnBhZGRpbmdbMV1cbiAgICAgICAgICAgIGNvbnRyb2wucGFkZGluZy5yaWdodCA9IGRlc2NyaXB0b3IucGFkZGluZ1syXVxuICAgICAgICAgICAgY29udHJvbC5wYWRkaW5nLmJvdHRvbSA9IGRlc2NyaXB0b3IucGFkZGluZ1szXVxuICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IuYWxpZ25tZW50P1xuICAgICAgICAgICAgY29udHJvbC5hbGlnbm1lbnQgPSBAYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudF1cbiAgICAgICAgICAgIFxuICAgICAgICBjb250cm9sLmFsaWdubWVudFkgPSBAYWxpZ25tZW50c1tkZXNjcmlwdG9yLmFsaWdubWVudFkgfHwgMF1cbiAgICAgICAgY29udHJvbC5hbGlnbm1lbnRYID0gQGFsaWdubWVudHNbZGVzY3JpcHRvci5hbGlnbm1lbnRYIHx8IDBdXG4gICAgICAgIGNvbnRyb2wuekluZGV4ID0gZGVzY3JpcHRvci56SW5kZXggfHwgMFxuICAgICAgICBjb250cm9sLm9yZGVyID0gZGVzY3JpcHRvci5vcmRlciB8fCAwXG4gICAgICAgIGNvbnRyb2wuY2hhaW5PcmRlciA9IChkZXNjcmlwdG9yLmNoYWluT3JkZXIgPyBkZXNjcmlwdG9yLnpPcmRlcikgKyAocGFyZW50Py5jaGFpbk9yZGVyIHx8IDApXG4gICAgICAgIGlmIGRlc2NyaXB0b3Iuem9vbT9cbiAgICAgICAgICAgIGNvbnRyb2wuem9vbSA9IHg6IGRlc2NyaXB0b3Iuem9vbVswXSAvIDEwMCwgeTogZGVzY3JpcHRvci56b29tWzFdIC8gMTAwXG4gICAgICAgICNjb250cm9sLmRhdGFGaWVsZHMgPSBkYXRhRmllbGRzXG4gICAgICAgICNjb250cm9sLmNvbnRyb2xsZXJzID0gQGNvbnRyb2xsZXJzXG4gICAgICAgICNjb250cm9sLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyXG4gICAgICAgIFxuICAgICAgICBpZiBkZXNjcmlwdG9yLnZpc2libGU/XG4gICAgICAgICAgICBjb250cm9sLnZpc2libGUgPSBkZXNjcmlwdG9yLnZpc2libGVcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jbGlwUmVjdFxuICAgICAgICAgICAgY29udHJvbC5jbGlwUmVjdCA9IG5ldyBSZWN0KGNvbnRyb2wuZHN0UmVjdC54LCBjb250cm9sLmRzdFJlY3QueSwgY29udHJvbC5kc3RSZWN0LndpZHRoLCBjb250cm9sLmRzdFJlY3QuaGVpZ2h0KVxuXG4gICAgICAgIGlmIGRlc2NyaXB0b3Iuc3R5bGVzP1xuICAgICAgICAgICAgQGFkZENvbnRyb2xTdHlsZXMoY29udHJvbCwgZGVzY3JpcHRvci5zdHlsZXMpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgIGlmIGRlc2NyaXB0b3IudGVtcGxhdGU/XG4gICAgICAgICAgICBjb250cm9sLmJlaGF2aW9yLm1hbmFnZW1lbnRNb2RlID0gdWkuTGF5b3V0TWFuYWdlbWVudE1vZGUuZnJvbVN0cmluZyhkZXNjcmlwdG9yLm1hbmFnZW1lbnRNb2RlKVxuICAgICAgICAgICAgZGF0YSA9IHVpLkNvbXBvbmVudF9Gb3JtdWxhSGFuZGxlci5maWVsZFZhbHVlKGNvbnRyb2wsIGNvbnRyb2wuZGF0YUZpZWxkKSAjY29udHJvbC5kYXRhRmllbGRzW2NvbnRyb2wuZGF0YUZpZWxkXVxuICAgICAgICAgICAgaXNOdW1iZXIgPSB0eXBlb2YgZGF0YSA9PSBcIm51bWJlclwiXG4gICAgICAgICAgICBpZiBkYXRhP1xuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4uKGRhdGEubGVuZ3RoID8gZGF0YSldXG4gICAgICAgICAgICAgICAgICAgIGlmIGRhdGFbaV0/IG9yIGlzTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IHllc1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGVzY3JpcHRvci5kYXRhRmlsdGVyPyBhbmQgbm90IGlzTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSB1aS5Db21wb25lbnRfSGFuZGxlci5jaGVja0NvbmRpdGlvbihkYXRhW2ldLCBkZXNjcmlwdG9yLmRhdGFGaWx0ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiB2YWxpZCBvciBpc051bWJlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gQGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLnRlbXBsYXRlLCBjb250cm9sLCBpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICNjaGlsZC5kYXRhRmllbGRzID0gY29udHJvbC5kYXRhRmllbGRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZGF0YVtpXT8uZHN0UmVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5kc3RSZWN0ID0gdWkuVUlFbGVtZW50UmVjdGFuZ2xlLmZyb21SZWN0KGNoaWxkLCBkYXRhW2ldLmRzdFJlY3QpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vdCBjaGlsZC5jbGlwUmVjdD8pIGFuZCBjb250cm9sLmNsaXBSZWN0P1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5jbGlwUmVjdCA9IGNvbnRyb2wuY2xpcFJlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY2hpbGQucGFyZW50ID0gY29udHJvbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuYWRkT2JqZWN0KGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmluZGV4ID0gaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLm9yZGVyID0gKGRhdGEubGVuZ3RoID8gZGF0YSkgLSBpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5jb250cm9scy5wdXNoKGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb250cm9scyBhbmQgZGVzY3JpcHRvci5jb250cm9scy5leGVjXG4gICAgICAgICAgICBjb250cm9scyA9IHVpLkNvbXBvbmVudF9Gb3JtdWxhSGFuZGxlci5maWVsZFZhbHVlKGRlc2NyaXB0b3IsIGRlc2NyaXB0b3IuY29udHJvbHMpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRyb2xzID0gZGVzY3JpcHRvci5jb250cm9sc1xuICAgICAgICAgICAgXG4gICAgICAgIGlmIGNvbnRyb2xzP1xuICAgICAgICAgICAgZm9yIGl0ZW0sIGkgaW4gY29udHJvbHNcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wgPSBAX2NyZWF0ZUZyb21EZXNjcmlwdG9yKGl0ZW0sIGNvbnRyb2wsIGkpXG4gICAgICAgICAgICAgICAgaWYgKG5vdCBjaGlsZENvbnRyb2wuY2xpcFJlY3Q/KSBhbmQgY29udHJvbC5jbGlwUmVjdD9cbiAgICAgICAgICAgICAgICAgICAgY2hpbGRDb250cm9sLmNsaXBSZWN0ID0gY29udHJvbC5jbGlwUmVjdFxuICAgICAgICAgICAgICAgIGNoaWxkQ29udHJvbC5pbmRleCA9IGlcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wub3JpZ2luLnggPSBjb250cm9sLm9yaWdpbi54ICsgY29udHJvbC5kc3RSZWN0LnhcbiAgICAgICAgICAgICAgICBjaGlsZENvbnRyb2wub3JpZ2luLnkgPSBjb250cm9sLm9yaWdpbi55ICsgY29udHJvbC5kc3RSZWN0LnlcbiAgICAgICAgICAgICAgICAjY2hpbGRDb250cm9sLnBhcmVudCA9IGNvbnRyb2xcbiAgICAgICAgICAgICAgICBjb250cm9sLmFkZE9iamVjdChjaGlsZENvbnRyb2wpXG4gICAgICAgICAgICAgICAgY29udHJvbC5jb250cm9scy5wdXNoKGNoaWxkQ29udHJvbClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgY29udHJvbC5zdHlsZXMgYW5kIGNvbnRyb2wucGFyZW50c0J5U3R5bGVcbiAgICAgICAgICAgICNmb3Igc3R5bGUgaW4gY29udHJvbC5zdHlsZXNcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50ID0gY29udHJvbC5wYXJlbnRcbiAgICAgICAgICAgIHdoaWxlIHBhcmVudFxuICAgICAgICAgICAgICAgIGlmIHBhcmVudC5zdHlsZXNcbiAgICAgICAgICAgICAgICAgICAgZm9yIHN0eWxlIGluIHBhcmVudC5zdHlsZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICFjb250cm9sLnBhcmVudHNCeVN0eWxlW3N0eWxlLmlkXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdLnB1c2gocGFyZW50KVxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICN3aGlsZSBwYXJlbnRcbiAgICAgICAgICAgICAgICAgICAgI2lmIHBhcmVudC5jb250cm9sc0J5U3R5bGVcbiAgICAgICAgICAgICAgICAgICAgIyAgICBpZighcGFyZW50LmNvbnRyb2xzQnlTdHlsZVtzdHlsZS5pZF0pXG4gICAgICAgICAgICAgICAgICAgICMgICAgICAgIHBhcmVudC5jb250cm9sc0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICAgIyAgICBwYXJlbnQuY29udHJvbHNCeVN0eWxlW3N0eWxlLmlkXS5wdXNoKGNvbnRyb2wpXG4gICAgICAgICAgICAgICAgICAjICBpZiBjb250cm9sLnBhcmVudHNCeVN0eWxlXG4gICAgICAgICAgICAgICAgICAjICAgICAgaWYgIWNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdXG4gICAgICAgICAgICAgICAgICAjICAgICAgICAgIGNvbnRyb2wucGFyZW50c0J5U3R5bGVbc3R5bGUuaWRdID0gW11cbiAgICAgICAgICAgICAgICAgICMgICAgICBjb250cm9sLnBhcmVudHNCeVN0eWxlW3N0eWxlLmlkXS5wdXNoKHBhcmVudClcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5hbmltYXRpb25zP1xuICAgICAgICAgICAgY29udHJvbC5hbmltYXRpb25zID0gT2JqZWN0LmRlZXBDb3B5KGRlc2NyaXB0b3IuYW5pbWF0aW9ucylcbiAgICAgICAgICAgIGNvbnRyb2wuYW5pbWF0aW9uRXhlY3V0b3IgPSBuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkV4ZWN1dG9yKClcbiAgICAgICAgICAgIGNvbnRyb2wuYWRkQ29tcG9uZW50KGNvbnRyb2wuYW5pbWF0aW9uRXhlY3V0b3IpXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChuZXcgdWkuQ29tcG9uZW50X0FuaW1hdGlvbkhhbmRsZXIoKSlcbiAgICAgICAgIFxuICAgICAgICBjb250cm9sLnVpLnVwZGF0ZVN0eWxlKClcbiAgICAgICAgY29udHJvbC5zZXR1cCgpXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGFuIFVJIG9iamVjdCBmcm9tIGEgc3BlY2lmaWVkIFVJIGRlc2NyaXB0b3IuXG4gICAgKlxuICAgICogQG1ldGhvZCBfY3JlYXRlRnJvbURlc2NyaXB0b3JcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIC0gVGhlIFVJIG9iamVjdCBkZXNjcmlwdG9yLlxuICAgICogQHBhcmFtIHtncy5PYmplY3RfVUlFbGVtZW50fSBwYXJlbnQgLSBUaGUgVUkgcGFyZW50IG9iamVjdC4gKEEgbGF5b3V0IGZvciBleGFtcGxlKS5cbiAgICAqIEByZXR1cm4ge2dzLk9iamVjdF9VSUVsZW1lbnR9IFRoZSBjcmVhdGVkIFVJIG9iamVjdC5cbiAgICAqIEBwcm90ZWN0ZWQgXG4gICAgIyMjICAgXG4gICAgX2NyZWF0ZUZyb21EZXNjcmlwdG9yOiAoZGVzY3JpcHRvciwgcGFyZW50LCBpbmRleCkgLT4gICAgIFxuICAgICAgICBjb250cm9sID0gQGNyZWF0ZUNvbnRyb2xGcm9tRGVzY3JpcHRvcihkZXNjcmlwdG9yLCBwYXJlbnQsIGluZGV4KVxuICAgICAgICBcbiAgICAgICAgaWYgZGVzY3JpcHRvci5jb250cm9sbGVyP1xuICAgICAgICAgICAgY29udHJvbGxlciA9IEBjb250cm9sbGVyc1tkZXNjcmlwdG9yLmNvbnRyb2xsZXJdXG4gICAgICAgICAgICBjb250cm9sLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyXG4gICAgICAgICAgICBjb250cm9sLmFkZENvbXBvbmVudChjb250cm9sbGVyKVxuICAgICAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gY29udHJvbFxuICAgICAgICBcbiAgICBjcmVhdGVMYXlvdXRGcm9tRGVzY3JpcHRvcjogKGRlc2NyaXB0b3IsIHBhcmVudCwgaW5kZXgpIC0+XG4gICAgICAgIEBfY3JlYXRlRnJvbURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcGFyZW50LCBpbmRleClcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIFxuR3JhcGhpY3Mud2lkdGggPSAkUEFSQU1TLnJlc29sdXRpb24ud2lkdGhcbkdyYXBoaWNzLmhlaWdodCA9ICRQQVJBTVMucmVzb2x1dGlvbi5oZWlnaHRcbnVpLlVpRmFjdG9yeSA9IG5ldyBVSU1hbmFnZXIoKVxudWkuVUlNYW5hZ2VyID0gdWkuVWlGYWN0b3J5Il19\n//# sourceURL=UIManager_103.js"
    },
    "summary": [
        "name",
        "type",
        "order"
    ]
}

Commits for Nextrek/s2s/data/4216707AK784EA4859S86BBE1FCA7990F36B.json

Diff revisions: vs.
Revision Author Commited Message
1086 Diff Diff ASorrentino picture ASorrentino Fri 11 May, 2018 21:50:37 +0000
1084 MOliva picture MOliva Fri 11 May, 2018 12:41:55 +0000