iwmlib/pixi/all.js

13966 lines
1.6 MiB

(function () {
'use strict';
/**
* Class that represents a PixiJS Theme.
*
* @example
* // Create the theme
* const yellow = new Theme({
* fill: 0xfecd2d,
* fillActive: 0xfe9727,
* strokeActive: 0xfecd2d,
* strokeActiveWidth: 4,
* textStyle: {
* fill: 0x5ec7f8
* },
* textStyleActive: {
* fill: 0x5954d3
* },
* textStyleLarge: {
* fontSize: 36
* }
* })
*
* // Create the app and apply the new theme to it
* const app = new PIXIApp({
* view: canvas,
* width: 450,
* height: 150,
* theme: yellow
* }).setup().run()
*
* @class
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest}
*/
class Theme {
/**
* Creates an instance of a Theme.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the theme.
* @param {number} [opts.margin=10] - The outer spacing (distance to other objects) from the border.
* @param {number} [opts.padding=10] - The inner spacing (distance from icon and/or label) to the border.
* @param {number} [opts.radius=4] - The radius used when drawing a rounded rectangle.
* @param {number} [opts.fast=0.25] - The duration of time when it has to be fast.
* @param {number} [opts.normal=0.5] - The duration of time when it has to be normal.
* @param {number} [opts.slow=1] - The duration of time when it has to be slow.
* @param {number} [opts.primaryColor=0x5ec7f8] - The primary color of the theme.
* @param {number} [opts.color1=0x282828] - The first color of the theme. For example used for the background.
* @param {number} [opts.color2=0xf6f6f6] - The second color of the theme. For example used for the border.
* @param {number} [opts.fill=color1] - The color of the background as a hex value.
* @param {number} [opts.fillAlpha=1] - The alpha value of the background.
* @param {number} [opts.fillActive=color1] - The color of the background when activated.
* @param {number} [opts.fillActiveAlpha=1] - The alpha value of the background when activated.
* @param {number} [opts.stroke=color2] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=0.6] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=1] - The alpha value of the border.
* @param {number} [opts.strokeActive=color2] - The color of the border when activated.
* @param {number} [opts.strokeActiveWidth=0.6] - The width of the border in pixel when activated.
* @param {number} [opts.strokeActiveAlpha=1] - The alpha value of the border when activated.
* @param {number} [opts.iconColor=color2] - The color of the icon (set by the tint property) as a hex value.
* @param {number} [opts.iconColorActive=colorPrimary] - The color of the icon when activated.
* @param {number} [opts.background=color1] - The color of a background for a component (e.g. at the Modal class).
* @param {object} [opts.textStyle={}] - A textstyle object for the styling of text. See PIXI.TextStyle
* for possible options. Default object:
* @param {string} [opts.textStyle.fontFamily="Avenir Next", "Open Sans", "Segoe UI", ...] - The font family.
* @param {string} [opts.textStyle.fontWeight=400] - The font weight.
* @param {number} [opts.textStyle.fontSize=16] - The font size.
* @param {number} [opts.textStyle.fill=color2] - The fill color.
* @param {number} [opts.textStyle.stroke=color1] - The stroke color.
* @param {number} [opts.textStyle.strokeThickness=0] - The thickness of the stroke.
* @param {number} [opts.textStyle.miterLimit=1] - The meter limit.
* @param {string} [opts.textStyle.lineJoin=round] - The line join.
* @param {object} [opts.textStyleActive=textStyle + {fill: primaryColor}] - A textstyle object which is used
* for actived text.
* @param {object} [opts.textStyleSmall=textStyle + {fontSize: -= 3}] - A textstyle object which is used for
* small text.
* @param {object} [opts.textStyleSmallActive=textStyleSmall + {fill: primaryColor}] - A textstyle object which
* is used for small actived text.
* @param {object} [opts.textStyleLarge=textStyle + {fontSize: += 3}] - A textstyle object which is used for
* large text.
* @param {object} [opts.textStyleLargeActive=textStyleLarge + {fill: primaryColor}] - A textstyle object which
* is used for large actived text.
*/
constructor(opts = {}) {
const colorPrimary = opts.primaryColor != null ? opts.primaryColor : 0x5ec7f8; // blue
const color1 = opts.color1 != null ? opts.color1 : 0x282828; // black
const color2 = opts.color2 != null ? opts.color2 : 0xf6f6f6; // white
this.opts = Object.assign({}, {
margin: 12,
padding: 12,
radius: 4,
fast: .25,
normal: .5,
slow: 1,
primaryColor: colorPrimary,
color1: color1,
color2: color2,
fill: color1,
fillAlpha: 1,
fillActive: color1,
fillActiveAlpha: 1,
stroke: color2,
strokeWidth: .6,
strokeAlpha: 1,
strokeActive: color2,
strokeActiveWidth: .6,
strokeActiveAlpha: 1,
iconColor: color2,
iconColorActive: colorPrimary,
background: color1
}, opts);
// Set textStyle and variants
this.opts.textStyle = Object.assign({}, {
fontFamily: '"Avenir Next", "Open Sans", "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, system-ui, BlinkMacSystemFont, Arial, sans-serif !default',
fontWeight: '500',
fontSize: 18,
fill: color2,
stroke: color1,
strokeThickness: 0,
miterLimit: 1,
lineJoin: 'round'
}, this.opts.textStyle);
this.opts.textStyleSmall = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize - 3}, this.opts.textStyleSmall);
this.opts.textStyleLarge = Object.assign({}, this.opts.textStyle, {fontSize: this.opts.textStyle.fontSize + 3}, this.opts.textStyleLarge);
this.opts.textStyleActive = Object.assign({}, this.opts.textStyle, {fill: this.opts.primaryColor}, this.opts.textStyleActive);
this.opts.textStyleSmallActive = Object.assign({}, this.opts.textStyleSmall, {fill: this.opts.primaryColor}, this.opts.textStyleSmallActive);
this.opts.textStyleLargeActive = Object.assign({}, this.opts.textStyleLarge, {fill: this.opts.primaryColor}, this.opts.textStyleLargeActive);
Object.assign(this, this.opts);
}
/**
* Factory function
*
* @static
* @param {string} theme=dark - The name of the theme to load.
* @return {Theme} Returns a newly created Theme object.
*/
static fromString(theme) {
if (theme && typeof theme === 'object') {
return theme
}
switch (theme) {
case 'light':
return new ThemeLight()
case 'red':
return new ThemeRed()
default:
return new ThemeDark()
}
}
}
/**
* Class that represents a PixiJS ThemeDark.
*
* @example
* // Create the app with a new dark theme
* const app = new PIXIApp({
* view: canvas,
* width: 450,
* height: 150,
* theme: new ThemeDark()
* }).setup().run()
*
* @class
* @extends Theme
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest}
*/
class ThemeDark extends Theme {
}
/**
* Class that represents a PixiJS ThemeLight.
* The color1 is set to 0xf6f6f6, color2 to 0x282828.
*
* @example
* // Create the app with a new light theme
* const app = new PIXIApp({
* view: canvas,
* width: 450,
* height: 150,
* theme: new ThemeLight()
* }).setup().run()
*
* @class
* @extends Theme
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest}
*/
class ThemeLight extends Theme {
/**
* Creates an instance of a ThemeLight.
*
* @constructor
*/
constructor() {
super({color1: 0xf6f6f6, color2: 0x282828});
}
}
/**
* Class that represents a PixiJS ThemeRed.
* The primaryColor is set to 0xd92f31.
*
* @example
* // Create the app with a new red theme
* const app = new PIXIApp({
* view: canvas,
* width: 450,
* height: 150,
* theme: new ThemeRed()
* }).setup().run()
*
* @class
* @extends Theme
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/theme.html|DocTest}
*/
class ThemeRed extends Theme {
/**
* Creates an instance of a ThemeRed.
*
* @constructor
*/
constructor() {
super({primaryColor: 0xd92f31});
}
}
/**
* Class that represents a PixiJS Progress.
*
* @example
* // Create the progress
* const progress = new Progress({
* app: app
* })
*
* // Add the progress to a DisplayObject
* app.scene.addChild(progress)
*
* @class
* @extends PIXI.Container
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/progress.html|DocTest}
*/
class Progress extends PIXI.Container {
/**
* Creates an instance of a Progress.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the progress.
* @param {number} [opts.id=auto generated] - The id of the progress.
* @param {PIXIApp} [opts.app=window.app] - The app where the progress belongs to.
* @param {number} [opts.width] - The width of the progress bar. When not set, the width is the size of the app
* minus 2 * opts.margin.
* @param {number} [opts.height=2] - The height of the progress bar.
* @param {string|Theme} [opts.theme=dark] - The theme to use for this progress. Possible values are dark, light, red
* or a Theme object.
* @param {number} [opts.margin=100] - The outer spacing to the edges of the app.
* @param {number} [opts.padding=0] - The inner spacing (distance from icon and/or label) to the border.
* @param {number} [opts.fill=Theme.fill] - The color of the progress background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
* @param {number} [opts.fillActive=Theme.primaryColor] - The color of the progress background when activated.
* @param {number} [opts.fillActiveAlpha=Theme.fillActiveAlpha] - The alpha value of the background when activated.
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=0] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.strokeActive=Theme.strokeActive] - The color of the border when activated.
* @param {number} [opts.strokeActiveWidth=0] - The width of the border in pixel when activated.
* @param {number} [opts.strokeActiveAlpha=Theme.strokeActiveAlpha] - The alpha value of the border when activated.
* @param {boolean} [opts.background=false] - The alpha value of the border when activated.
* @param {number} [opts.backgroundFill=Theme.background] - A textstyle object for the styling of the label. See PIXI.TextStyle
* for possible options.
* @param {number} [opts.backgroundFillAlpha=1] - A textstyle object for the styling of the label when the
* progress is activated. See PIXI.TextStyle for possible options.
* @param {number} [opts.radius=Theme.radius] - The radius of the four corners of the progress (which is a rounded rectangle).
* @param {boolean} [opts.destroyOnComplete=true] - Should the progress bar destroy itself after reaching 100 %?
* @param {boolean} [opts.visible=true] - Is the progress initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
app: window.app,
width: null,
height: 2,
margin: 100,
padding: 0,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
fillActive: theme.primaryColor,
fillActiveAlpha: theme.fillActiveAlpha,
stroke: theme.stroke,
strokeWidth: 0,
strokeAlpha: theme.strokeAlpha,
strokeActive: theme.strokeActive,
strokeActiveWidth: 0,
strokeActiveAlpha: theme.strokeActiveAlpha,
background: false,
backgroundFill: theme.background,
backgroundFillAlpha: 1,
radius: theme.radius,
destroyOnComplete: true,
visible: true
}, opts);
this.id = this.opts.id;
this.background = null;
this.bar = null;
this.barActive = null;
this.alpha = 0;
this.visible = this.opts.visible;
this._progress = 0;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Progress} A reference to the progress for chaining.
*/
setup() {
// interaction
//-----------------
this.on('added', e => {
this.show();
});
// background
//-----------------
if (this.opts.background) {
const background = new PIXI.Graphics();
this.background = background;
this.addChild(background);
}
// bar
//-----------------
const bar = new PIXI.Graphics();
this.bar = bar;
this.addChild(bar);
const barActive = new PIXI.Graphics();
this.barActive = barActive;
this.bar.addChild(barActive);
return this
}
/**
* Should be called to refresh the layout of the progress. Can be used after resizing.
*
* @return {Progress} A reference to the progress for chaining.
*/
layout() {
const width = this.opts.app.size.width;
const height = this.opts.app.size.height;
// background
//-----------------
if (this.opts.background) {
this.background.clear();
this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha);
this.background.drawRect(0, 0, width, height);
this.background.endFill();
}
this.draw();
return this
}
/**
* Draws the canvas.
*
* @private
* @return {Progress} A reference to the progress for chaining.
*/
draw() {
this.bar.clear();
this.barActive.clear();
this.drawBar();
this.drawBarActive();
return this
}
/**
* Draws the bar.
*
* @private
* @return {Progress} A reference to the progress for chaining.
*/
drawBar() {
const width = this.opts.app.size.width;
const height = this.opts.app.size.height;
this.radius = this.opts.radius;
if ((this.radius * 2) > this.opts.height) {
this.radius = this.opts.height / 2;
}
const wantedWidth = this.opts.width || (width - (2 * this.opts.margin));
const wantedHeight = this.opts.height;
this.bar.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.bar.beginFill(this.opts.fill, this.opts.fillAlpha);
if (this.radius > 1) {
this.bar.drawRoundedRect(0, 0, wantedWidth, wantedHeight, this.radius);
} else {
this.bar.drawRect(0, 0, wantedWidth, wantedHeight);
}
this.bar.endFill();
this.bar.x = width / 2 - this.bar.width / 2;
this.bar.y = height / 2 - this.bar.height / 2;
return this
}
/**
* Draws the active bar.
*
* @private
* @return {Progress} A reference to the progress for chaining.
*/
drawBarActive() {
const wantedWidth = this.bar.width - (2 * this.opts.padding);
const wantedHeight = this.bar.height - (2 * this.opts.padding);
const barActiveWidth = wantedWidth * this._progress / 100;
this.barActive.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha);
this.barActive.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha);
if (barActiveWidth > 0) {
if (this.radius > 1) {
this.barActive.drawRoundedRect(0, 0, barActiveWidth, wantedHeight, this.radius);
} else {
this.barActive.drawRect(0, 0, barActiveWidth, wantedHeight);
}
}
this.barActive.endFill();
this.barActive.x = this.opts.padding;
this.barActive.y = this.opts.padding;
return this
}
/**
* Shows the progress (sets his alpha values to 1).
*
* @return {Progress} A reference to the progress for chaining.
*/
show() {
TweenLite.to(this, this.theme.fast, {alpha: 1});
return this
}
/**
* Hides the progress (sets his alpha values to 1).
*
* @return {Progress} A reference to the progress for chaining.
*/
hide() {
TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false});
return this
}
/**
* Gets or sets the progress. Has to be a number between 0 and 100.
*
* @member {number}
*/
get progress() {
return this._progress
}
set progress(value) {
value = Math.round(value);
if (value < 0) {
value = 0;
}
if (value > 100) {
value = 100;
}
TweenLite.to(this, this.theme.normal, {
_progress: value,
onUpdate: () => this.draw(),
onComplete: () => {
if (value === 100 && this.opts.destroyOnComplete) {
TweenLite.to(this, this.theme.fast, {
alpha: 0,
onComplete: () => this.destroy({children: true})
});
}
}
});
}
}
/**
* Class that represents a PixiJS AbstractPopup.
* The class is used for various other Popup-like classes
* like Popup, Message, Tooltip...
*
* @class
* @abstract
* @extends PIXI.Graphics
* @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics}
*/
class AbstractPopup extends PIXI.Graphics {
/**
* Creates an instance of an AbstractPopup (only for internal use).
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the popup.
* @param {number} [opts.id=auto generated] - The id of the popup.
* @param {number} [opts.x=0] - The x position of the popup. Can be also set after creation with popup.x = 0.
* @param {number} [opts.y=0] - The y position of the popup. Can be also set after creation with popup.y = 0.
* @param {string|Theme} [opts.theme=dark] - The theme to use for this popup. Possible values are dark, light, red
* or a Theme object.
* @param {string|number|PIXI.Text} [opts.header] - The heading inside the popup as a string, a number (will be
* converted to a text) or as a PIXI.Text object.
* @param {string|number|PIXI.DisplayObject} [opts.content] - A text, a number (will be converted to a text) or
* an PIXI.DisplayObject as the content of the popup.
* @param {number} [opts.minWidth=320] - The minimum width of the popup.
* @param {number} [opts.minHeight=130] - The minimum height of the popup.
* @param {number} [opts.padding=Theme.padding] - The inner spacing (distance from header and content) the the border.
* @param {number} [opts.fill=Theme.fill] - The color of the button background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=Theme.strokeWidth] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {object} [opts.headerStyle=Theme.textStyleLarge] - A textstyle object for the styling of the header. See PIXI.TextStyle
* for possible options.
* @param {object} [opts.textStyle=Theme.textStyleSmall] - A textstyle object for the styling of the text. See PIXI.TextStyle
* for possible options.
* @param {number} [opts.radius=Theme.radius] - The radius of the four corners of the popup (which is a rounded rectangle).
* @param {hiddenCallback} [opts.onHidden] - Executed when the popup gets hidden.
* @param {boolean} [opts.visible=true] - Is the popup initially visible (property visible)?
* @param {string} [opts.orientation] - When set to portrait, the popup cannot be displayed in landscape mode. When set
* to landscape, the popup cannot be displayed in portrait mode.
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
x: 0,
y: 0,
header: null, // null or null
content: null, // null or String or PIXI.DisplayObject
minWidth: 320,
minHeight: 130,
maxWidth: null,
padding: theme.padding,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
stroke: theme.stroke,
strokeWidth: theme.strokeWidth,
strokeAlpha: theme.strokeAlpha,
headerStyle: theme.textStyleLarge,
textStyle: theme.textStyleSmall,
radius: theme.radius,
onHidden: null,
visible: true,
orientation: null
}, opts);
this.id = this.opts.id;
this.headerStyle = new PIXI.TextStyle(this.opts.headerStyle);
this.textStyle = new PIXI.TextStyle(this.opts.textStyle);
if (this.opts.maxWidth) {
this.headerStyle.wordWrap = true;
this.headerStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding);
this.textStyle.wordWrap = true;
this.textStyle.wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding);
}
this.alpha = 0;
this.visible = this.opts.visible;
this._header = null;
this._content = null;
// position
this.x = this.opts.x;
this.y = this.opts.y;
// padding
this.innerPadding = this.opts.padding * 1.5;
// interaction
//-----------------
this.interactive = true;
this.on('added', e => {
this.show();
});
}
/**
* Creates the framework and instantiates everything.
*
* @private
* @return {AbstractPopup} A reference to the popup for chaining.
*/
setup() {
// position
//-----------------
this.sy = this.opts.padding;
// header
//-----------------
if (this.opts.header != null) {
let header = null;
if (this.opts.header instanceof PIXI.Text) {
header = this.opts.header;
} else if (typeof this.opts.header === 'number') {
header = new PIXI.Text(this.opts.header.toString(), this.headerStyle);
} else {
header = new PIXI.Text(this.opts.header, this.headerStyle);
}
header.x = this.opts.padding;
header.y = this.sy;
this.addChild(header);
this.sy += header.height;
this._header = header;
}
if (this.opts.header && this.opts.content) {
this.sy += this.innerPadding;
}
// content
//-----------------
if (this.opts.content != null) {
let content = null;
if (typeof this.opts.content === 'string') {
content = new PIXI.Text(this.opts.content, this.textStyle);
} else if (typeof this.opts.content === 'number') {
content = new PIXI.Text(this.opts.content.toString(), this.textStyle);
} else {
content = this.opts.content;
}
content.x = this.opts.padding;
content.y = this.sy;
this.sy += content.height;
this.addChild(content);
this._content = content;
}
return this
}
/**
* Should be called to refresh the layout of the popup. Can be used after resizing.
*
* @return {AbstractPopup} A reference to the popup for chaining.
*/
layout() {
// wanted width & wanted height
//-----------------
const padding = this.opts.padding;
const size = this.getInnerSize();
const width = size.width + (2 * padding);
const height = size.height + (2 * padding);
this.wantedWidth = Math.max(width, this.opts.minWidth);
this.wantedHeight = Math.max(height, this.opts.minHeight);
if (this.opts.maxWidth) {
this.wantedWidth = Math.min(this.wantedWidth, this.opts.maxWidth);
}
if (this.opts.radius * 2 > this.wantedWidth) {
this.wantedWidth = this.opts.radius * 2;
}
if (this.opts.radius * 2 > this.wantedHeight) {
this.wantedHeight = this.opts.radius * 2;
}
switch (this.opts.orientation) {
case 'portrait':
if (this.wantedWidth > this.wantedHeight) {
this.wantedHeight = this.wantedWidth;
}
break
case 'landscape':
if (this.wantedHeight > this.wantedWidth) {
this.wantedWidth = this.wantedHeight;
}
break
}
this.draw();
return this
}
/**
* Draws the canvas.
*
* @private
* @return {AbstractPopup} A reference to the popup for chaining.
*/
draw() {
const square = Math.round(this.wantedWidth) === Math.round(this.wantedHeight);
const diameter = Math.round(this.opts.radius * 2);
this.clear();
this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.beginFill(this.opts.fill, this.opts.fillAlpha);
if (square && diameter === this.wantedWidth) {
this.drawCircle(this.wantedWidth / 2, this.wantedHeight / 2, this.opts.radius);
} else {
this.drawRoundedRect(0, 0, this.wantedWidth, this.wantedHeight, this.opts.radius);
}
this.endFill();
return this
}
/**
* Calculates the size of the children of the AbstractPopup.
* Cannot use getBounds() because it is not updated when children
* are removed.
*
* @private
* @returns {object} An JavaScript object width the keys width and height.
*/
getInnerSize() {
let width = 0;
let height = 0;
if (this._header) {
width = this._header.width;
height = this._header.height;
}
if (this._header && this._content) {
height += this.innerPadding;
}
if (this._content) {
width = Math.max(width, this._content.width);
height += this._content.height;
}
return {width, height}
}
/**
* Shows the popup (sets his alpha values to 1).
*
* @param {callback} [cb] - Executed when show animation was completed.
* @return {AbstractPopup} A reference to the popup for chaining.
*/
show(cb) {
TweenLite.to(this, this.theme.fast, {
alpha: 1,
onComplete: () => {
if (cb) {
cb.call(this);
}
}
});
return this
}
/**
* Hides the popup (sets his alpha values to 0).
*
* @param {callback} [cb] - Executed when hide animation was completed.
* @return {AbstractPopup} A reference to the popup for chaining.
*/
hide(cb) {
TweenLite.to(this, this.theme.fast, {
alpha: 0,
onComplete: () => {
this.visible = false;
if (cb) {
cb.call(this);
}
}
});
if (this.opts.onHidden) {
this.opts.onHidden.call(this, this);
}
return this
}
/**
* Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive
* a string, a number or a PIXI.Text object.
*
* @member {string|number|PIXI.Text}
*/
get header() {
return this._header
}
set header(value) {
if (this._header) {
this._header.destroy();
}
this.opts.header = value;
this.setup().layout();
}
/**
* Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive
* a string, a number or a PIXI.DisplayObject.
*
* @member {string|number|PIXI.DisplayObject}
*/
get content() {
return this._content
}
set content(value) {
if (this._content) {
this._content.destroy();
}
this.opts.content = value;
this.setup().layout();
}
}
/**
* Class that represents a PixiJS Tooltip.
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* // Add an DisplayObject to the app
* const circle = new PIXI.Graphics()
* circle.beginFill(0x5251a3)
* circle.drawCircle(50, 50, 40)
* app.scene.addChild(circle)
*
* const tooltip = new Tooltip({
* object: circle,
* container: app.scene,
* content: 'Das Gesetz ist der Freund des Schwachen.'
* })
*
* @class
* @extends AbstractPopup
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/tooltip.html|DocTest}
*/
class Tooltip extends AbstractPopup {
/**
* Creates an instance of a Tooltip.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the tooltip.
* @param {number} [opts.minWidth=0] - The minimum width of the tooltip.
* @param {number} [opts.minHeight=0] - The minimum height of the tooltip.
* @param {number} [opts.padding=Theme.padding / 2] - The inner spacing of the tooltip.
* @param {PIXI.DisplayObject} opts.object - The object, where the tooltip should be displayed.
* @param {PIXI.DisplayObject} [opts.container=object] - The container where the tooltip should be attached to.
* @param {number} [opts.offsetLeft=8] - The horizontal shift of the tooltip.
* @param {number} [opts.offsetTop=-8] - The vertical shift of the tooltip.
* @param {number} [opts.delay=0] - A delay, after which the tooltip should be opened.
*/
constructor(opts = {}) {
const theme = Theme.fromString(opts.theme);
opts = Object.assign({}, {
minWidth: 0,
minHeight: 0,
padding: theme.padding / 2,
object: null,
container: null,
offsetLeft: 8,
offsetTop: -8,
delay: 0
}, opts);
opts.container = opts.container || opts.object;
super(opts);
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Tooltip} A reference to the tooltip for chaining.
*/
setup() {
super.setup();
// bind events this
//-----------------
this.interactive = true;
let mouseoverTooltip = false;
this.on('mouseover', e => {
mouseoverTooltip = true;
});
this.on('mouseout', e => {
mouseoverTooltip = false;
if (!mouseoverObject) {
this.hide(() => {
this.opts.container.removeChild(this);
});
}
});
// bind events object
//-----------------
const object = this.opts.object;
object.interactive = true;
let mouseoverObject = false;
object.on('mouseover', e => {
this.timeout = window.setTimeout(() => {
mouseoverObject = true;
this.visible = true;
this.opts.container.addChild(this);
this.setPosition(e);
}, this.opts.delay * 1000);
});
object.on('mousemove', e => {
if (mouseoverObject) {
this.setPosition(e);
}
});
object.on('mouseout', e => {
mouseoverObject = false;
window.clearTimeout(this.timeout);
if (!mouseoverTooltip) {
this.hide(() => {
this.opts.container.removeChild(this);
});
}
});
return this
}
/**
* Calculates and sets the position of the tooltip.
*
* @private
* @return {Tooltip} A reference to the tooltip for chaining.
*/
setPosition(e) {
const position = e.data.getLocalPosition(this.opts.container);
this.x = position.x + this.opts.offsetLeft;
this.y = position.y + this.opts.offsetTop - this.height;
return this
}
}
/**
* Class that represents a PixiJS Badge.
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* // Add an DisplayObject to the app
* const circle = new PIXI.Graphics()
* circle.beginFill(0x5251a3)
* circle.drawCircle(50, 50, 40)
* app.scene.addChild(circle)
*
* const badge1 = new Badge({
* object: circle,
* container: app.scene,
* content: 'Das Gesetz ist der Freund des Schwachen.'
* })
*
* @class
* @extends AbstractPopup
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/badge.html|DocTest}
*/
class Badge extends AbstractPopup {
/**
* Creates an instance of a Badge.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the badge.
* @param {number} [opts.minWidth=0] - The minimum width of the badge.
* @param {number} [opts.minHeight=0] - The minimum height of the badge.
* @param {number} [opts.padding=Theme.padding / 2] - The inner spacing of the badge.
* @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip
* to display.
*/
constructor(opts = {}) {
const theme = Theme.fromString(opts.theme);
opts = Object.assign({}, {
minWidth: 0,
minHeight: 0,
padding: theme.padding / 2,
tooltip: null
}, opts);
super(opts);
this.tooltip = null;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @override
* @return {Badge} A reference to the badge for chaining.
*/
setup() {
super.setup();
// tooltip
//-----------------
if (this.opts.tooltip) {
if (typeof this.opts.tooltip === 'string') {
this.tooltip = new Tooltip({object: this, content: this.opts.tooltip});
} else {
this.opts.tooltip = Object.assign({}, {object: this}, this.opts.tooltip);
this.tooltip = new Tooltip(this.opts.tooltip);
}
}
return this
}
/**
* Should be called to refresh the layout of the badge. Can be used after resizing.
*
* @override
* @return {Badge} A reference to the badge for chaining.
*/
layout() {
super.layout();
this.content.x = this.width / 2 - this.content.width / 2 - this.opts.strokeWidth / 2;
this.content.y = this.height / 2 - this.content.height / 2 - this.opts.strokeWidth / 2;
return this
}
}
class Events$1 {
static stop(event) {
event.preventDefault();
event.stopPropagation();
}
static extractPoint(event) {
switch (event.constructor.name) {
case 'TouchEvent':
for (let i = 0; i < event.targetTouches.length; i++) {
let t = event.targetTouches[i];
return { x: t.clientX, y: t.clientY }
}
break
default:
return { x: event.clientX, y: event.clientY }
}
}
static isCaptured(event) {
if (event.__capturedBy)
return true
return false
}
static capturedBy(event, obj) {
event.__capturedBy = obj;
}
static isMouseDown(event) {
// Attempts to clone the which attribute of events failed in WebKit. May
// be this is a bug or a security feature. Workaround: we introduce
// a mouseDownSubstitute attribute that can be assigned to cloned
// events after instantiation.
if (Reflect.has(event, 'mouseDownSubstitute'))
return event.mouseDownSubstitute
return event.buttons || event.which
}
static isSimulatedEvent(event) {
return Reflect.has(event, 'mouseDownSubstitute')
}
static isMouseRightClick(event) {
return event.buttons || event.which
}
static extractTouches(targets) {
let touches = [];
for (let i = 0; i < targets.length; i++) {
let t = targets[i];
touches.push({
targetSelector: this.selector(t.target),
identifier: t.identifier,
screenX: t.screenX,
screenY: t.screenY,
clientX: t.clientX,
clientY: t.clientY,
pageX: t.pageX,
pageY: t.pageY
});
}
return touches
}
static createTouchList(targets) {
let touches = [];
for (let i = 0; i < targets.length; i++) {
let t = targets[i];
let touchTarget = document.elementFromPoint(t.pageX, t.pageY);
let touch = new Touch(undefined, touchTarget, t.identifier,
t.pageX, t.pageY, t.screenX, t.screenY);
touches.push(touch);
}
return new TouchList(...touches)
}
static extractEvent(timestamp, event) {
let targetSelector = this.selector(event.target);
let infos = {
type: event.type,
time: timestamp,
constructor: event.constructor,
data: {
targetSelector: targetSelector,
view: event.view,
mouseDownSubstitute: event.buttons || event.which, // which cannot be cloned directly
bubbles: event.bubbles,
cancelable: event.cancelable,
screenX: event.screenX,
screenY: event.screenY,
clientX: event.clientX,
clientY: event.clientY,
layerX: event.layerX,
layerY: event.layerY,
pageX: event.pageX,
pageY: event.pageY,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey,
metaKey: event.metaKey
}
};
if (event.type.startsWith('touch')) {
// On Safari-WebKit the TouchEvent has layerX, layerY coordinates
let data = infos.data;
data.targetTouches = this.extractTouches(event.targetTouches);
data.changedTouches = this.extractTouches(event.changedTouches);
data.touches = this.extractTouches(event.touches);
}
if (event.type.startsWith('pointer')) {
let data = infos.data;
data.pointerId = event.pointerId;
data.pointerType = event.pointerType;
}
if (Events$1.debug) {
Events$1.extracted.push(this.toLine(event));
}
return infos
}
static cloneEvent(type, constructor, data) {
if (type.startsWith('touch')) {
// We need to find target from layerX, layerY
//var target = document.querySelector(data.targetSelector)
// elementFromPoint(data.layerX, data.layerY)
//data.target = target
data.targetTouches = this.createTouchList(data.targetTouches);
data.changedTouches = this.createTouchList(data.changedTouches);
data.touches = this.createTouchList(data.touches);
}
// We need to find target from pageX, pageY which are only
// available after construction. They seem to getter items.
let clone = Reflect.construct(constructor, [type, data]);
clone.mouseDownSubstitute = data.mouseDownSubstitute;
return clone
}
static simulateEvent(type, constructor, data) {
data.target = document.querySelector(data.targetSelector);
let clone = this.cloneEvent(type, constructor, data);
if (data.target != null) {
data.target.dispatchEvent(clone);
}
if (Events$1.debug) {
Events$1.simulated.push(this.toLine(clone));
}
}
static toLine(event) {
return `${event.type} #${event.target.id} ${event.clientX} ${event.clientY}`
let result = event.type;
let selector = this.selector(event.target);
result += ' selector: ' + selector;
if (event.target != document.querySelector(selector))
console.log('Cannot resolve', selector);
let keys = ['layerX', 'layerY', 'pageX', 'pageY', 'clientX', 'clientY'];
for (let key of keys) {
try {
result += ' ' + key + ':' + event[key];
}
catch (e) {
console.log('Invalid key: ' + key);
}
}
return result
}
static compareExtractedWithSimulated() {
if (this.extracted.length != this.simulated.length) {
alert('Unequal length of extracted [' + this.extracted.length +
'] and simulated events [' + this.simulated.length + '].');
}
else {
for (let i = 0; i < this.extracted.length; i++) {
var extracted = this.extracted[i];
var simulated = this.simulated[i];
if (extracted != simulated) {
console.log('Events differ:' + extracted + '|' + simulated);
}
}
}
}
static selector(context) {
return OptimalSelect.select(context)
}
static reset() {
this.extracted = [];
this.simulated = [];
}
static resetSimulated() {
this.simulated = [];
}
static showExtractedEvents(event) {
if (!event.shiftKey) {
return
}
if (this.popup == null) {
let element = document.createElement('div');
Elements.setStyle(element, {
position: 'absolute',
width: '480px',
height: '640px',
overflow: 'auto',
backgroundColor: 'lightgray'
});
document.body.appendChild(element);
this.popup = element;
}
this.popup.innerHTML = '';
for (let line of this.extracted) {
let div = document.createElement('div');
div.innerHTML = line;
this.popup.appendChild(div);
}
let div = document.createElement('div');
div.innerHTML = '------------ Simulated -----------';
this.popup.appendChild(div);
for (let line of this.simulated) {
let div = document.createElement('div');
div.innerHTML = line;
this.popup.appendChild(div);
}
Elements.setStyle(this.popup,
{ left: event.clientX + 'px', top: event.clientY + 'px' });
}
}
Events$1.popup = null;
Events$1.debug = true;
Events$1.extracted = [];
Events$1.simulated = [];
Events$1.simulationRunning = false;
/**
* Callback for the button action.
*
* @callback actionCallback
* @param {object} event - The event object.
* @param {Button} button - A reference to the button (also this refers to the button).
*/
/**
* Callback for the button beforeAction.
*
* @callback beforeActionCallback
* @param {object} event - The event object.
* @param {Button} button - A reference to the button (also this refers to the button).
*/
/**
* Callback for the button afterAction.
*
* @callback afterActionCallback
* @param {object} event - The event object.
* @param {Button} button - A reference to the button (also this refers to the button).
*/
/**
* Class that represents a PixiJS Button.
*
* @example
* // Create the button
* const button = new Button({
* label: 'My Button',
* action: () => console.log('Button was clicked')
* })
*
* // Add the button to a DisplayObject
* app.scene.addChild(button)
*
* @class
* @extends PIXI.Container
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/button.html|DocTest}
*/
class Button extends PIXI.Container {
/**
* Creates an instance of a Button.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the button.
* @param {number} [opts.id=auto generated] - The id of the button.
* @param {string} [opts.label] - The label of the button.
* @param {number} [opts.x=0] - The x position of the button. Can be also set after creation with button.x = 0.
* @param {number} [opts.y=0] - The y position of the button. Can be also set after creation with button.y = 0.
* @param {string|Theme} [opts.theme=dark] - The theme to use for this button. Possible values are dark, light, red
* or a Theme object.
* @param {number} [opts.minWidth=44] - The minimum width of the button.
* @param {number} [opts.minHeight=44] - The minimum height of the button.
* @param {number} [opts.padding=Theme.padding] - The inner spacing (distance from icon and/or label) to the border.
* @param {string|PIXI.DisplayObject} [opts.icon] - The icon of the button. Can be a predefined one, an URL or an PIXI.DisplayObject.
* @param {string|PIXI.DisplayObject} [opts.iconActive=icon] - The icon of the button when activated. Can be a predefined one, an URL or an PIXI.DisplayObject.
* @param {string} [opts.iconPosition=left] - The position of the icon in relation to the label. Can be left or right.
* @param {number} [opts.iconColor=Theme.iconColor] - The color of the icon (set by the tint property) as a hex value.
* @param {number} [opts.iconColorActive=Theme.iconColorActive] - The color of the icon when activated.
* @param {number} [opts.fill=Theme.fill] - The color of the button background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
* @param {number} [opts.fillActive=Theme.fillActive] - The color of the button background when activated.
* @param {number} [opts.fillActiveAlpha=Theme.fillActiveAlpha] - The alpha value of the background when activated.
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=Theme.strokeWidth] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.strokeActive=Theme.strokeActive] - The color of the border when activated.
* @param {number} [opts.strokeActiveWidth=Theme.strokeActiveWidth] - The width of the border in pixel when activated.
* @param {number} [opts.strokeActiveAlpha=Theme.strokeActiveAlpha] - The alpha value of the border when activated.
* @param {object} [opts.textStyle=Theme.textStyle] - A textstyle object for the styling of the label. See PIXI.TextStyle
* for possible options.
* @param {number} [opts.textStyleActive=Theme.textStyleActive] - A textstyle object for the styling of the label when the
* button is activated. See PIXI.TextStyle for possible options.
* @param {string} [opts.style=default] - A shortcut for styling options. Possible values are default, link.
* @param {number} [opts.radius=Theme.radius] - The radius of the four corners of the button (which is a rounded rectangle).
* @param {boolean} [opts.disabled=false] - Is the button disabled? When disabled, the button has a lower alpha value
* and cannot be clicked (interactive is set to false).
* @param {boolean} [opts.active=false] - Is the button initially active?
* @param {actionCallback} [opts.action] - Executed when the button was triggered (by pointerup).
* @param {beforeActionCallback} [opts.beforeAction] - Executed before the main action is triggered.
* @param {afterActionCallback} [opts.afterAction] - Executed after the main action was triggered.
* @param {string} [opts.type=default] - The type of the button. Can be default or checkbox. When the type is
* checkbox, the active state is toggled automatically.
* @param {string} [opts.align=center] - The horizontal position of the label and the icon. Possible values are
* left, center and right. Only affects the style when the minWidth is bigger than the width of the icon and label.
* @param {string} [opts.verticalAlign=middle] - The vertical position of the label and the icon. Possible values are
* top, middle and button. Only affects the style when the minHeight is bigger than the height of the icon and label.
* @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip
* to display.
* @param {string|object} [opts.badge] - A string for the label of the badge or an object to configure the badge to display.
* If the parameter is an object, all badge options can be set plus the following:
* @param {string} [opts.badge.align=right] - The horizontal alignment of the badge. Possible values: left, center, right
* @param {string} [opts.badge.verticalAlign=top] - The vertical alignment of the badge. Possible values: top, middle, bottom
* @param {number} [opts.badge.offsetLeft=0] - The horizontal shift of the badge.
* @param {number} [opts.badge.offsetTop=0] - The vertical shift of the badge.
* @param {boolean} [opts.visible=true] - Is the button initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
label: null,
x: 0,
y: 0,
minWidth: 44,
minHeight: 44,
padding: theme.padding,
icon: undefined,
iconActive: undefined,
iconPosition: 'left',
iconColor: theme.iconColor,
iconColorActive: theme.iconColorActive,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
fillActive: theme.fillActive,
fillActiveAlpha: theme.fillActiveAlpha,
stroke: theme.stroke,
strokeWidth: theme.strokeWidth,
strokeAlpha: theme.strokeAlpha,
strokeActive: theme.strokeActive,
strokeActiveWidth: theme.strokeActiveWidth,
strokeActiveAlpha: theme.strokeActiveAlpha,
textStyle: theme.textStyle,
textStyleActive: theme.textStyleActive,
style: 'default',
radius: theme.radius,
disabled: false,
active: false,
action: null,
beforeAction: null,
afterAction: null,
type: 'default',
align: 'center',
verticalAlign: 'middle',
tooltip: null,
badge: null,
visible: true
}, opts);
this.id = this.opts.id;
if (typeof this.opts.icon === 'undefined' && typeof this.opts.iconActive !== 'undefined') {
this.opts.icon = this.opts.iconActive;
} else if (typeof this.opts.icon !== 'undefined' && typeof this.opts.iconActive === 'undefined') {
this.opts.iconActive = this.opts.icon;
}
if (this.opts.style === 'link') {
Object.assign(this.opts, {strokeAlpha: 0, strokeActiveAlpha: 0, fillAlpha: 0, fillActiveAlpha: 0});
}
this._active = null;
this._disabled = null;
this.iconInactive = null;
this.iconActive = null;
this.text = null;
this.button = null;
this.content = null;
this.tooltip = null;
this.badge = null;
this.visible = this.opts.visible;
// setup
//-----------------
this.setup();
}
/**
* Captures an event to inform InteractionMapper about processed events.
*
* @param {event|PIXI.InteractionEvent} event - The PIXI event to capture.
*/
capture(event) {
Events$1.capturedBy(event.data.originalEvent, this);
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Button} A reference to the button for chaining.
*/
setup() {
// Button
//-----------------
let button = new PIXI.Graphics();
this.button = button;
this.addChild(button);
// Content
//-----------------
let content = new PIXI.Container();
this.content = content;
this.addChild(content);
// Text
//-----------------
if (this.opts.label) {
this.text = new PIXI.Text(this.opts.label, this.opts.textStyle);
}
// Icon
//-----------------
if (this.opts.icon) {
this.iconInactive = this.loadIcon(this.opts.icon, this.opts.iconColor);
}
if (this.opts.iconActive) {
this.iconActive = this.loadIcon(this.opts.iconActive, this.opts.iconColorActive);
}
// interaction
//-----------------
this.button.on('pointerover', e => {
this.capture(e);
TweenLite.to([this.button, this.content], this.theme.fast, {alpha: .83, overwrite: 'none'});
});
this.button.on('pointermove', e => {
this.capture(e);
});
this.button.on('pointerout', e => {
this.capture(e);
TweenLite.to([this.button, this.content], this.theme.fast, {alpha: 1, overwrite: 'none'});
});
this.button.on('pointerdown', e => {
//this.capture(e)
TweenLite.to([this.button, this.content], this.theme.fast, {alpha: .7, overwrite: 'none'});
});
this.button.on('pointerup', e => {
this.capture(e);
if (this.opts.beforeAction) {
this.opts.beforeAction.call(this, e, this);
}
if (this.opts.action) {
this.opts.action.call(this, e, this);
}
TweenLite.to([this.button, this.content], this.theme.fast, {alpha: .83, overwrite: 'none'});
if (this.opts.type === 'checkbox') {
this.active = !this.active;
}
if (this.opts.afterAction) {
this.opts.afterAction.call(this, e, this);
}
});
// disabled
//-----------------
this.disabled = this.opts.disabled;
// active
//-----------------
this.active = this.opts.active; // calls .layout()
// tooltip
//-----------------
if (this.opts.tooltip) {
if (typeof this.opts.tooltip === 'string') {
this.tooltip = new Tooltip({object: this, content: this.opts.tooltip});
} else {
this.opts.tooltip = Object.assign({}, {object: this}, this.opts.tooltip);
this.tooltip = new Tooltip(this.opts.tooltip);
}
}
// badge
//-----------------
if (this.opts.badge) {
let opts = Object.assign({}, {
align: 'right',
verticalAlign: 'top',
offsetLeft: 0,
offsetTop: 0
});
if (typeof this.opts.badge === 'string') {
opts = Object.assign(opts, {content: this.opts.badge});
} else {
opts = Object.assign(opts, this.opts.badge);
}
const badge = new Badge(opts);
switch (opts.align) {
case 'left':
badge.x = this.x - badge.width / 2 + opts.offsetLeft;
break
case 'center':
badge.x = this.x + this.width / 2 - badge.width / 2 + opts.offsetLeft;
break
case 'right':
badge.x = this.x + this.width - badge.width / 2 + opts.offsetLeft;
}
switch (opts.verticalAlign) {
case 'top':
badge.y = this.y - badge.height / 2 + opts.offsetTop;
break
case 'middle':
badge.y = this.y + this.height / 2 - badge.height / 2 + opts.offsetTop;
break
case 'bottom':
badge.y = this.y + this.height - badge.height / 2 + opts.offsetTop;
}
this.addChild(badge);
this.badge = badge;
}
// set position
//-----------------
this.position.set(this.opts.x, this.opts.y);
return this
}
/**
* Should be called to refresh the layout of the button. Can be used after resizing.
*
* @return {Button} A reference to the button for chaining.
*/
layout() {
// Clear content
//-----------------
this.removeChild(this.content);
this.content = new PIXI.Container();
this.addChild(this.content);
// Set the icon
//-----------------
let icon = null;
if (!this.active && this.iconInactive) {
icon = this.iconInactive;
} else if (this.active && this.iconActive) {
icon = this.iconActive;
}
// Set the text
//-----------------
if (this.text) {
this.text.position.set(0, 0);
}
// Width and Height
//-----------------
let width = 0;
if (icon && this.text) {
width = icon.width + this.text.width + 3 * this.opts.padding;
} else if (icon) {
width = icon.width + 2 * this.opts.padding;
} else if (this.text) {
width = this.text.width + 2 * this.opts.padding;
}
if (width < this.opts.minWidth) {
width = this.opts.minWidth;
}
let height = 0;
if (icon) {
height = icon.height + 2 * this.opts.padding;
} else if (this.text) {
height = this.text.height + 2 * this.opts.padding;
}
if (height < this.opts.minHeight) {
height = this.opts.minHeight;
}
this._width = width;
this._height = height;
// Position icon and text
//-----------------
if (icon && this.text) {
if (this.opts.iconPosition === 'right') {
icon.x = this.text.width + this.opts.padding;
} else {
this.text.x = icon.width + this.opts.padding;
}
this.content.addChild(icon, this.text);
} else if (icon) {
this.content.addChild(icon);
} else if (this.text) {
this.content.addChild(this.text);
}
this.layoutInnerContent();
this.layoutContent();
this.icon = icon;
// draw
//-----------------
this.draw();
return this
}
/**
* Calculates the positions of the content children (icon and/or text).
*
* @private
* @return {Button} A reference to the button for chaining.
*/
layoutInnerContent() {
for (let child of this.content.children) {
switch (this.opts.verticalAlign) {
case 'top':
child.y = 0;
break
case 'middle':
child.y = this.content.height / 2 - child.height / 2;
break
case 'bottom':
child.y = this.content.height - child.height;
break
}
}
return this
}
/**
* Sets the horizontal and vertical position of the content.
* Uses the option keys "align" and "verticalAlign".
*
* @private
* @return {Button} A reference to the button for chaining.
*/
layoutContent() {
switch (this.opts.align) {
case 'left':
this.content.x = this.opts.padding;
break
case 'center':
this.content.x = ((this._width - this.content.width) / 2);
break
case 'right':
this.content.x = this._width - this.opts.padding - this.content.width;
break
}
switch (this.opts.verticalAlign) {
case 'top':
this.content.y = this.opts.padding;
break
case 'middle':
this.content.y = (this._height - this.content.height) / 2;
break
case 'bottom':
this.content.y = this._height - this.opts.padding - this.content.height;
break
}
return this
}
/**
* Draws the canvas.
*
* @private
* @return {Button} A reference to the button for chaining.
*/
draw() {
this.button.clear();
if (this.active) {
this.button.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha);
this.button.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha);
} else {
this.button.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.button.beginFill(this.opts.fill, this.opts.fillAlpha);
}
this.button.drawRoundedRect(0, 0, this._width, this._height, this.opts.radius);
this.button.endFill();
return this
}
/**
* Gets or sets the active state.
*
* @member {boolean}
*/
get active() {
return this._active
}
set active(value) {
this._active = value;
if (this._active) {
if (this.text) {
this.text.style = this.opts.textStyleActive;
}
} else {
if (this.text) {
this.text.style = this.opts.textStyle;
}
}
this.layout();
}
/**
* Gets or sets the disabled state. When disabled, the button cannot be clicked.
*
* @member {boolean}
*/
get disabled() {
return this._disabled
}
set disabled(value) {
this._disabled = value;
if (this._disabled) {
this.button.interactive = false;
this.button.buttonMode = false;
this.button.alpha = .5;
if (this.icon) {
this.icon.alpha = .5;
}
if (this.text) {
this.text.alpha = .5;
}
} else {
this.button.interactive = true;
this.button.buttonMode = true;
this.button.alpha = 1;
if (this.icon) {
this.icon.alpha = 1;
}
if (this.text) {
this.text.alpha = 1;
}
}
}
/**
* Shows the button (sets his alpha values to 1).
*
* @return {Button} A reference to the button for chaining.
*/
show() {
this.opts.strokeAlpha = 1;
this.opts.strokeActiveAlpha = 1;
this.opts.fillAlpha = 1;
this.opts.fillActiveAlpha = 1;
this.layout();
return this
}
/**
* Hides the button (sets his alpha values to 0).
*
* @return {Button} A reference to the button for chaining.
*/
hide() {
this.opts.strokeAlpha = 0;
this.opts.strokeActiveAlpha = 0;
this.opts.fillAlpha = 0;
this.opts.fillActiveAlpha = 0;
this.layout();
return this
}
/**
* Loads an icon
*
* @private
* @param {string|PIXI.DisplayObject} icon - The icon to load.
* @param {number} color - The color of the icon (if not an PIXI.DisplayObject).
* @return {PIXI.DisplayObject} Return the icon as an PIXI.DisplayObject.
*/
loadIcon(icon, color) {
let displayObject = null;
if (icon instanceof PIXI.DisplayObject) {
displayObject = icon;
} else {
let size = 17;
if (this.text) {
size = this.text.height;
} else if (this.opts.minHeight) {
size = this.opts.minHeight - (2 * this.opts.padding);
}
const url = Button.iconIsUrl(icon) ? icon : `../../assets/icons/png/flat/${icon}.png`;
const iconTexture = PIXI.Texture.fromImage(url, true);
const sprite = new PIXI.Sprite(iconTexture);
sprite.tint = color;
sprite.width = size;
sprite.height = size;
displayObject = sprite;
}
return displayObject
}
/**
* Tests if an icon string is an url.
*
* @private
* @static
* @param {string} url - The url to test.
* @return {boolean} true if the url is an url to an image.
*/
static iconIsUrl(url) {
return /\.(png|svg|gif|jpg|jpeg|tif|tiff)$/i.test(url)
}
/**
* Gets or sets the color of the current icon (no matter how the status is). Changing the color, changes
* the tint property of the icon sprite.
*
* @member {number}
*/
get iconColor() {
return this.icon ? this.icon.tint : null
}
set iconColor(value) {
if (this.icon) {
this.icon.tint = value;
}
}
}
/**
* Class that represents a PixiJS ButtonGroup.
*
* @example
* // Create the button group
* const buttonGroup = new ButtonGroup({
* buttons: [
* {label: 'Button 1', action: event => console.log(event)},
* {label: 'Button 2', action: event => console.log(event)},
* {label: 'Button 3', action: event => console.log(event)}
* ],
* minWidth: 100
* })
*
* // Add the button group to a DisplayObject
* app.scene.addChild(buttonGroup)
*
* @class
* @extends PIXI.Graphics
* @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/buttongroup.html|DocTest}
*/
class ButtonGroup extends PIXI.Graphics {
/**
* Creates an instance of a ButtonGroup.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the button group.
* @param {number} [opts.id=auto generated] - The id of the button group.
* @param {number} [opts.x=0] - The x position of the button group. Can be also set after creation with buttonGroup.x = 0.
* @param {number} [opts.y=0] - The y position of the button group. Can be also set after creation with buttonGroup.y = 0.
* @param {object[]} [opts.buttons=[]] - An array of the buttons of the button group. One item of the array (one object)
* can have exactly the same properties as an Button object when instantiating a Button. If a property of the button group
* conflicts with a property of a button object, the value from the button object will be used.
* @param {string|Theme=} [opts.theme=dark] - The theme to use for this button group. Possible values are dark, light, red
* or a Theme object.
* @param {number} [opts.minWidth=44] - Button: The minimum width of one button.
* @param {number} [opts.minHeight=44] - Button: The minimum height of one button.
* @param {number} [opts.padding=Theme.padding] - Button: The inner spacing (distance from icon and/or label) the the border.
* @param {number} [opts.margin=Theme.margin] - The outer spacing (distance from one button to the previous/next button).
* @param {string} [opts.iconPosition=left] - Button: The position of the icon in relation to the label. Can be left or right.
* @param {number} [opts.iconColor=Theme.iconColor] - Button: The color of the icon (set by the tint property) as a hex value.
* @param {number} [opts.iconColorActive=Theme.iconColorActive] - Button: The color of the icon when activated.
* @param {number} [opts.fill=Theme.fill] - Button: The color of the button background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - Button: The alpha value of the background.
* @param {number} [opts.fillActive=Theme.fillActive] - Button: The color of the button background when activated.
* @param {number} [opts.fillActiveAlpha=Theme.fillActiveAlpha] - Button: The alpha value of the background when activated.
* @param {number} [opts.stroke=Theme.stroke] - Button: The color of the border as a hex value.
* @param {number} [opts.strokeWidth=Theme.strokeWidth] - Button: The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - Button: The alpha value of the border.
* @param {number} [opts.strokeActive=Theme.strokeActive] - Button: The color of the border when activated.
* @param {number} [opts.strokeActiveWidth=Theme.strokeActiveWidth] - Button: The width of the border in pixel when activated.
* @param {number} [opts.strokeActiveAlpha=Theme.strokeActiveAlpha] - Button: The alpha value of the border when activated.
* @param {object} [opts.textStyle=Theme.textStyle] - Button: A textstyle object for the styling of the label. See PIXI.TextStyle
* for possible options.
* @param {number} [opts.textStyleActive=Theme.textStyleActive] - Button: A textstyle object for the styling of the label when the
* button is activated. See PIXI.TextStyle for possible options.
* @param {string} [opts.style=default] - A shortcut for styling options. Possible values are default, link.
* @param {number} [opts.radius=Theme.radius] - Button: The radius of the four corners of the button (which is a rounded rectangle).
* @param {boolean} [opts.disabled=false] - Is the button group disabled? When disabled, the button group has a lower alpha value
* and cannot be clicked (interactive of every button is set to false).
* @param {string} [opts.type=default] - The type of the button group. Can be default, checkbox or radio. When the type is
* checkbox, the active state is toggled for each button automatically. When the type is radio, only one button can
* be activated at the same time.
* @param {string} [opts.orientation=horizontal] - The orientation of the button group. Can be horizontal or vertical.
* @param {string} [opts.align=center] - Button: The horizontal position of the label and the icon. Possible values are
* left, center and right. Only affects the style when the minWidth is bigger than the width of the icon and label.
* @param {string} [opts.verticalAlign=middle] - Button: The vertical position of the label and the icon. Possible values are
* top, middle and bottom. Only affects the style when the minHeight is bigger than the height of the icon and label.
* @param {boolean} [opts.visible=true] - Is the button group initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
x: 0,
y: 0,
buttons: [],
minWidth: 44,
minHeight: 44,
padding: theme.padding,
margin: theme.margin,
iconPosition: 'left', // left, right
iconColor: theme.iconColor,
iconColorActive: theme.iconColorActive,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
fillActive: theme.fillActive,
fillActiveAlpha: theme.fillActiveAlpha,
stroke: theme.stroke,
strokeWidth: theme.strokeWidth,
strokeAlpha: theme.strokeAlpha,
strokeActive: theme.strokeActive,
strokeActiveWidth: theme.strokeActiveWidth,
strokeActiveAlpha: theme.strokeActiveAlpha,
textStyle: theme.textStyle,
textStyleActive: theme.textStyleActive,
style: 'default',
radius: theme.radius,
disabled: null,
type: 'default', // default, checkbox, radio
orientation: 'horizontal',
align: 'center', // left, center, right
verticalAlign: 'middle', // top, middle, bottom
visible: true
}, opts);
this.buttons = [];
this._disabled = null;
this.visible = this.opts.visible;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {ButtonGroup} A reference to the button group for chaining.
*/
setup() {
// Buttons
//-----------------
let position = 0;
for (let it of this.opts.buttons) {
delete it.x;
delete it.y;
if (this.opts.orientation === 'horizontal') {
it.x = position;
} else {
it.y = position;
}
it.theme = it.theme || this.opts.theme;
it.minWidth = it.minWidth || this.opts.minWidth;
it.minHeight = it.minHeight || this.opts.minHeight;
it.padding = it.padding || this.opts.padding;
it.iconPosition = it.iconPosition || this.opts.iconPosition;
it.iconColor = it.iconColor || this.opts.iconColor;
it.iconColorActive = it.iconColorActive || this.opts.iconColorActive;
it.fill = it.fill || this.opts.fill;
it.fillAlpha = it.fillAlpha || this.opts.fillAlpha;
it.fillActive = it.fillActive || this.opts.fillActive;
it.fillActiveAlpha = it.fillActiveAlpha || this.opts.fillActiveAlpha;
it.stroke = it.stroke || this.opts.stroke;
it.strokeWidth = it.strokeWidth != null ? it.strokeWidth : this.opts.strokeWidth;
it.strokeAlpha = it.strokeAlpha != null ? it.strokeAlpha : this.opts.strokeAlpha;
it.strokeActive = it.strokeActive || this.opts.strokeActive;
it.strokeActiveWidth = it.strokeActiveWidth != null ? it.strokeActiveWidth : this.opts.strokeActiveWidth;
it.strokeActiveAlpha = it.strokeActiveAlpha != null ? it.strokeActiveAlpha : this.opts.strokeActiveAlpha;
it.textStyle = it.textStyle || this.opts.textStyle;
it.textStyleActive = it.textStyleActive || this.opts.textStyleActive;
it.style = it.style || this.opts.style;
it.radius = it.radius != null ? it.radius : this.opts.radius;
if (!it.type) {
switch (this.opts.type) {
case 'checkbox':
it.type = this.opts.type;
break
default:
it.type = 'default';
break
}
}
//it.type = it.type || this.opts.type || 'default'
it.align = it.align || this.opts.align;
it.verticalAlign = it.verticalAlign || this.opts.verticalAlign;
it.afterAction = (event, button) => {
if (this.opts.type === 'radio' && button.opts.type === 'default') {
this.buttons.forEach(it => {
if (it.opts.type === 'default') {
it.active = false;
}
});
if (button.opts.type === 'default') {
button.active = true;
}
}
};
if (it.tooltip) {
if (typeof it.tooltip === 'string') {
it.tooltip = {content: it.tooltip, container: this};
} else {
it.tooltip = Object.assign({}, {container: this}, it.tooltip);
}
}
let button = new Button(it);
this.addChild(button);
this.buttons.push(button);
position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin;
}
if (this.opts.orientation === 'vertical') {
const maxWidth = this.getMaxButtonWidth();
this.buttons.forEach(it => {
it.opts.minWidth = maxWidth;
it.layout();
});
}
// disabled
//-----------------
if (this.opts.disabled != null) {
this.disabled = this.opts.disabled;
}
return this
}
/**
* Should be called to refresh the layout of the button group. Can be used after resizing.
*
* @return {ButtonGroup} A reference to the button group for chaining.
*/
layout() {
// set position
//-----------------
this.position.set(this.opts.x, this.opts.y);
// draw
//-----------------
this.draw();
return this
}
/**
* Draws the canvas.
*
* @private
* @return {ButtonGroup} A reference to the button group for chaining.
*/
draw() {
if (this.opts.margin === 0) {
this.buttons.forEach(it => it.hide());
this.clear();
this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.beginFill(this.opts.fill, this.opts.fillAlpha);
this.drawRoundedRect(0, 0, this.width, this.height, this.opts.radius);
// Draw borders
this.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha / 2);
this.buttons.forEach((it, i) => {
if (i > 0) {
this.moveTo(it.x, it.y);
if (this.opts.orientation === 'horizontal') {
this.lineTo(it.x, it.height);
} else {
this.lineTo(it.width, it.y);
}
}
});
this.endFill();
}
return this
}
/**
* Gets or sets the disabled state. When disabled, no button of the button group can be clicked.
*
* @member {boolean}
*/
get disabled() {
return this._disabled
}
set disabled(value) {
this._disabled = value;
this.buttons.forEach(it => it.disabled = value);
}
/**
* Searches all buttons of the button group and returns the maximum width of one button.
*
* @private
* @return {number} The maximum with of a button of the button group.
*/
getMaxButtonWidth() {
let widths = this.buttons.map(it => it.width);
return Math.max(...widths)
}
/**
* Shows the button group (sets his alpha value to 1).
*
* @return {ButtonGroup} A reference to the button group for chaining.
*/
show() {
this.alpha = 1;
return this
}
/**
* Hides the button group (sets his alpha value to 0).
*
* @return {ButtonGroup} A reference to the button group for chaining.
*/
hide() {
this.alpha = 0;
return this
}
}
/**
* Class that represents a PixiJS InteractivePopup.
* The class is used for various other Popup-like classes
* like Popup, Message...
*
* @class
* @abstract
* @extends AbstractPopup
*/
class InteractivePopup extends AbstractPopup {
/**
* Creates an instance of an InteractivePopup (only for internal use).
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the popup.
* @param {boolean} [opts.closeOnPopup=false] - Should the popup be closed when the user clicks on the popup?
* @param {boolean} [opts.closeButton=true] - Should a close button be displayed on the upper right corner?
* @param {object} [opts.button] - A Button object to be display on the lower right corner.
* @param {object} [opts.buttonGroup] - A ButtonGroup object to be displayed on the lower right corner.
*/
constructor(opts = {}) {
opts = Object.assign({}, {
closeOnPopup: false,
closeButton: true,
button: null,
buttonGroup: null
}, opts);
super(opts);
this._closeButton = null;
this._buttons = null;
// padding
this.smallPadding = this.opts.padding / 2;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates the framework and instantiates everything.
*
* @private
* @return {AbstractPopup} A reference to the popup for chaining.
*/
setup() {
super.setup();
// interaction
//-----------------
this.on('pointerup', e => {
if (this.opts.closeOnPopup) {
this.hide();
} else {
e.stopPropagation();
}
});
// closeButton
//-----------------
if (this.opts.closeButton) {
let closeButton = PIXI.Sprite.fromImage('../../assets/icons/png/flat/close.png', true);
closeButton.width = this.headerStyle.fontSize;
closeButton.height = closeButton.width;
closeButton.tint = this.theme.color2;
// This is needed, because the closeButton belongs to the content. The popup must resize with the closeButton.
if (this._header) {
closeButton.x = this._header.width + this.innerPadding;
} else if (this._content) {
closeButton.x = this._content.width + this.innerPadding;
}
closeButton.interactive = true;
closeButton.buttonMode = true;
closeButton.on('pointerdown', e => {
this.hide();
});
this._closeButton = closeButton;
this.addChild(closeButton);
// maxWidth is set and a closeButton should be displayed
//-----------------
if (this.opts.maxWidth) {
const wordWrapWidth = this.opts.maxWidth - (2 * this.opts.padding) - this.smallPadding - this._closeButton.width;
if (this._header) {
this.headerStyle.wordWrapWidth = wordWrapWidth;
} else if (this._content) {
this.textStyle.wordWrapWidth = wordWrapWidth;
}
}
}
// buttons
//-----------------
if (this.opts.button || this.opts.buttonGroup) {
if (this.opts.button) {
this._buttons = new Button(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.button));
} else {
this._buttons = new ButtonGroup(Object.assign({textStyle: this.theme.textStyleSmall}, this.opts.buttonGroup));
}
this.addChild(this._buttons);
this._buttons.y = this.innerPadding + this.sy;
}
return this
}
/**
* Should be called to refresh the layout of the popup. Can be used after resizing.
*
* @return {AbstractPopup} A reference to the popup for chaining.
*/
layout() {
super.layout();
// closeButton
//-----------------
if (this.opts.closeButton) {
this._closeButton.x = this.wantedWidth - this.smallPadding - this._closeButton.width;
this._closeButton.y = this.smallPadding;
}
// buttons
//-----------------
if (this._buttons) {
this._buttons.x = this.wantedWidth - this.opts.padding - this._buttons.width;
this._buttons.y = this.wantedHeight - this.opts.padding - this._buttons.height;
}
return this
}
/**
* Calculates the size of the children of the AbstractPopup.
* Cannot use getBounds() because it is not updated when children
* are removed.
*
* @private
* @override
* @returns {object} An JavaScript object width the keys width and height.
*/
getInnerSize() {
let size = super.getInnerSize();
if (this._closeButton) {
size.width += this.smallPadding + this._closeButton.width;
}
if (this._buttons) {
size.width = Math.max(size.width, this._buttons.x + this._buttons.width);
size.height += this.innerPadding + this._buttons.height;
}
return size
}
}
/**
* Class that represents a PixiJS Popup.
*
* @example
* // Create the popup
* const popup = new Popup({
* header: 'Goethe',
* content: 'Man kann die Erfahrung nicht früh genug machen, wie entbehrlich man in der Welt ist.'
* })
*
* // Add the popup to a DisplayObject
* app.scene.addChild(popup)
*
* @class
* @extends InteractivePopup
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popup.html|DocTest}
*/
class Popup extends InteractivePopup {
/**
* Creates an instance of a Popup.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the popup.
* @param {boolean} [opts.closeButton=false] - Should a close button be displayed on the upper right corner?
* @param {number} [opts.minWidth=0] - The minimum width of the popup.
* @param {number} [opts.minHeight=0] - The minimum height of the popup.
*/
constructor(opts = {}) {
opts = Object.assign({}, {
closeButton: false,
minWidth: 0,
minHeight: 0
}, opts);
super(opts);
}
}
/**
* Class that represents a PixiJS Modal.
*
* @example
* // Create the button and the modal when clicked
* const button = new Button({
* label: 'Show Modal',
* action: e => {
* const modal = new Modal({
* app: app,
* header: 'This is the header',
* content: 'This is the text.'
* })
* app.scene.addChild(modal)
* }
* })
*
* // Add the button to a DisplayObject
* app.scene.addChild(button)
*
* @class
* @extends PIXI.Container
* @extends InteractivePopup
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/modal.html|DocTest}
*/
class Modal extends PIXI.Container {
/**
* Creates an instance of a Modal.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the modal.
* @param {number} [opts.id=auto generated] - The id of the modal.
* @param {PIXIApp} [opts.app=window.app] - The app where the modal belongs to.
* @param {number} [opts.backgroundFill=Theme.background] - The color of the background.
* @param {number} [opts.backgroundFillAlpha=0.6] - The opacity of the background.
* @param {boolean} [opts.closeOnBackground=true] - Should the modal be closed when the user clicks the
* background?
* @param {boolean} [opts.visible=true] - Is the modal initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
app: window.app,
backgroundFill: theme.background,
backgroundFillAlpha: .6,
closeOnBackground: true,
visible: true
}, opts);
this.id = this.opts.id;
this.background = null;
this.popup = null;
this.alpha = 0;
this.visible = this.opts.visible;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Modal} A reference to the modal for chaining.
*/
setup() {
// interaction
//-----------------
this.interactive = true;
this.on('added', e => {
if (this.visible) {
this.show();
}
});
// background
//-----------------
let background = new PIXI.Graphics();
this.background = background;
this.addChild(this.background);
if (this.opts.closeOnBackground) {
background.interactive = true;
background.on('pointerup', e => {
this.hide();
});
}
// popup
//-----------------
const popupOpts = Object.assign({}, this.opts, {
visible: true,
onHidden: () => {
this.hide();
}
});
let popup = new InteractivePopup(popupOpts);
this.popup = popup;
this.addChild(popup);
popup.show();
return this
}
/**
* Should be called to refresh the layout of the modal. Can be used after resizing.
*
* @return {Modal} A reference to the modal for chaining.
*/
layout() {
const width = this.opts.app.size.width;
const height = this.opts.app.size.height;
// background
//-----------------
this.background.clear();
this.background.beginFill(this.opts.backgroundFill, this.opts.backgroundFillAlpha);
this.background.drawRect(0, 0, width, height);
this.background.endFill();
// position
this.popup.x = width / 2 - this.popup.width / 2;
this.popup.y = height / 2 - this.popup.height / 2;
return this
}
/**
* Shows the modal (sets his alpha values to 1).
*
* @return {Modal} A reference to the modal for chaining.
*/
show() {
TweenLite.to(this, this.theme.fast, {alpha: 1, onStart: () => this.visible = true});
return this
}
/**
* Hides the modal (sets his alpha values to 0).
*
* @return {Modal} A reference to the modal for chaining.
*/
hide() {
TweenLite.to(this, this.theme.fast, {alpha: 0, onComplete: () => this.visible = false});
return this
}
/**
* Sets or gets the header. The getter always returns a PIXI.Text object. The setter can receive
* a string or a PIXI.Text object.
*
* @member {string|PIXI.Text}
*/
get header() {
return this.popup.header
}
set header(value) {
this.opts.header = value;
this.background.destroy();
this.popup.destroy();
this.setup().layout();
}
/**
* Sets or gets the content. The getter always returns an PIXI.DisplayObject. The setter can receive
* a string or a PIXI.DisplayObject.
*
* @member {string|PIXI.DisplayObject}
*/
get content() {
return this.popup.content
}
set content(value) {
this.opts.content = value;
this.background.destroy();
this.popup.destroy();
this.setup().layout();
}
}
/**
* Class that represents a Message. A message pops up and disappears after a specific amount of time.
*
* @example
* // Create the PixiJS App
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* // Create a button
* let button = new Button({
* label: 'Click me',
* action: e => {
* const message = new Message({
* app: app,
* header: 'Header',
* content: 'Text.'
* })
* app.scene.addChild(message)
* }
* })
*
* // Add the button to the scene
* app.scene.addChild(button)
*
* @class
* @extends InteractivePopup
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/message.html|DocTest}
*/
class Message extends InteractivePopup {
/**
* Creates an instance of a Message.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the message.
* @param {PIXIApp} [opts.app=window.app] - The PIXIApp where this message belongs to.
* @param {boolean} [opts.closeButton=false] - Should a close button be displayed in the upper right corner?
* @param {number} [opts.minWidth=280] - The minimum width of the message box. Automatically expands with the content.
* @param {number} [opts.minHeight=100] - The minimum height of the message box. Automatically expands with the content.
* @param {number} [opts.margin=Theme.margin] - The outer spacing of the message box.
* @param {string} [opts.align=right] - The horizontal position of the message box relative to the app. Possible
* values are left, center, right.
* @param {string} [opts.verticalAlign=top] - The vertical position of the message box relative to the app. Possible
* values are top, middle, bottom.
* @param {number} [opts.duration=5] - The duration in seconds when the message box should disappear.
* @param {boolean} [opts.autoClose=true] - Should the message box be closed automatically?
* @param {number} [opts.closeDuration=Theme.fast] - The duration in seconds of the closing of the message box.
*/
constructor(opts = {}) {
const theme = Theme.fromString(opts.theme);
opts = Object.assign({}, {
app: window.app,
closeButton: false,
minWidth: 280,
minHeight: 100,
margin: theme.margin,
align: 'right', // left, center, right
verticalAlign: 'top', // top, middle, bottom
duration: 5,
autoClose: true,
closeDuration: theme.fast
}, opts);
super(opts);
}
/**
* Relayouts the position of the message box.
*
* @return {Message} Returns the message box for chaining.
*/
layout() {
super.layout();
// horizontal
switch (this.opts.align) {
case 'left':
this.x = this.opts.margin;
break
case 'center':
this.x = (this.opts.app.size.width / 2) - (this.width / 2);
break
case 'right':
this.x = this.opts.app.size.width - this.opts.margin - this.width;
break
}
// vertical
switch (this.opts.verticalAlign) {
case 'top':
this.y = this.opts.margin;
break
case 'middle':
this.y = (this.opts.app.size.height / 2) - (this.height / 2);
break
case 'bottom':
this.y = this.opts.app.size.height - this.opts.margin - this.height;
break
}
}
/**
* Shows the message box.
*
* @private
*/
show() {
super.show();
if (this.opts.autoClose) {
window.setTimeout(() => {
this.hide();
}, this.opts.duration * 1000);
}
}
}
/* globals WebKitPoint */
/** Tests whether an object is empty
* @param {Object} obj - the object to be tested
* @return {boolean}
*/
function isEmpty(obj) {
// > isEmpty({})
// true
for (let i in obj) {
return false
}
return true
}
function lerp(start, stop, amt) {
return amt * (stop - start) + start
}
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
// Taken from: https://davidwalsh.name/essential-javascript-functions
function debounce(func, wait, immediate) {
let timeout;
return function () {
let context = this,
args = arguments;
let later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
}
}
/** Returns an id that is guaranteed to be unique within the livetime of the
* application
* @return {string}
*/
let _idGenerator = 0;
function getId() {
return 'id' + _idGenerator++
}
class Dates {
static create(fullYear, month, day) {
return new Date(Date.UTC(fullYear, month, day))
}
static daysInMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate()
}
static startYearRange(date) {
return new Date(Date.UTC(date.getFullYear() - 1, 11, 31, 23, 59, 59, 999))
}
static endYearRange(date) {
return new Date(Date.UTC(date.getFullYear() + 1, 0, 1))
}
static prevYear(date, offset = 1) {
return this.create(date.getFullYear() - offset, 0, 1)
}
static nextYear(date, offset = 1) {
return this.create(date.getFullYear() + offset, 0, 1)
}
static nextMonth(date) {
return this.create(date.getFullYear(), date.getMonth() + 1, 1)
}
static nextDay(date) {
return this.create(
date.getFullYear(),
date.getMonth(),
date.getDate() + 1
)
}
static nextHour(date) {
// See http://stackoverflow.com/questions/1050720/adding-hours-to-javascript-date-object
return new Date(date.getTime() + 60 * 60 * 1000)
}
static nextMinute(date) {
// See above
return new Date(date.getTime() + 60 * 1000)
}
static nextSecond(date) {
// See above
return new Date(date.getTime() + 1000)
}
static nextMillisecond(date) {
// See above
return new Date(date.getTime() + 1)
}
static *iterYears(start, end) {
let date = this.create(start.getFullYear(), 0, 1);
while (date <= end) {
yield date;
date = this.nextYear(date);
}
yield date;
}
static *iterMonths(year, limit = 12) {
let month = 0;
while (month < limit) {
let date = this.create(year.getFullYear(), month, 1);
yield date;
month += 1;
}
}
static *iterMonthsOfYears(years) {
for (let year of years) {
for (let month of this.iterMonths(year)) {
yield month;
}
}
}
static *iterDays(month) {
let day = 1;
let limit = Dates.daysInMonth(month);
while (day <= limit) {
let date = this.create(month.getFullYear(), month.getMonth(), day);
yield date;
day += 1;
}
}
static *iterDaysOfMonths(months) {
for (let month of months) {
for (let day of this.iterDays(month)) {
yield day;
}
}
}
}
/* Color conversion functions */
class Colors {
// http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
static rgb2num(red, green, blue) {
let rgb = blue | (green << 8) | (red << 16);
return 0x000000 + rgb
}
static rgb2hex(red, green, blue) {
let rgb = blue | (green << 8) | (red << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1)
}
static hex2rgb(hex) {
// long version
let r = hex.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
if (r) {
return r.slice(1, 4).map(x => {
return parseInt(x, 16)
})
}
// short version
r = hex.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i);
if (r) {
return r.slice(1, 4).map(x => {
return 0x11 * parseInt(x, 16)
})
}
return null
}
static rgb(r, g, b) {
return { r, g, b }
}
static string2hex(str) {
return parseInt('0x' + str.slice(1))
}
static lerp(rgb1, rgb2, amount) {
return {
r: Math.round(lerp(rgb1.r, rgb2.r, amount)),
g: Math.round(lerp(rgb1.g, rgb2.g, amount)),
b: Math.round(lerp(rgb1.b, rgb2.b, amount))
}
}
static get violet() {
return Colors.rgb2num(89, 34, 131)
}
static get steelblue() {
return Colors.rgb2num(0, 130, 164)
}
static get ochre() {
return Colors.rgb2num(181, 157, 0)
}
static get turquoise() {
return Colors.rgb2num(34, 164, 131)
}
static get eminence() {
return Colors.rgb2num(150, 60, 134)
}
static random() {
let r = Math.round(Math.random() * 255);
let g = Math.round(Math.random() * 255);
let b = Math.round(Math.random() * 255);
return Colors.rgb2num(r, g, b)
}
}
class Cycle extends Array {
constructor(...items) {
super();
for (let item of items) {
this.push(item);
}
this.index = 0;
}
next() {
if (this.index == this.length) {
this.index = 0;
}
return this[this.index++]
}
current() {
if (this.index === this.length) {
this.index = 0;
}
return this[this.index]
}
}
/** Static methods to compute 2D points with x and y coordinates.
*/
class Points {
static length(a) {
return Math.sqrt(a.x * a.x + a.y * a.y)
}
static normalize(p) {
let len = this.length(p);
return this.multiplyScalar(p, 1 / len)
}
static mean(a, b) {
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }
}
static subtract(a, b) {
return { x: a.x - b.x, y: a.y - b.y }
}
static multiply(a, b) {
return { x: a.x * b.x, y: a.y * b.y }
}
static divide(a, b) {
return { x: a.x / b.x, y: a.y / b.y }
}
static multiplyScalar(a, b) {
return { x: a.x * b, y: a.y * b }
}
static add(a, b) {
return { x: a.x + b.x, y: a.y + b.y }
}
static negate(p) {
return { x: -p.x, y: -p.y }
}
static angle(p1, p2) {
return Math.atan2(p1.y - p2.y, p1.x - p2.x)
}
static normalizedAngle(p1, p2) {
return Angle.normalize(this.angle(p1, p2))
}
static normalized2Angle(p1, p2) {
return Angle.normalize2(this.angle(p1, p2))
}
static arc(p, alpha, radius) {
return {
x: p.x + radius * Math.cos(alpha),
y: p.y + radius * Math.sin(alpha)
}
}
static distance(a, b) {
let dx = a.x - b.x;
let dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy)
}
static fromPageToNode(element, p) {
// if (window.webkitConvertPointFromPageToNode) {
// return window.webkitConvertPointFromPageToNode(element,
// new WebKitPoint(p.x, p.y))
// }
return window.convertPointFromPageToNode(element, p.x, p.y)
}
static fromNodeToPage(element, p) {
// if (window.webkitConvertPointFromNodeToPage) {
// return window.webkitConvertPointFromNodeToPage(element,
// new WebKitPoint(p.x, p.y))
// }
return window.convertPointFromNodeToPage(element, p.x, p.y)
}
}
/** Static methods to compute angles.
*/
class Angle {
static normalize(angle) {
let TAU = Math.PI * 2.0;
while (angle > Math.PI) {
angle -= TAU;
}
while (angle < -Math.PI) {
angle += TAU;
}
return angle
}
static normalize2(angle) {
let TAU = Math.PI * 2.0;
while (angle > TAU) {
angle -= TAU;
}
while (angle < 0) {
angle += TAU;
}
return angle
}
static normalizeDegree(angle) {
let full = 360.0;
while (angle > 180.0) {
angle -= full;
}
while (angle < -180.0) {
angle += full;
}
return angle
}
static normalizedDiff(a, b) {
return this.normalize(this.diff(a, b))
}
static normalized2Diff(a, b) {
return this.normalize2(this.diff(a, b))
}
static diff(a, b) {
return Math.atan2(Math.sin(a - b), Math.cos(a - b))
}
static degree2radian(degree) {
return Math.PI * degree / 180.0
}
static radian2degree(rad) {
return 180.0 / Math.PI * rad
}
}
class Elements$1 {
static setStyle(element, styles) {
for (let key in styles) {
element.style[key] = styles[key];
}
}
static addClass(element, cssClass) {
element.classList.add(cssClass);
}
static removeClass(element, cssClass) {
element.classList.remove(cssClass);
}
static toggleClass(element, cssClass) {
element.classList.toggle(cssClass);
}
static hasClass(element, cssClass) {
return element.classList.contains(cssClass)
}
}
class MapProxy {
/* This class is needed if we want to use the interaction classes
in Firefox 45.8 and modern Browsers.
A workaround for https://github.com/babel/babel/issues/2334
*/
constructor() {
this.map = new Map();
}
get size() {
return this.map.size
}
get(key) {
return this.map.get(key)
}
set(key, value) {
return this.map.set(key, value)
}
delete(key) {
return this.map.delete(key)
}
clear() {
return this.map.clear()
}
has(key) {
return this.map.has(key)
}
keys() {
return this.map.keys()
}
values() {
return this.map.values()
}
entries() {
return this.map.entries()
}
forEach(func) {
this.map.forEach(func);
}
}
/* Based om https://gist.github.com/cwleonard/e124d63238bda7a3cbfa */
class Polygon {
/*
* This is the Polygon constructor. All points are center-relative.
*/
constructor(center) {
this.points = new Array();
this.center = center;
}
/*
* Point x and y values should be relative to the center.
*/
addPoint(p) {
this.points.push(p);
}
/*
* Point x and y values should be absolute coordinates.
*/
addAbsolutePoint(p) {
this.points.push({ x: p.x - this.center.x, y: p.y - this.center.y });
}
/*
* Returns the number of sides. Equal to the number of vertices.
*/
getNumberOfSides() {
return this.points.length
}
/*
* rotate the polygon by a number of radians
*/
rotate(rads) {
for (let i = 0; i < this.points.length; i++) {
let x = this.points[i].x;
let y = this.points[i].y;
this.points[i].x = Math.cos(rads) * x - Math.sin(rads) * y;
this.points[i].y = Math.sin(rads) * x + Math.cos(rads) * y;
}
}
/*
* The draw function takes as a parameter a Context object from
* a Canvas element and draws the polygon on it.
*/
draw(context, { lineWidth = 2, stroke = '#000000', fill = null } = {}) {
context.beginPath();
context.moveTo(
this.points[0].x + this.center.x,
this.points[0].y + this.center.y
);
for (let i = 1; i < this.points.length; i++) {
context.lineTo(
this.points[i].x + this.center.x,
this.points[i].y + this.center.y
);
}
context.closePath();
context.lineWidth = lineWidth;
if (stroke) {
context.strokeStyle = stroke;
context.stroke();
}
if (fill) {
context.fillStyle = fill;
context.fill();
}
}
absolutePoints() {
let result = new Array();
for (let p of this.points) {
result.push(Points.add(p, this.center));
}
return result
}
flatAbsolutePoints() {
let result = new Array();
for (let p of this.points) {
let a = Points.add(p, this.center);
result.push(a.x);
result.push(a.y);
}
return result
}
/*
* This function returns true if the given point is inside the polygon,
* and false otherwise.
*/
containsPoint(pnt) {
let nvert = this.points.length;
let testx = pnt.x;
let testy = pnt.y;
let vertx = new Array();
for (let q = 0; q < this.points.length; q++) {
vertx.push(this.points[q].x + this.center.x);
}
let verty = new Array();
for (let w = 0; w < this.points.length; w++) {
verty.push(this.points[w].y + this.center.y);
}
let i,
j = 0;
let c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
if (
verty[i] > testy != verty[j] > testy &&
testx <
(vertx[j] - vertx[i]) *
(testy - verty[i]) /
(verty[j] - verty[i]) +
vertx[i]
)
c = !c;
}
return c
}
multiplyScalar(scale) {
let center = Points.multiplyScalar(this.center, scale);
let clone = new Polygon(center);
for (let p of this.points) {
clone.addPoint(Points.multiplyScalar(p, scale));
}
return clone
}
/*
* To detect intersection with another Polygon object, this
* function uses the Separating Axis Theorem. It returns false
* if there is no intersection, or an object if there is. The object
* contains 2 fields, overlap and axis. Moving the polygon by overlap
* on axis will get the polygons out of intersection.
*/
intersectsWith(other) {
let axis = { x: 0, y: 0 };
let tmp, minA, maxA, minB, maxB;
let side, i;
let smallest = null;
let overlap = 99999999;
/* test polygon A's sides */
for (side = 0; side < this.getNumberOfSides(); side++) {
/* get the axis that we will project onto */
if (side == 0) {
axis.x =
this.points[this.getNumberOfSides() - 1].y -
this.points[0].y;
axis.y =
this.points[0].x -
this.points[this.getNumberOfSides() - 1].x;
} else {
axis.x = this.points[side - 1].y - this.points[side].y;
axis.y = this.points[side].x - this.points[side - 1].x;
}
/* normalize the axis */
tmp = Math.sqrt(axis.x * axis.x + axis.y * axis.y);
axis.x /= tmp;
axis.y /= tmp;
/* project polygon A onto axis to determine the min/max */
minA = maxA = this.points[0].x * axis.x + this.points[0].y * axis.y;
for (i = 1; i < this.getNumberOfSides(); i++) {
tmp = this.points[i].x * axis.x + this.points[i].y * axis.y;
if (tmp > maxA) maxA = tmp;
else if (tmp < minA) minA = tmp;
}
/* correct for offset */
tmp = this.center.x * axis.x + this.center.y * axis.y;
minA += tmp;
maxA += tmp;
/* project polygon B onto axis to determine the min/max */
minB = maxB =
other.points[0].x * axis.x + other.points[0].y * axis.y;
for (i = 1; i < other.getNumberOfSides(); i++) {
tmp = other.points[i].x * axis.x + other.points[i].y * axis.y;
if (tmp > maxB) maxB = tmp;
else if (tmp < minB) minB = tmp;
}
/* correct for offset */
tmp = other.center.x * axis.x + other.center.y * axis.y;
minB += tmp;
maxB += tmp;
/* test if lines intersect, if not, return false */
if (maxA < minB || minA > maxB) {
return false
} else {
let o = maxA > maxB ? maxB - minA : maxA - minB;
if (o < overlap) {
overlap = o;
smallest = { x: axis.x, y: axis.y };
}
}
}
/* test polygon B's sides */
for (side = 0; side < other.getNumberOfSides(); side++) {
/* get the axis that we will project onto */
if (side == 0) {
axis.x =
other.points[other.getNumberOfSides() - 1].y -
other.points[0].y;
axis.y =
other.points[0].x -
other.points[other.getNumberOfSides() - 1].x;
} else {
axis.x = other.points[side - 1].y - other.points[side].y;
axis.y = other.points[side].x - other.points[side - 1].x;
}
/* normalize the axis */
tmp = Math.sqrt(axis.x * axis.x + axis.y * axis.y);
axis.x /= tmp;
axis.y /= tmp;
/* project polygon A onto axis to determine the min/max */
minA = maxA = this.points[0].x * axis.x + this.points[0].y * axis.y;
for (i = 1; i < this.getNumberOfSides(); i++) {
tmp = this.points[i].x * axis.x + this.points[i].y * axis.y;
if (tmp > maxA) maxA = tmp;
else if (tmp < minA) minA = tmp;
}
/* correct for offset */
tmp = this.center.x * axis.x + this.center.y * axis.y;
minA += tmp;
maxA += tmp;
/* project polygon B onto axis to determine the min/max */
minB = maxB =
other.points[0].x * axis.x + other.points[0].y * axis.y;
for (i = 1; i < other.getNumberOfSides(); i++) {
tmp = other.points[i].x * axis.x + other.points[i].y * axis.y;
if (tmp > maxB) maxB = tmp;
else if (tmp < minB) minB = tmp;
}
/* correct for offset */
tmp = other.center.x * axis.x + other.center.y * axis.y;
minB += tmp;
maxB += tmp;
/* test if lines intersect, if not, return false */
if (maxA < minB || minA > maxB) {
return false
} else {
let o = maxA > maxB ? maxB - minA : maxA - minB;
if (o < overlap) {
overlap = o;
smallest = { x: axis.x, y: axis.y };
}
}
}
return { overlap: overlap + 0.001, axis: smallest }
}
static fromPoints(points) {
let min = { x: Number.MAX_VALUE, y: Number.MAX_VALUE };
let max = { x: Number.MIN_VALUE, y: Number.MIN_VALUE };
for (let p of points) {
min.x = Math.min(p.x, min.x);
max.x = Math.max(p.x, max.x);
min.y = Math.min(p.y, min.y);
max.y = Math.max(p.y, max.y);
}
let center = Points.mean(min, max);
let polygon = new Polygon(center);
for (let p of points) {
polygon.addAbsolutePoint(p);
}
return polygon
}
}
/* global apollo, subscriptions, gql */
/**
* A special InteractionManager for fullscreen apps, which may
* go beyond the limits of WebGL drawing buffers. On Safari and Chrome
* the drawing buffers are limited to 4096 in width (Safari) or 4096x4096
* in total buffer size (Chrome). The original InteractionManager.mapPositionToPoint
* does not work with these extreme sizes which mainly occur if large
* retina displays (>= 4K) are used with devicePixelRatio > 1.
*
* @private
* @class
* @extends PIXI.interaction.InteractionManager
* @see {@link http://pixijs.download/dev/docs/PIXI.interaction.InteractionManager.html|PIXI.interaction.InteractionManager}
* @see {@link https://stackoverflow.com/questions/29710696/webgl-drawing-buffer-size-does-not-equal-canvas-size}
*/
class FullscreenInteractionManager extends PIXI.interaction.InteractionManager {
mapPositionToPoint(point, x, y) {
let resolution = this.renderer.resolution;
let extendWidth = 1.0;
let extendHeight = 1.0;
let dy = 0;
let canvas = this.renderer.view;
let context = canvas.getContext('webgl');
if (context.drawingBufferWidth < canvas.width ||
context.drawingBufferHeight < canvas.height) {
extendWidth = context.drawingBufferWidth / canvas.width;
extendHeight = context.drawingBufferHeight / canvas.height;
//dx = wantedWidth - context.drawingBufferWidth
dy = (canvas.height - context.drawingBufferHeight) / resolution;
}
x *= extendWidth;
y *= extendHeight;
super.mapPositionToPoint(point, x, y + dy);
}
}
/**
* The class PixiApp extends the class PIXI.Application
* by several functions and makes meaningful pre-assumptions.
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 450,
* height: 150,
* fpsLogging: true,
* theme: 'light',
* transparent: false
* }).setup().run()
*
* @class
* @extends PIXI.Application
* @see {@link http://pixijs.download/dev/docs/PIXI.Application.html|PIXI.Application}
*/
class PIXIApp extends PIXI.Application {
/**
* Creates an instance of a PixiApp.
*
* @constructor
* @param {object} [opts={}] - An options object. The following options can be set:
* @param {number} [opts.width] - The width of the renderer. If no set, the application will run in fullscreen.
* @param {number} [opts.height] - The height of the renderer. If no set, the application will run in fullscreen.
* @param {HTMLElement} [opts.view] - The canvas HTML element. If not set, a render-element is added inside the body.
* @param {boolean} [opts.transparent=true] - Should the render view be transparent?
* @param {boolean} [opts.antialias=true] - Sets antialias (only applicable in chrome at the moment).
* @param {number} [opts.resolution=window.devicePixelRatio | 1] - The resolution / device pixel ratio of the renderer, retina would be 2.
* @param {boolean} [opts.autoResize=true] - Should the canvas-element be resized automatically if the resolution was set?
* @param {number} [opts.backgroundColor=0x282828] - The color of the background.
* @param {string|Theme} [opts.theme=dark] - The name of the theme (dark, light, red) or a Theme object to use for styling.
* @param {boolean} [opts.fpsLogging=false] - If set to true, the current frames per second are displayed in the upper left corner.
* @param {object} [opts.progress={}] - Can be used to add options to the progress bar. See class Progress for more informations.
* @param {boolean} [opts.forceCanvas=false] - Prevents selection of WebGL renderer, even if such is present.
* @param {boolean} [opts.roundPixels=true] - Align PIXI.DisplayObject coordinates to screen resolution.
* @param {boolean} [opts.monkeyPatchMapping=true] - Monkey patch for canvas fullscreen support on large displays.
* @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision.
*/
constructor({
width = null, height = null, view = null,
transparent = true, backgroundColor = 0x282828, theme = 'dark',
antialias = true, resolution = window.devicePixelRatio || 1, autoResize = true,
fpsLogging = false, progress = {}, forceCanvas = false, roundPixels = true, monkeyPatchMapping = true, adaptive = true,
graphql = false }) {
const fullScreen = !width || !height;
if (fullScreen) {
width = window.innerWidth;
height = window.innerHeight;
}
super({
view: view,
width: width,
height: height,
transparent: transparent,
antialias: antialias,
resolution: resolution,
autoResize: autoResize,
backgroundColor: backgroundColor,
roundPixels: roundPixels,
forceCanvas: forceCanvas
});
this.width = width;
this.height = height;
this.theme = Theme.fromString(theme);
this.fpsLogging = fpsLogging;
this.progressOpts = progress;
this.fullScreen = fullScreen;
this.orient = null;
this.originalMapPositionToPoint = null;
this.monkeyPatchMapping = monkeyPatchMapping;
PIXI.Graphics.CURVES.adaptive = adaptive;
this.graphql = graphql;
if (fullScreen || autoResize) {
console.log('App is in fullScreen mode or autoResize mode');
const resizeDebounced = debounce(event => this.resize(event), 50);
window.addEventListener('resize', resizeDebounced);
document.body.addEventListener('orientationchange', this.checkOrientation.bind(this));
}
if (monkeyPatchMapping) {
console.log('Using monkey patched coordinate mapping');
// Pluggin the specializtion does not work. Monkey patching does
// this.renderer.plugins.interaction = new FullscreenInteractionManager(this.renderer)
this.monkeyPatchPixiMapping();
}
}
/**
* Extra setup method to construct complex scenes, etc...
* Overwrite this method if you need additonal views and components.
*
* @return {PIXIApp} A reference to the PIXIApp for chaining.
*/
setup() {
this.scene = this.sceneFactory();
this.stage.addChild(this.scene);
// fpsLogging
if (this.fpsLogging) {
this.addFpsDisplay();
}
// GraphQL
if (this.graphql && typeof apollo !== 'undefined') {
const networkInterface = apollo.createNetworkInterface({
uri: '/graphql'
});
const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, {
reconnect: true,
connectionParams: {}
});
const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions(
networkInterface,
wsClient
);
this.apolloClient = new apollo.ApolloClient({
networkInterface: networkInterfaceWithSubscriptions
});
}
// progress
this._progress = new Progress(Object.assign({ theme: this.theme }, this.progressOpts, { app: this }));
this._progress.visible = false;
this.stage.addChild(this._progress);
return this
}
/**
* Tests whether the width is larger than the height of the application.
*
* @return {boolean} Returns true if app is in landscape mode.
*/
orientation() {
return this.width > this.height
}
/**
* Checks orientation and adapts view size if necessary. Implements a
* handler for the orientationchange event.
*
* @param {event=} - orientationchange event
*/
checkOrientation(event) {
var value = this.orientation();
if (value != this.orient) {
setTimeout(100, function () {
this.orientationChanged(true);
}.bind(this));
this.orient = value;
}
}
/**
* Called if checkOrientation detects an orientation change event.
*
* @param {boolean=} [force=false] - Called if checkOrientation detects an orientation change event.
*/
orientationChanged(force = false) {
if (this.expandRenderer() || force) {
this.layout();
}
}
/**
* Called after a resize. Empty method but can be overwritten to
* adapt their layout to the new app size.
*
* @param {number} [width] - The width of the app.
* @param {number} [height] - The height of the app.
*/
layout(width, height) {
}
/**
* Draws the display tree of the app. Typically this can be delegated
* to the layout method.
*
*/
draw() {
this.layout(this.width, this.height);
}
/*
* Run the application. Override this method with everything
* that is needed to maintain your App, e.g. setup calls, main loops, etc.
*
*/
run() {
return this
}
/*
* Overwrite this factory method if your application needs a special
* scene object.
*
* @returns {PIXI.Container} - A new PIXI Container for use as a scene.
*/
sceneFactory() {
return new PIXI.Container()
}
/**
* Adds the display of the frames per second to the renderer in the upper left corner.
*
* @return {PIXIApp} - Returns the PIXIApp for chaining.
*/
addFpsDisplay() {
const fpsDisplay = new FpsDisplay(this);
this.stage.addChild(fpsDisplay);
return this
}
/**
* Returns the size of the renderer as an object with the keys width and height.
*
* @readonly
* @member {object}
*/
get size() {
return { width: this.width, height: this.height }
}
/**
* Returns the center of the renderer as an object with the keys x and y.
*
* @readonly
* @member {object}
*/
get center() {
return { x: this.width / 2, y: this.height / 2 }
}
/**
* Resizes the renderer to fit into the window or given width and height.
*
* @param {object} [event] - The event.
* @param {object=} [opts={}] - The event.
* @param {number} [opts.width=window.innerWidth] - The width of the app to resize to.
* @param {number} [opts.height=window.innerHeight] - The height of the app to resize to.
* @return {PIXIApp} - Returns the PIXIApp for chaining.
*/
resize(event, { width = window.innerWidth, height = window.innerHeight } = {}) {
this.width = width;
this.height = height;
this.expandRenderer();
this.layout(width, height);
//console.log("App.resize", width, height, window.innerWidth, window.innerHeight )
// if (this.scene) {
// console.log("gl.drawingBufferWidth", this.renderer.view.getContext('webgl').drawingBufferWidth)
// console.log("scene", this.scene.scale, this.renderer, this.renderer.autoResize, this.renderer.resolution)
// }
return this
}
/**
* @todo Write the documentation.
*
* @private
*/
monkeyPatchPixiMapping() {
if (this.originalMapPositionToPoint === null) {
let interactionManager = this.renderer.plugins.interaction;
this.originalMapPositionToPoint = interactionManager.mapPositionToPoint;
interactionManager.mapPositionToPoint = (point, x, y) => {
return this.fixedMapPositionToPoint(point, x, y)
};
}
}
/**
* In some browsers the canvas is distorted if the screen resolution and
* overall size of the canvas exceeds the internal limits (e.g. 4096 x 4096 pixels).
* To compensate these distortions we need to fix the mapping to the actual
* drawing buffer coordinates.
* @private
* @param {any} local
* @param {number} x
* @param {number} y
* @return {} interactionManager.mapPositionToPoint
*/
fixedMapPositionToPoint(local, x, y) {
let resolution = this.renderer.resolution;
let interactionManager = this.renderer.plugins.interaction;
let extendWidth = 1.0;
let extendHeight = 1.0;
let dy = 0;
let canvas = this.renderer.view;
let context = canvas.getContext('webgl');
if (context !== null && (context.drawingBufferWidth < canvas.width ||
context.drawingBufferHeight < canvas.height)) {
extendWidth = context.drawingBufferWidth / canvas.width;
extendHeight = context.drawingBufferHeight / canvas.height;
//dx = wantedWidth - context.drawingBufferWidth
dy = (canvas.height - context.drawingBufferHeight) / resolution;
}
x *= extendWidth;
y *= extendHeight;
return this.originalMapPositionToPoint.call(interactionManager, local, x, y + dy)
}
/**
* Expand the renderer step-wise on resize.
*
* @param {number} [expand] - The amount of additional space for the renderer [px].
* @return {boolean} true if the renderer was resized.
*/
expandRenderer(expand = 256) {
let renderer = this.renderer;
let resolution = this.renderer.resolution;
let ww = this.width;
let hh = this.height;
let sw = this.screen.width;
let sh = this.screen.height;
if (ww > sw || hh > sh) {
//console.log('App.expandRenderer')
renderer.resize(ww + expand, hh + expand);
return true
}
renderer.resize(ww, hh);
return false
}
/**
* Set the loading progress of the application. If called for the first time, display the progress bar.
*
* @param {number} [value] - Should be a value between 0 and 100. If 100, the progress bar will disappear.
* @return {PIXIApp|Progress} The PixiApp object for chaining or the Progress object when the method was
* called without a parameter.
*/
progress(value) {
if (typeof value === 'undefined') {
return this._progress
}
this._progress.visible = true;
this._progress.progress = value;
return this
}
/**
* Opens a new Modal object binded to this app.
*
* @param {object} [opts] - An options object for the Modal object.
* @return {Modal} Returns the Modal object.
*/
modal(opts = {}) {
let modal = new Modal(Object.assign({ theme: this.theme }, opts, { app: this }));
this.scene.addChild(modal);
return modal
}
/**
* Opens a new Message object binded to this app.
*
* @param {object} [opts] - An options object for the Message object.
* @return {Message} Returns the Message object.
*/
message(opts = {}) {
let message = new Message(Object.assign({ theme: this.theme }, opts, { app: this }));
this.scene.addChild(message);
return message
}
/**
* Loads sprites, e.g. images into the PIXI TextureCache.
*
* @param {string|string[]} resources - A String or an Array of urls to the images to load.
* @param {function} [loaded] - A callback which is executed after all resources has been loaded.
* Receives one paramter, a Map of sprites where the key is the path of the image which was
* loaded and the value is the PIXI.Sprite object.
* @param {object} [opts] - An options object for more specific parameters.
* @param {boolean} [opts.resolutionDependent=true] - Should the sprites be loaded dependent of the
* renderer resolution?
* @param {boolean} [opts.progress=false] - Should a progress bar display the loading status?
* @return {PIXIApp} The PIXIApp object for chaining.
*/
loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) {
this.loadTextures(resources, textures => {
let sprites = new Map();
for (let [key, texture] of textures) {
sprites.set(key, new PIXI.Sprite(texture));
}
if (loaded) {
loaded.call(this, sprites);
}
}, { resolutionDependent, progress });
return this
}
/**
* Loads textures, e.g. images into the PIXI TextureCache.
*
* @param {string|string[]} resources - A String or an Array of urls to the images to load.
* @param {function} [loaded] - A callback which is executed after all resources has been loaded.
* Receives one paramter, a Map of textures where the key is the path of the image which was
* loaded and the value is the PIXI.Texture object.
* @param {object} [opts] - An options object for more specific parameters.
* @param {boolean} [opts.resolutionDependent=true] - Should the textures be loaded dependent of the
* renderer resolution?
* @param {boolean} [opts.progress=false] - Should a progress bar display the loading status?
* @return {PIXIApp} The PIXIApp object for chaining.
*/
loadTextures(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) {
if (!Array.isArray(resources)) {
resources = [resources];
}
const loader = this.loader;
for (let resource of resources) {
if (!loader.resources[resource]) {
if (resolutionDependent) {
let resolution = Math.round(this.renderer.resolution);
switch (resolution) {
case 2:
loader.add(resource, resource.replace(/\.([^.]*)$/, '@2x.$1'));
break
case 3:
loader.add(resource, resource.replace(/\.([^.]*)$/, '@3x.$1'));
break
default:
loader.add(resource);
break
}
} else {
loader.add(resource);
}
}
}
if (progress) {
loader.on('progress', e => {
this.progress(e.progress);
});
}
loader.load((loader, resources) => {
const textures = new Map();
for (let key in resources) {
textures.set(key, resources[key].texture);
}
if (loaded) {
loaded.call(this, textures);
}
});
return this
}
/**
* Queries the GraphQL endpoint.
*
* @param {string} [query] - The GraphQL query string.
* @param {object} [opts={}] - An options object. The following options can be set:
* http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient.query
* @return {Promise} Returns a Promise which is either resolved with the resulting data or
* rejected with an error.
*/
query(query, opts = {}) {
if (typeof query === 'string') {
opts = Object.assign({}, opts, { query });
} else {
opts = Object.assign({}, query);
}
opts.query = opts.query.trim();
if (!opts.query.startsWith('query')) {
if (opts.query.startsWith('{')) {
opts.query = `query ${opts.query}`;
} else {
opts.query = `query {${opts.query}}`;
}
}
opts.query = gql(opts.query);
return this.apolloClient.query(opts)
}
/**
* Mutate the GraphQL endpoint.
*
* @param {string} [mutation] - The GraphQL mutation string.
* @param {object} [opts={}] - An options object. The following options can be set:
* http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient.mutate
* @return {Promise} Returns a Promise which is either resolved with the resulting data or
* rejected with an error.
*/
mutate(mutation, opts = {}) {
if (typeof mutation === 'string') {
opts = Object.assign({}, opts, { mutation });
} else {
opts = Object.assign({}, mutation);
}
opts.mutation = opts.mutation.trim();
if (!opts.mutation.startsWith('mutation')) {
if (opts.mutation.startsWith('{')) {
opts.mutation = `mutation ${opts.mutation}`;
} else {
opts.mutation = `mutation {${opts.mutation}}`;
}
}
opts.mutation = gql(opts.mutation);
return this.apolloClient.mutate(opts)
}
/**
* Subscribe the GraphQL endpoint.
*
* @param {string} [subscription] - The GraphQL subscription.
* @param {object} [opts={}] - An options object. The following options can be set:
* http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient.query
* @return {Promise} Returns a Promise which is either resolved with the resulting data or
* rejected with an error.
*/
subscribe(subscription, opts = {}) {
if (typeof subscription === 'string') {
opts = Object.assign({}, opts, { subscription });
} else {
opts = Object.assign({}, subscription);
}
opts.subscription = opts.subscription.trim();
if (!opts.subscription.startsWith('subscription')) {
if (opts.subscription.startsWith('{')) {
opts.subscription = `subscription ${opts.subscription}`;
} else {
opts.subscription = `subscription {${opts.subscription}}`;
}
}
opts.query = gql(opts.subscription);
delete opts.subscription;
return this.apolloClient.subscribe(opts)
}
/**
* Supports the page as a global coordinate system and converts browser page coordinates
* to local DisplayObject coordinates.
*
* @param {DisplayObject} displayObject - The PIXI displayObject.
* @param {number} x - The x coordinate.
* @param {number} y - The y coordinate.
*
* @return {PIXI.Point} Returns a PIXI.Point.
*/
convertPointFromPageToNode(displayObject, x, y) {
let resolution = this.renderer.resolution;
console.log("resolution", resolution);
let pixiGlobal = window.convertPointFromPageToNode(app.view, x, y);
pixiGlobal.x /= resolution;
pixiGlobal.y /= resolution;
return displayObject.toLocal(new PIXI.Point(pixiGlobal.x, pixiGlobal.y))
}
/**
* Supports the page as a global coordinate system and converts local DisplayObject coordinates
* to browser page coordinates.
*
* @param {DisplayObject} displayObject - The PIXI displayObject.
* @param {number} x - The x coordinate.
* @param {number} y - The y coordinate.
*
* @return {Point} Returns a DOM Point.
*/
convertPointFromNodeToPage(displayObject, x, y) {
let resolution = this.renderer.resolution;
let pixiGlobal = displayObject.toGlobal(new PIXI.Point(x, y));
pixiGlobal.x *= resolution;
pixiGlobal.y *= resolution;
// console.log("app.convertPointFromNodeToPage", pixiGlobal)
return window.convertPointFromNodeToPage(app.view, pixiGlobal.x, pixiGlobal.y)
}
}
/**
* The class fpsdisplay shows in the upper left corner
* of the renderer the current image refresh rate.
*
* @private
* @class
* @extends PIXI.Graphics
* @see {@link http://pixijs.download/dev/docs/PIXI.Graphics.html|PIXI.Graphics}
*/
class FpsDisplay extends PIXI.Graphics {
/**
* Creates an instance of a FpsDisplay.
*
* @constructor
* @param {PIXIApp} app - The PIXIApp where the frames per second should be displayed.
*/
constructor(app) {
super();
this.app = app;
this.lineStyle(3, 0x434f4f, 1)
.beginFill(0x434f4f, .6)
.drawRoundedRect(0, 0, 68, 32, 5)
.endFill()
.position.set(20, 20);
this.text = new PIXI.Text(this.fps, new PIXI.TextStyle({
fontFamily: 'Arial',
fontSize: 14,
fontWeight: 'bold',
fill: '#f6f6f6',
stroke: '#434f4f',
strokeThickness: 3
}));
this.text.position.set(6, 6);
this.addChild(this.text);
this.refreshFps();
window.setInterval(this.refreshFps.bind(this), 1000);
}
/**
* Refreshes fps numer.
*
* @return {PIXIApp} Returns the PIXIApp object for chaining.
*/
refreshFps() {
this.text.text = `${(this.app.ticker.FPS).toFixed(1)} fps`;
return this
}
}
/**
* A Gaussian blur filter. With this filter, you can blur an area of a PIXI.DisplayObject. This cannot
* be done with the PIXI.filters.BlurFilter (when you use the PIXI.filters.BlurFilter with
* an filter area, all pixels outside of the area are not displayed). Attention: The area of
* the filter is always in global scope, NOT relative to the PIXI.DisplayObject the filter
* is assigned to!
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 480,
* height: 270,
* transparent: false
* }).setup().run()
*
* // Add a video sprite
* const sprite = new PIXI.Sprite(PIXI.Texture.fromVideo("assets/blurfilter.mp4"))
* sprite.width = app.size.width
* sprite.height = app.size.height
* app.scene.addChild(sprite)
*
* // Create the filter and assign it to the scene
* const blurFilter = new BlurFilter(new PIXI.Rectangle(20, 20, 80, 60))
* app.scene.filters = [blurFilter]
*
* @class
* @extends PIXI.Filter
* @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} shape The area where the blur effect should be applied to. Relative to the
* canvas, NOT relative to the PIXI.DisplayObject where the blur effect is assigned to!
* @param {number} [blur=50] The strength of the blur.
*/
class BlurFilter extends PIXI.Filter {
constructor(shape, blur = 50) {
super();
const normalized = this.normalize(shape);
this.tiltShiftXFilter = new TiltShiftXFilter(normalized, blur);
this.tiltShiftYFilter = new TiltShiftYFilter(normalized, blur);
}
apply(filterManager, input, output) {
let renderTarget = filterManager.getRenderTarget(true);
this.tiltShiftXFilter.apply(filterManager, input, renderTarget);
this.tiltShiftYFilter.apply(filterManager, renderTarget, output);
filterManager.returnRenderTarget(renderTarget);
}
/**
* The strength of the blur.
*
* @member {number}
*/
get blur() {
return this.tiltShiftXFilter.blur
}
set blur(value) {
this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value;
}
/**
* The blur shape.
*
* @member {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject}
*/
get shape() {
return this.tiltShiftXFilter.shape
}
set shape(value) {
this.tiltShiftXFilter.shape = this.tiltShiftYFilter.shape = this.normalize(value);
}
/**
*
* @private
* @param {PIXI.Rectangle|PIXI.Circle|PIXI.DisplayObject} value
* @returns {Object}
*/
normalize(value) {
let shape = null;
if (value instanceof PIXI.Circle) {
shape = {type: 'circle', x: value.x, y: value.y, r: value.radius};
} else if (value instanceof PIXI.Rectangle) {
shape = {type: 'rectangle', x: value.x, y: value.y, width: value.width, height: value.height};
} else {
const bounds = value.getBounds();
shape = {type: 'rectangle', x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height};
}
return shape
}
}
/**
* A TiltShiftAxisFilter.
*
* @class
* @extends PIXI.Filter
* @abstract
* @private
*/
class TiltShiftAxisFilter extends PIXI.Filter {
constructor(shape, blur){
const vertex = `
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat3 projectionMatrix;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
}
`;
const fragment = `
varying vec2 vTextureCoord;
uniform vec4 filterArea;
uniform sampler2D uSampler;
uniform int shape;
uniform vec4 rectangle;
uniform vec3 circle;
uniform float blur;
uniform vec2 delta;
uniform vec2 texSize;
float random(vec3 scale, float seed) {
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
}
void main(void) {
// textureCoord to pixelCoord
vec2 pixelCoord = vTextureCoord * filterArea.xy - vec2(4.0, 4.0); // FIXME: There's a shift of 4 * 4 pixels, don't know why...
bool inside = false;
if (shape == 1) {
inside = distance(pixelCoord, circle.xy) <= circle.z;
} else if (shape == 2) {
inside = pixelCoord.x >= rectangle.x && pixelCoord.x <= rectangle.z && pixelCoord.y >= rectangle.y && pixelCoord.y <= rectangle.w;
}
if (inside) {
vec4 color = vec4(0.0);
float total = 0.0;
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
for (float t = -30.0; t <= 30.0; t++) {
float percent = (t + offset - 0.5) / 30.0;
float weight = 1.0 - abs(percent);
vec4 sample = texture2D(uSampler, vTextureCoord + delta / texSize * percent * blur);
sample.rgb *= sample.a;
color += sample * weight;
total += weight;
}
gl_FragColor = color / total;
gl_FragColor.rgb /= gl_FragColor.a + 0.00001;
} else {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
}
`;
super(vertex, fragment);
if (shape.type === 'circle') {
this.uniforms.shape = 1;
this.uniforms.circle = [shape.x, shape.y, shape.r];
} else {
this.uniforms.shape = 2;
this.uniforms.rectangle = [shape.x, shape.y, shape.x + shape.width, shape.y + shape.height];
}
this.uniforms.blur = blur;
this.uniforms.delta = new PIXI.Point(0, 0);
this.uniforms.texSize = new PIXI.Point(480, 270);
this.updateDelta();
}
/**
* The strength of the blur.
*
* @member {number}
* @memberof PIXI.filters.TiltShiftAxisFilter#
*/
get blur() {
return this.uniforms.blur
}
set blur(value) {
this.uniforms.blur = value;
}
/**
* The blur shape.
*
* @member {PIXI.Rectangle}
* @memberof PIXI.filters.TiltShiftAxisFilter#
*/
get shape() {
if (this.uniforms.shape === 1) {
const circle = this.uniforms.circle;
return new PIXI.Circle(circle[0], circle[1], circle[2])
} else {
const rectangle = this.uniforms.rectangle;
return new PIXI.Rectangle(rectangle[0], rectangle[1], rectangle[2], rectangle[3])
}
}
set shape(value) {
if (value.type === 'circle') {
this.uniforms.shape = 1;
this.uniforms.circle = [value.x, value.y, value.r];
} else {
this.uniforms.shape = 2;
this.uniforms.rectangle = [value.x, value.y, value.x + value.width, value.y + value.height];
}
}
}
/**
* A TiltShiftXFilter.
*
* @class
* @extends PIXI.TiltShiftAxisFilter
* @private
*/
class TiltShiftXFilter extends TiltShiftAxisFilter {
/**
* Updates the filter delta values.
*/
updateDelta() {
this.uniforms.delta.x = 0.1;
this.uniforms.delta.y = 0;
}
}
/**
* A TiltShiftYFilter.
*
* @class
* @extends PIXI.TiltShiftAxisFilter
* @private
*/
class TiltShiftYFilter extends TiltShiftAxisFilter {
/**
* Updates the filter delta values.
*/
updateDelta() {
this.uniforms.delta.x = 0;
this.uniforms.delta.y = 0.1;
}
}
// In order to test this interface implementation run jsc interface.js
class Interface {
// Abstract interface that should be extended in interface subclasses.
// By convention all interfaces should start with an upper 'I'
static implementationError(klass) {
let interfaceKeys = Reflect.ownKeys(this.prototype);
let classKeys = Reflect.ownKeys(klass.prototype);
for(let key of interfaceKeys) {
let interfaceDesc = this.prototype[key];
let classDesc = klass.prototype[key];
if (typeof(classDesc) == 'undefined')
return 'Missing ' + key
}
return null
}
static implementedBy(klass) {
// In the first step only checks whether the methods of this
// interface are all implemented by the given class
let error = this.implementationError(klass);
return error == null
}
// TODO: Specify optional methods
// static optionalMethods() {
// return [this.onMouseWheel]
// }
}
/* globals Hammer, propagating */
/** Interaction patterns
See interaction.html for explanation
*/
class IInteractionTarget extends Interface {
capture(event) {
return typeof true
}
onStart(event, interaction) { }
onMove(event, interaction) { }
onEnd(event, interaction) { }
onMouseWheel(event) { }
}
class IInteractionMapperTarget extends Interface {
capture(event) {
return typeof true
}
findTarget(event, local, global) {
return IInteractionTarget
}
}
class PointMap extends MapProxy {
// Collects touch points, mouse coordinates, etc. as key value pairs.
// Keys are pointer and touch ids, the special "mouse" key.
// Values are points, i.e. all objects with numeric x and y properties.
constructor(points = {}) {
super();
for (let key in points) {
this.set(key, points[key]);
}
}
toString() {
let points = [];
for (let key of this.keys()) {
let value = this.get(key);
points.push(`${key}:{x:${value.x}, y:${value.y}}`);
}
let attrs = points.join(', ');
return `[PointMap ${attrs}]`
}
clone() {
let result = new PointMap();
for (let key of this.keys()) {
let value = this.get(key);
result.set(key, { x: value.x, y: value.y });
}
return result
}
keyOf(value) {
for (let key of this.keys()) {
let p = this.get(key);
if (p.x == value.x && p.y == value.y) {
return key
}
}
return null
}
firstKey() {
for (let key of this.keys()) {
return key
}
return null
}
first() {
for (let key of this.keys()) {
return this.get(key)
}
return null
}
farthests() {
if (this.size == 0) {
return null
}
let pairs = [];
for (let key of this.keys()) {
let p = this.get(key);
p.key = key;
for (let k of this.keys()) {
let q = this.get(k);
q.key = k;
pairs.push([p, q]);
}
}
let sorted = pairs.sort((a, b) => {
return Points.distance(b[0], b[1]) - Points.distance(a[0], a[1])
});
return sorted[0]
}
mean() {
if (this.size == 0) {
return null
}
let x = 0.0,
y = 0.0;
for (let p of this.values()) {
x += p.x;
y += p.y;
}
return { x: x / this.size, y: y / this.size }
}
}
class InteractionDelta {
constructor(x, y, zoom, rotate, about) {
this.x = x;
this.y = y;
this.zoom = zoom;
this.rotate = rotate;
this.about = about;
}
toString() {
let values = [];
for (let key of Object.keys(this)) {
let value = this[key];
if (key == 'about') {
values.push(`${key}:{x:${value.x}, y:${value.y}}`);
} else {
values.push(`${key}:${value}`);
}
}
let attrs = values.join(', ');
return `[InteractionDelta ${attrs}]`
}
}
class InteractionPoints {
constructor(parent = null) {
this.parent = parent;
this.current = new PointMap();
this.previous = new PointMap();
this.start = new PointMap();
this.ended = new PointMap();
this.timestamps = new Map();
}
moved(key) {
let current = this.current.get(key);
let previous = this.previous.get(key);
return Points.subtract(current, previous)
}
move() {
let current = this.current.mean();
let previous = this.previous.mean();
return Points.subtract(current, previous)
}
/**
* Computes the delta between previous and current angles. Corrects
* value that are larger than 45°
* @param {*} a
* @param {*} b
* @returns delta
*/
diffAngle(a, b) {
let alpha = Math.atan2(Math.sin(a - b), Math.cos(a - b));
if (Math.abs(alpha) > Math.PI / 4) {
alpha -= Math.PI;
}
return alpha
}
/**
* Computes the delta between interaction points at t and t+1.
*
* @returns InteractionDelta
* @memberof InteractionPoints
*/
delta() {
let csize = this.current.size;
let psize = this.previous.size;
if (csize >= 2 && csize == psize) {
// Reduce to the two farthests points
let current = this.current.farthests();
let c1 = current[0];
let c2 = current[1];
let p1 = this.previous.get(c1.key);
let p2 = this.previous.get(c2.key);
//let p1 = previous[0]
//let p2 = previous[1]
let d1 = Points.subtract(c1, p1);
let d2 = Points.subtract(c2, p2);
let cm = Points.mean(c1, c2);
//let pm = Points.mean(p1, p2)
// UO: Using the mean lead to jumps between time slices with 3 and 2 fingers
// We use the mean of deltas instead
let delta = Points.mean(d1, d2); //Points.subtract(cm, pm)
let zoom = 1.0;
let distance1 = Points.distance(p1, p2);
let distance2 = Points.distance(c1, c2);
if (distance1 != 0 && distance2 != 0) {
zoom = distance2 / distance1;
}
let currentAngle = Points.angle(c1, c2);
let previousAngle = Points.angle(p1, p2);
let alpha = this.diffAngle(currentAngle, previousAngle);
return new InteractionDelta(delta.x, delta.y, zoom, alpha, cm)
} else if (csize == 1 && psize == 1 && this.current.firstKey() == this.previous.firstKey()) {
// We need to ensure that the keys are the same
let current = this.current.first();
let previous = this.previous.first();
let delta = Points.subtract(current, previous);
return new InteractionDelta(delta.x, delta.y, 1.0, 0.0, current)
}
return null
}
started(key, point) {
this.current.set(key, point);
this.start.set(key, point);
this.previous.set(key, point);
this.timestamps.set(key, performance.now());
}
update(key, point) {
// Returns true iff the key is new
this.current.set(key, point);
if (!this.start.has(key)) {
this.start.set(key, point);
this.previous.set(key, point);
this.timestamps.set(key, performance.now());
return true
}
return false
}
updatePrevious() {
for (let key of this.current.keys()) {
this.previous.set(key, this.current.get(key));
}
}
stop(key, point) {
if (this.current.has(key)) {
this.current.delete(key);
this.previous.delete(key);
this.ended.set(key, point);
}
}
finish(key, point) {
this.current.delete(key);
this.previous.delete(key);
this.start.delete(key);
this.timestamps.delete(key);
this.ended.delete(key);
}
isFinished() {
return this.current.size == 0
}
isNoLongerTwoFinger() {
return this.previous.size > 1 && this.current.size < 2
}
isTap(key) {
return this.parent.isTap(key)
}
isDoubleTap(key) {
return this.parent.isDoubleTap(key)
}
isLongPress(key) {
return this.parent.isLongPress(key)
}
}
class Interaction extends InteractionPoints {
constructor(tapDistance = 10, tapDuration = 250.0, longPressTime = 500.0) {
super();
this.tapDistance = tapDistance;
this.tapCounts = new Map();
this.tapPositions = new Map();
this.tapTimestamps = new Map();
this.tapDuration = tapDuration;
this.longPressTime = longPressTime;
this.targets = new Map();
this.subInteractions = new Map(); // target:Object : InteractionPoints
}
stop(key, point) {
super.stop(key, point);
for (let points of this.subInteractions.values()) {
points.stop(key, point);
}
}
addTarget(key, target) {
this.targets.set(key, target);
this.subInteractions.set(target, new InteractionPoints(this));
}
removeTarget(key) {
let target = this.targets.get(key);
this.targets.delete(key);
// Only remove target if no keys are refering to the target
let remove = true;
for (let t of this.targets.values()) {
if (target === t) {
remove = false;
}
}
if (remove) {
this.subInteractions.delete(target);
}
}
finish(key, point) {
super.finish(key, point);
this.removeTarget(key);
}
mapInteraction(points, aspects, mappingFunc) {
// Map centrally registered points to target interactions
// Returns an array of [target, updated subInteraction] pairs
let result = new Map();
for (let key in points) {
if (this.targets.has(key)) {
let target = this.targets.get(key);
if (this.subInteractions.has(target)) {
let interaction = this.subInteractions.get(target);
for (let aspect of aspects) {
let pointMap = this[aspect];
let point = pointMap.get(key);
let mapped = mappingFunc(point, target);
interaction[aspect].set(key, mapped);
}
result.set(target, interaction);
}
}
}
return result
}
registerTap(key, point) {
if (this.tapCounts.has(key)) {
let count = this.tapCounts.get(key);
this.tapCounts.set(key, count+1);
}
else {
this.tapCounts.set(key, 1);
}
this.tapPositions.set(key, point);
this.tapTimestamps.set(key, performance.now());
}
unregisterTap(key) {
this.tapCounts.delete(key);
this.tapPositions.delete(key);
this.tapTimestamps.delete(key);
}
isTap(key) {
let ended = this.ended.get(key);
let start = this.start.get(key);
if (
start &&
ended &&
Points.distance(ended, start) < this.tapDistance
) {
let t1 = this.timestamps.get(key);
let tookLong = performance.now() > t1 + this.longPressTime;
if (tookLong) {
return false
}
return true
}
return false
}
isDoubleTap(key) {
let ended = this.ended.get(key);
if (this.tapCounts.has(key) && this.tapCounts.get(key) > 2) {
this.unregisterTap(key);
}
if (this.tapPositions.has(key)) {
let pos = this.tapPositions.get(key);
if (Points.distance(ended, pos) > this.tapDistance) {
this.unregisterTap(key);
}
}
if (this.tapTimestamps.has(key) && performance.now() > this.tapTimestamps.get(key) + this.tapDuration) {
//console.log("tap too long")
this.unregisterTap(key);
}
let result = false;
if (this.isTap(key)) {
this.registerTap(key, ended);
result = this.tapCounts.get(key) == 2;
}
else {
this.unregisterTap(key);
}
//console.log("isDoubleTap", this.tapCounts.get(key), result)
return result
}
isAnyTap() {
for (let key of this.ended.keys()) {
if (this.isTap(key)) return true
}
return false
}
isLongPress(key) {
let ended = this.ended.get(key);
let start = this.start.get(key);
if (
start &&
ended &&
Points.distance(ended, start) < this.tapDistance
) {
let t1 = this.timestamps.get(key);
let tookLong = performance.now() > t1 + this.longPressTime;
if (tookLong) {
return true
}
return false
}
return false
}
isAnyLongPress() {
for (let key of this.ended.keys()) {
if (this.isLongPress(key)) return true
}
return false
}
isStylus(key) {
return key === 'stylus'
}
}
/**
* This class implements the main delegate functionality: All necessary event handlers are registered for the
* given element. Uses PointerEvents if available or TouchEvents on iOS. The fallback is on mouse events.
* Collects the events if the interaction target captures the start event (i.e. declares that
* the target wants the start event as well as all following move and end evcents.)
*
* @export
* @class InteractionDelegate
*/
class InteractionDelegate {
// Long press: http://stackoverflow.com/questions/1930895/how-long-is-the-event-onlongpress-in-the-android
// Stylus support: https://w3c.github.io/touch-events/
/**
* Creates an instance of InteractionDelegate.
* @param {any} element
* @param {any} target
* @param {any} [{ mouseWheelElement = null, useCapture = true, capturePointerEvents = true, debug = false }={}]
* @memberof InteractionDelegate
*/
constructor(
element,
target,
{ mouseWheelElement = null, useCapture = true, capturePointerEvents = true, cancelOnWindowOut = true, debug = false } = {}
) {
this.debug = debug;
this.interaction = new Interaction();
this.element = element;
this.mouseWheelElement = mouseWheelElement || element;
this.target = target;
this.useCapture = useCapture;
this.capturePointerEvents = capturePointerEvents;
this.cancelOnWindowOut = cancelOnWindowOut;
this.setupInteraction();
}
setupInteraction() {
if (this.debug) {
let error = this.targetInterface.implementationError(
this.target.constructor
);
if (error != null) {
throw new Error('Expected IInteractionTarget: ' + error)
}
}
this.setupTouchInteraction();
this.setupMouseWheelInteraction();
}
get targetInterface() {
return IInteractionTarget
}
setupTouchInteraction() {
let element = this.element;
let useCapture = this.useCapture;
if (window.PointerEvent) {
if (this.debug) console.log('Pointer API' + window.PointerEvent);
element.addEventListener(
'pointerdown',
e => {
if (this.debug) console.log('pointerdown', e.pointerId);
if (this.capture(e)) {
if (this.capturePointerEvents) {
try {
element.setPointerCapture(e.pointerId);
} catch (e) { }
}
this.onStart(e);
}
},
useCapture
);
element.addEventListener(
'pointermove',
e => {
if (this.debug) console.log('pointermove', e.pointerId);
if (
e.pointerType == 'touch' ||
(e.pointerType == 'mouse' && Events$1.isMouseDown(e))
) {
// this.capture(e) &&
if (this.debug)
console.log('pointermove captured', e.pointerId);
this.onMove(e);
}
},
useCapture
);
element.addEventListener(
'pointerup',
e => {
if (this.debug) console.log('pointerup');
this.onEnd(e);
if (this.capturePointerEvents) {
try {
element.releasePointerCapture(e.pointerId);
} catch (e) { }
}
},
useCapture
);
element.addEventListener(
'pointercancel',
e => {
if (this.debug) console.log('pointercancel');
this.onEnd(e);
if (this.capturePointerEvents)
element.releasePointerCapture(e.pointerId);
},
useCapture
);
if (!this.capturePointerEvents) {
element.addEventListener(
'pointerleave',
e => {
if (this.debug) console.log('pointerleave');
if (e.target == element) this.onEnd(e);
},
useCapture
);
}
if (!this.capturePointerEvents) {
element.addEventListener(
'pointerout',
e => {
if (this.debug) console.log('pointerout');
if (e.target == element) this.onEnd(e);
},
useCapture
);
}
if (this.cancelOnWindowOut) {
window.addEventListener(
'pointerout',
e => {
if (e.target == element) {
this.onEnd(e);
}
},
useCapture);
}
} else if (window.TouchEvent) {
if (this.debug) console.log('Touch API');
element.addEventListener(
'touchstart',
e => {
if (this.debug)
console.log('touchstart', this.touchPoints(e));
if (this.capture(e)) {
for (let touch of e.changedTouches) {
this.onStart(touch);
}
}
},
useCapture
);
element.addEventListener(
'touchmove',
e => {
if (this.debug)
console.log('touchmove', this.touchPoints(e), e);
for (let touch of e.changedTouches) {
this.onMove(touch);
}
for (let touch of e.targetTouches) {
this.onMove(touch);
}
},
useCapture
);
element.addEventListener(
'touchend',
e => {
if (this.debug) console.log('touchend', this.touchPoints(e));
for (let touch of e.changedTouches) {
this.onEnd(touch);
}
},
useCapture
);
element.addEventListener(
'touchcancel',
e => {
if (this.debug)
console.log(
'touchcancel',
e.targetTouches.length,
e.changedTouches.length
);
for (let touch of e.changedTouches) {
this.onEnd(touch);
}
},
useCapture
);
} else {
if (this.debug) console.log('Mouse API');
element.addEventListener(
'mousedown',
e => {
if (this.debug) console.log('mousedown', e);
if (this.capture(e)) {
this.onStart(e);
}
},
useCapture
);
element.addEventListener(
'mousemove',
e => {
// Dow we only use move events if the mouse is down?
// HOver effects have to be implemented by other means
// && Events.isMouseDown(e))
if (Events$1.isMouseDown(e)) {
if (this.debug)
console.log('mousemove', e);
this.onMove(e);
}
},
useCapture
);
element.addEventListener(
'mouseup',
e => {
if (this.debug) console.log('mouseup', e);
this.onEnd(e);
},
true
);
if (!this.capturePointerEvents) {
element.addEventListener(
'mouseout',
e => {
if (e.target == element) {
this.onEnd(e);
console.warn("Shouldn't happen: mouseout ends interaction");
}
},
useCapture
);
}
if (this.cancelOnWindowOut) {
window.addEventListener(
'mouseout',
e => {
if (e.target == element) {
this.onEnd(e);
}
},
useCapture);
}
}
}
isDescendant(parent, child) {
if (parent == child) return true
let node = child.parentNode;
while (node != null) {
if (node == parent) {
return true
}
node = node.parentNode;
}
return false
}
touchPoints(event) {
let result = [];
for (let touch of event.changedTouches) {
result.push(this.extractPoint(touch));
}
return result
}
setupMouseWheelInteraction() {
this.mouseWheelElement.addEventListener(
'mousewheel',
this.onMouseWheel.bind(this),
true
);
this.mouseWheelElement.addEventListener(
'DOMMouseScroll',
this.onMouseWheel.bind(this),
true
);
}
onMouseWheel(event) {
if (this.capture(event) && this.target.onMouseWheel) {
this.target.onMouseWheel(event);
}
}
onStart(event) {
let extracted = this.extractPoint(event);
this.startInteraction(event, extracted);
this.target.onStart(event, this.interaction);
}
onMove(event) {
let extracted = this.extractPoint(event, 'all');
this.updateInteraction(event, extracted);
this.target.onMove(event, this.interaction);
this.interaction.updatePrevious();
}
onEnd(event) {
let extracted = this.extractPoint(event, 'changedTouches');
this.endInteraction(event, extracted);
this.target.onEnd(event, this.interaction);
this.finishInteraction(event, extracted);
}
/**
* Asks the target whether the event should be captured
*
* @param {any} event
* @returns {bool}
* @memberof InteractionDelegate
*/
capture(event) {
if (Events$1.isCaptured(event)) {
return false
}
let captured = this.target.capture(event);
return captured
}
getPosition(event) {
return { x: event.clientX, y: event.clientY }
}
extractPoint(event, touchEventKey = 'all') {
// 'targetTouches'
let result = {};
switch (event.constructor.name) {
case 'MouseEvent':
let buttons = event.buttons || event.which;
if (buttons) result['mouse'] = this.getPosition(event);
break
case 'PointerEvent':
result[event.pointerId.toString()] = this.getPosition(event);
break
case 'Touch':
let id =
event.touchType === 'stylus'
? 'stylus'
: event.identifier.toString();
result[id] = this.getPosition(event);
break
// case 'TouchEvent':
// // Needs to be observed: Perhaps changedTouches are all we need. If so
// // we can remove the touchEventKey default parameter
// if (touchEventKey == 'all') {
// for(let t of event.targetTouches) {
// result[t.identifier.toString()] = this.getPosition(t)
// }
// for(let t of event.changedTouches) {
// result[t.identifier.toString()] = this.getPosition(t)
// }
// }
// else {
// for(let t of event.changedTouches) {
// result[t.identifier.toString()] = this.getPosition(t)
// }
// }
// break
default:
break
}
return result
}
interactionStarted(event, key, point) {
// Callback: can be overwritten
}
interactionEnded(event, key, point) {
// Callback: can be overwritten
}
interactionFinished(event, key, point) { }
startInteraction(event, extracted) {
for (let key in extracted) {
let point = extracted[key];
this.interaction.started(key, point);
this.interactionStarted(event, key, point);
}
}
updateInteraction(event, extracted) {
for (let key in extracted) {
let point = extracted[key];
let updated = this.interaction.update(key, point);
if (updated) {
console.warn("new pointer in updateInteraction shouldn't happen");
this.interactionStarted(event, key, point);
}
}
}
endInteraction(event, ended) {
for (let key in ended) {
let point = ended[key];
this.interaction.stop(key, point);
this.interactionEnded(event, key, point);
}
}
finishInteraction(event, ended) {
for (let key in ended) {
let point = ended[key];
this.interaction.finish(key, point);
this.interactionFinished(event, key, point);
}
}
}
/**
* A special InteractionDelegate that maps events to specific parts of
* the interaction target. The InteractionTarget must implement a findTarget
* method that returns an object implementing the IInteractionTarget interface.
*
* If the InteractionTarget also implements a mapPositionToPoint method this
* is used to map the points to the local coordinate space of the the target.
*
* This makes it easier to lookup elements and relate events to local
* positions.
*
* @export
* @class InteractionMapper
* @extends {InteractionDelegate}
*/
class InteractionMapper$1 extends InteractionDelegate {
constructor(
element,
target,
{ tapDistance = 10, longPressTime = 500.0, useCapture = true, mouseWheelElement = null } = {}
) {
super(element, target, { tapDistance, useCapture, longPressTime, mouseWheelElement });
}
get targetInterface() {
return IInteractionMapperTarget
}
mapPositionToPoint(point, element = null) {
if (this.target.mapPositionToPoint) {
return this.target.mapPositionToPoint(point, element)
}
return point
}
interactionStarted(event, key, point) {
if (this.target.findTarget) {
let local = this.mapPositionToPoint(point);
let found = this.target.findTarget(event, local, point);
if (found != null) {
this.interaction.addTarget(key, found);
}
}
}
onMouseWheel(event) {
if (this.capture(event)) {
if (this.target.findTarget) {
let point = this.getPosition(event);
let local = this.mapPositionToPoint(point);
let found = this.target.findTarget(event, local, point);
if (found != null && found.onMouseWheel) {
found.onMouseWheel(event);
return
}
}
if (this.target.onMouseWheel) {
this.target.onMouseWheel(event);
}
}
}
onStart(event) {
let extracted = this.extractPoint(event);
this.startInteraction(event, extracted);
let mapped = this.interaction.mapInteraction(
extracted,
['current', 'start'],
this.mapPositionToPoint.bind(this)
);
for (let [target, interaction] of mapped.entries()) {
target.onStart(event, interaction);
}
}
onMove(event) {
let extracted = this.extractPoint(event, 'all');
this.updateInteraction(event, extracted);
let mapped = this.interaction.mapInteraction(
extracted,
['current', 'previous'],
this.mapPositionToPoint.bind(this)
);
for (let [target, interaction] of mapped.entries()) {
target.onMove(event, interaction);
interaction.updatePrevious();
}
this.interaction.updatePrevious();
}
onEnd(event) {
let extracted = this.extractPoint(event, 'changedTouches');
this.endInteraction(event, extracted);
let mapped = this.interaction.mapInteraction(
extracted,
['ended'],
this.mapPositionToPoint.bind(this)
);
for (let [target, interaction] of mapped.entries()) {
target.onEnd(event, interaction);
}
this.finishInteraction(event, extracted);
}
/**
*
*
* @static
* @param {string|array} types - An event type, an array of event types or event types seperated by a space sign. The following
* events are possible:
* pan, panstart, panmove, panend, pancancel, panleft, panright, panup, pandown
* pinch, pinchstart, pinchmove, pinchend, pinchcancel, pinchin, pinchout
* press, pressup
* rotate, rotatestart, rotatemove, rotateend, rotatecancel
* swipe, swipeleft, swiperight, swipeup, swipedown
* tap
* @param {HTMLElement|HTMLElement[]} elements - An HTML element or an array of HTML elements.
* @param {function} [cb] - The callback. A function which is executed after the event occurs. Receives the event object as the
* first paramter
* @param {object} [opts] - An options object. See the hammer documentation for more details.
*/
static on(types, elements, cb, opts = {}) {
opts = Object.assign({}, {
}, opts);
if (typeof Hammer === 'undefined') {
console.error('Hammer.js not found!');
return this
}
// convert to array
types = Array.isArray(types) ? types : types.split(/\s/);
if (elements instanceof NodeList || elements instanceof HTMLCollection) {
elements = Array.from(elements);
}
elements = Array.isArray(elements) ? elements : [elements];
for (let i = 0; i < types.length; i++) {
const type = types[i].toLowerCase();
// list of hammer events
const useHammer = /^(tap|doubletap|press|pan|swipe|pinch|rotate).*$/.test(type);
// if it is a hammer event
if (useHammer) {
for (let j = 0; j < elements.length; j++) {
// if(elements[j].tagName == "svg") return false;
let hammer = new Hammer(elements[j], opts);
if (window.propagating !== 'undefined') {
hammer = propagating(hammer);
}
// recognizers
if (type.startsWith('pan')) {
hammer.get('pan').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts));
} else if (type.startsWith('pinch')) {
hammer.get('pinch').set(Object.assign({ enable: true }, opts));
} else if (type.startsWith('press')) {
hammer.get('press').set(opts);
} else if (type.startsWith('rotate')) {
hammer.get('rotate').set(Object.assign({ enable: true }, opts));
} else if (type.startsWith('swipe')) {
hammer.get('swipe').set(Object.assign({ direction: Hammer.DIRECTION_ALL }, opts));
} else if (type.startsWith('tap')) {
hammer.get('tap').set(opts);
}
hammer.on(type, event => {
cb(event);
});
}
} else {
for (let j = 0; j < elements.length; j++) {
Hammer.on(elements[j], type, event => {
cb(event);
});
}
}
}
return this
}
}
window.InteractionMapper = InteractionMapper$1;
/** Report capabilities with guaranteed values.
*/
class Capabilities {
/** Returns the browser userAgent.
@return {string}
*/
static get userAgent() {
return navigator.userAgent || 'Unknown Agent'
}
/** Tests whether the app is running on a mobile device.
Implemented as a readonly attribute.
@return {boolean}
*/
static get isMobile() {
return (/Mobi/.test(navigator.userAgent))
}
/** Tests whether the app is running on a iOS device.
Implemented as a readonly attribute.
@return {boolean}
*/
static get isIOS() {
return (/iPad|iPhone|iPod/.test(navigator.userAgent)) && !window.MSStream
}
/** Tests whether the app is running in a Safari environment.
See https://stackoverflow.com/questions/7944460/detect-safari-browser
Implemented as a readonly attribute.
@return {boolean}
*/
static get isSafari() {
return navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS')
}
/**
* Distincts if the app is running inside electron or not.
*
* source: https://discuss.atom.io/t/detect-electron-or-web-page-running/33180/3
*/
static get isElectron() {
return typeof process != 'undefined' && process.versions && process.versions.electron !== undefined
}
/** Returns the display resolution. Necessary for retina displays.
@return {number}
*/
static get devicePixelRatio() {
return window.devicePixelRatio || 1
}
/** Returns true if the device is a multi-touch table. This method is currently not universal usable and not sure!
@return {boolean}
*/
static get isMultiTouchTable() {
return Capabilities.devicePixelRatio > 2 && Capabilities.isMobile === false && /Windows/i.test(Capabilities.userAgent)
}
/** Returns true if mouse events are supported
@return {boolean}
*/
static supportsMouseEvents() {
return typeof(window.MouseEvent) != 'undefined'
}
/** Returns true if touch events are supported
@return {boolean}
*/
static supportsTouchEvents() {
return typeof(window.TouchEvent) != 'undefined'
}
/** Returns true if pointer events are supported
@return {boolean}
*/
static supportsPointerEvents() {
return typeof(window.PointerEvent) != 'undefined'
}
/** Returns true if DOM templates are supported
@return {boolean}
*/
static supportsTemplate() {
return 'content' in document.createElement('template');
}
}
/** Basic tests for Capabilities.
*/
class CapabilitiesTests {
static testConfirm() {
let bool = confirm('Please confirm');
document.getElementById('demo').innerHTML = (bool) ? 'Confirmed' : 'Not confirmed';
}
static testPrompt() {
let person = prompt('Please enter your name', 'Harry Potter');
if (person != null) {
demo.innerHTML =
'Hello ' + person + '! How are you today?';
}
}
static testUserAgent() {
let agent = 'User-agent: ' + Capabilities.userAgent;
user_agent.innerHTML = agent;
}
static testDevicePixelRatio() {
let value = 'Device Pixel Ratio: ' + Capabilities.devicePixelRatio;
device_pixel_ratio.innerHTML = value;
}
static testMultiTouchTable() {
let value = 'Is the device a multi-touch table? ' + Capabilities.isMultiTouchTable;
multi_touch_table.innerHTML = value;
}
static testSupportedEvents() {
let events = [];
if (Capabilities.supportsMouseEvents()) {
events.push('MouseEvents');
}
if (Capabilities.supportsTouchEvents()) {
events.push('TouchEvents');
}
if (Capabilities.supportsPointerEvents()) {
events.push('PointerEvents');
}
supported_events.innerHTML = 'Supported Events: ' + events.join(', ');
}
static testAll() {
this.testUserAgent();
this.testDevicePixelRatio();
this.testMultiTouchTable();
this.testSupportedEvents();
}
}
/* Optional global variables, needed in DocTests. */
window.Capabilities = Capabilities;
window.CapabilitiesTests = CapabilitiesTests;
/**
* A base class for scatter specific events.
*
* @constructor
* @param {name} String - The name of the event
* @param {target} Object - The target of the event
*/
class BaseEvent {
constructor(name, target) {
this.name = name;
this.target = target;
}
}
// Event types
const START = 'onStart';
const UPDATE = 'onUpdate';
const END = 'onEnd';
/**
* A scatter event that describes how the scatter has changed.
*
* @constructor
* @param {target} Object - The target scatter of the event
* @param {optional} Object - Optional parameter
*/
class ScatterEvent extends BaseEvent {
constructor(
target,
{
translate = { x: 0, y: 0 },
scale = null,
rotate = 0,
about = null,
fast = false,
type = null
} = {}
) {
super('scatterTransformed', { target: target });
this.translate = translate;
this.scale = scale;
this.rotate = rotate;
this.about = about;
this.fast = fast;
this.type = type;
}
toString() {
return (
"Event('scatterTransformed', scale: " +
this.scale +
' about: ' +
this.about.x +
', ' +
this.about.y +
')'
)
}
}
/**
* A scatter resize event that describes how the scatter has changed.
*
* @constructor
* @param {target} Object - The target scatter of the event
* @param {optional} Object - Optional parameter
*/
class ResizeEvent extends BaseEvent {
constructor(target, { width = 0, height = 0 } = {}) {
super('scatterResized', { width: width, height: height });
this.width = width;
this.height = height;
}
toString() {
return (
'Event(scatterResized width: ' +
this.width +
'height: ' +
this.height +
')'
)
}
}
/**
* A abstract base class that implements the throwable behavior of a scatter
* object.
*
* @constructor
*/
class Throwable {
constructor({
movableX = true,
movableY = true,
throwVisibility = 44,
throwDamping = 0.95,
autoThrow = true,
onThrowFinished = null
} = {}) {
this.movableX = movableX;
this.movableY = movableY;
this.throwVisibility = throwVisibility;
this.throwDamping = throwDamping;
this.autoThrow = autoThrow;
this.velocities = [];
this.velocity = null;
this.timestamp = null;
this.onThrowFinished = onThrowFinished;
//console.log("onThrowFinished", onThrowFinished)
}
observeVelocity() {
this.lastframe = performance.now();
}
addVelocity(delta, buffer = 5) {
let t = performance.now();
let dt = t - this.lastframe;
this.lastframe = t;
if (dt > 0) {
// Avoid division by zero errors later on
let velocity = { t: t, dt: dt, dx: delta.x, dy: delta.y };
this.velocities.push(velocity);
while (this.velocities.length > buffer) {
this.velocities.shift();
}
}
}
meanVelocity(milliseconds = 30) {
this.addVelocity({ x: 0, y: 0 });
let sum = { x: 0, y: 0 };
let count = 0;
let t = 0;
for (let i = this.velocities.length - 1; i > 0; i--) {
let v = this.velocities[i];
t += v.dt;
let nv = { x: v.dx / v.dt, y: v.dy / v.dt };
sum = Points.add(sum, nv);
count += 1;
if (t > milliseconds) {
break
}
}
if (count === 0) return sum // empty vector
return Points.multiplyScalar(sum, 1 / count)
}
killAnimation() {
this.velocity = null;
this.velocities = [];
}
startThrow() {
this.velocity = this.meanVelocity();
if (this.velocity != null) {
// Call next velocity to ansure that specializations
// that use keepOnStage are called
this.velocity = this.nextVelocity(this.velocity);
if (this.autoThrow) this.animateThrow(performance.now());
} else {
this.onDragComplete();
}
}
animateThrow(time) {
if (this.velocity != null) {
let t = performance.now();
let dt = t - this.lastframe;
this.lastframe = t;
// console.log("animateThrow", dt)
let next = this.nextVelocity(this.velocity);
let prevLength = Points.length(this.velocity);
let nextLength = Points.length(next);
if (nextLength > prevLength) {
let factor = nextLength / prevLength;
next = Points.multiplyScalar(next, 1 / factor);
console.log('Prevent acceleration', factor, this.velocity, next);
}
this.velocity = next;
let d = Points.multiplyScalar(this.velocity, dt);
this._move(d);
this.onDragUpdate(d);
if (dt == 0 || this.needsAnimation()) {
requestAnimationFrame(this.animateThrow.bind(this));
return
} else {
if (this.isOutside()) {
requestAnimationFrame(this.animateThrow.bind(this));
return
}
}
}
this.onDragComplete();
if (this.onThrowFinished != null) {
this.onThrowFinished();
}
}
needsAnimation() {
if (this.velocity == null) {
return false
}
return Points.length(this.velocity) > 0.01
}
nextVelocity(velocity) {
// Must be overwritten: computes the changed velocity. Implement
// damping, collison detection, etc. here
let next = Points.multiplyScalar(velocity, this.throwDamping);
return {
x: (this.movableX) ? next.x : 0,
y: (this.movableY) ? next.y : 0
}
}
_move(delta) {
// Overwrite if necessary
}
onDragComplete() {
// Overwrite if necessary
}
onDragUpdate(delta) {
// Overwrite if necessary
}
}
class AbstractScatter extends Throwable {
constructor({
minScale = 0.1,
maxScale = 1.0,
startScale = 1.0,
autoBringToFront = true,
autoThrow = true,
translatable = true,
scalable = true,
rotatable = true,
resizable = false,
movableX = true,
movableY = true,
throwVisibility = 44,
throwDamping = 0.95,
overdoScaling = 1,
mouseZoomFactor = 1.1,
rotationDegrees = null,
rotation = null,
onTransform = null,
interactive = true,
onClose = null,
onThrowFinished = null,
scaleAutoClose = false,
scaleCloseThreshold = 0.10,
scaleCloseBuffer = 0.05
} = {}) {
if (rotationDegrees != null && rotation != null) {
throw new Error('Use rotationDegrees or rotation but not both')
} else if (rotation != null) {
rotationDegrees = Angle.radian2degree(rotation);
} else if (rotationDegrees == null) {
rotationDegrees = 0;
}
super({
movableX,
movableY,
throwVisibility,
throwDamping,
autoThrow,
onThrowFinished
});
/**
* Closes the card when the minScale is reached and the
* card is released. Card can be saved by scaling it up again.
*/
this.scaleAutoClose = scaleAutoClose;
this.scaleCloseThreshold = scaleCloseThreshold;
this.scaleCloseBuffer = scaleCloseBuffer;
this.scaleAutoCloseTimeout = null;
this.interactive = interactive;
this.startRotationDegrees = rotationDegrees;
this.startScale = startScale; // Needed to reset object
this.minScale = minScale;
this.maxScale = maxScale;
this.overdoScaling = overdoScaling;
this.translatable = translatable;
if (!translatable) {
this.movableX = false;
this.movableY = false;
}
this.scalable = scalable;
this.rotatable = rotatable;
this.resizable = resizable;
this.mouseZoomFactor = mouseZoomFactor;
this.autoBringToFront = autoBringToFront;
this.dragging = false;
this.onTransform = onTransform != null ? [onTransform] : null;
this.onClose = onClose != null ? [onClose] : null;
}
addCloseEventCallback(callback) {
if (this.onClose == null) {
this.onClose = [];
}
this.onClose.push(callback);
}
addTransformEventCallback(callback) {
if (this.onTransform == null) {
this.onTransform = [];
}
this.onTransform.push(callback);
}
startGesture(interaction) {
this.bringToFront();
this.killAnimation();
this.observeVelocity();
return true
}
close() {
if (this.onClose) {
this.onClose.forEach(callback => callback(this));
}
}
gesture(interaction) {
let delta = interaction.delta();
//console.log("gesture", delta)
if (delta != null) {
this.addVelocity(delta);
this.transform(delta, delta.zoom, delta.rotate, delta.about);
if (delta.zoom != 1) this.interactionAnchor = delta.about;
}
}
get polygon() {
let w2 = this.width * this.scale / 2;
let h2 = this.height * this.scale / 2;
let center = this.center;
let polygon = new Polygon(center);
polygon.addPoint({ x: -w2, y: -h2 });
polygon.addPoint({ x: w2, y: -h2 });
polygon.addPoint({ x: w2, y: h2 });
polygon.addPoint({ x: -w2, y: h2 });
polygon.rotate(this.rotation);
return polygon
}
isOutside() {
let stagePolygon = this.containerPolygon;
if (stagePolygon == null)
return false
let polygon = this.polygon;
if (polygon == null)
return false
let result = stagePolygon.intersectsWith(polygon);
return result === false || result.overlap < this.throwVisibility
}
recenter() {
// Return a small vector that guarantees that the scatter is moving
// towards the center of the stage
let center = this.center;
let target = this.container.center;
let delta = Points.subtract(target, center);
return Points.normalize(delta)
}
nextVelocity(velocity) {
return this.keepOnStage(velocity)
}
bouncing() {
// Implements the bouncing behavior of the scatter. Moves the scatter
// to the center of the stage if the scatter is outside the stage or
// not within the limits of the throwVisibility.
let stagePolygon = this.containerPolygon;
let polygon = this.polygon;
let result = stagePolygon.intersectsWith(polygon);
if (result === false || result.overlap < this.throwVisibility) {
let cv = this.recenter();
let recentered = false;
while (result === false || result.overlap < this.throwVisibility) {
polygon.center.x += cv.x;
polygon.center.y += cv.y;
this._move(cv);
result = stagePolygon.intersectsWith(polygon);
recentered = true;
}
return recentered
}
return false
}
keepOnStage(velocity, collision = 0.5) {
let stagePolygon = this.containerPolygon;
if (!stagePolygon) return
let polygon = this.polygon;
let bounced = this.bouncing();
if (bounced) {
let stage = this.containerBounds;
let x = this.center.x;
let y = this.center.y;
let dx = this.movableX ? velocity.x : 0;
let dy = this.movableY ? velocity.y : 0;
let factor = this.throwDamping;
// if (recentered) {
if (x < 0) {
dx = -dx;
factor = collision;
}
if (x > stage.width) {
dx = -dx;
factor = collision;
}
if (y < 0) {
dy = -dy;
factor = collision;
}
if (y > stage.height) {
dy = -dy;
factor = collision;
}
// }
return Points.multiplyScalar({ x: dx, y: dy }, factor)
}
return super.nextVelocity(velocity)
}
endGesture(interaction) {
this.startThrow();
this._checkAutoClose();
}
_checkAutoClose() {
if (this.scaleAutoClose)
if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) {
this.zoom(this.minScale, { animate: 0.2, onComplete: this.close.bind(this) });
} else if (this.scale < this.minScale + this.scaleCloseThreshold) {
this.zoom(this.minScale + this.scaleCloseThreshold, { animate: 0.4 });
}
}
rotateDegrees(degrees, anchor) {
let rad = Angle.degree2radian(degrees);
this.rotate(rad, anchor);
}
rotate(rad, anchor) {
this.transform({ x: 0, y: 0 }, 1.0, rad, anchor);
}
move(d, { animate = 0 } = {}) {
if (this.translatable) {
if (animate > 0) {
let startPos = this.position;
TweenLite.to(this, animate, {
x: '+=' + d.x,
y: '+=' + d.y,
/* scale: scale, uo: not defined, why was this here? */
onUpdate: e => {
let p = this.position;
let dx = p.x - startPos.x;
let dy = p.x - startPos.y;
this.onMoved(dx, dy);
}
});
} else {
this._move(d);
this.onMoved(d.x, d.y);
}
}
}
moveTo(p, { animate = 0 } = {}) {
let c = this.origin;
let delta = Points.subtract(p, c);
this.move(delta, { animate: animate });
}
centerAt(p, { animate = 0 } = {}) {
let c = this.center;
let delta = Points.subtract(p, c);
this.move(delta, { animate: animate });
}
zoom(
scale,
{
animate = 0,
about = null,
delay = 0,
x = null,
y = null,
onComplete = null
} = {}
) {
let anchor = about || this.center;
if (scale != this.scale) {
if (animate > 0) {
TweenLite.to(this, animate, {
scale: scale,
delay: delay,
onComplete: onComplete,
onUpdate: this.onZoomed.bind(this)
});
} else {
this.scale = scale;
this.onZoomed(anchor);
}
}
}
_move(delta) {
this.x += this.movableX ? delta.x : 0;
this.y += this.movableX ? delta.y : 0;
}
transform(translate, zoom, rotate, anchor) {
let delta = {
x: this.movableX ? translate.x : 0,
y: this.movableY ? translate.y : 0
};
if (this.resizable) var vzoom = zoom;
if (!this.translatable) delta = { x: 0, y: 0 };
if (!this.rotatable) rotate = 0;
if (!this.scalable) zoom = 1.0;
if (zoom == 1.0 && rotate == 0) {
this._move(delta);
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
translate: delta,
scale: this.scale,
rotate: 0,
about: anchor,
fast: false,
type: UPDATE
});
this.onTransform.forEach(function (f) {
f(event);
});
}
return
}
let origin = this.rotationOrigin;
let beta = Points.angle(origin, anchor);
let distance = Points.distance(origin, anchor);
let { scale: newScale, zoom: thresholdedZoom } = this.calculateScale(zoom);
let newOrigin = Points.arc(anchor, beta + rotate, distance * thresholdedZoom);
let extra = Points.subtract(newOrigin, origin);
let offset = Points.subtract(anchor, origin);
this._move(offset);
this.scale = newScale;
this.rotation += rotate;
offset = Points.negate(offset);
offset = Points.add(offset, extra);
offset = Points.add(offset, translate);
this._move(offset);
delta.x += extra.x;
delta.y += extra.y;
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
translate: delta,
scale: newScale,
rotate: rotate,
about: anchor
});
this.onTransform.forEach(function (f) {
f(event);
});
}
if (this.resizable) {
this.resizeAfterTransform(vzoom);
}
}
/**
* For a given zoom, a new scale is calculated, taking
* min and max scale into account.
*
* @param {number} zoom - The zoom factor, to scale the object with.
* @returns {object} - Returns an object containing the a value for a valid scale and the corrected zoom factor.
*/
calculateScale(zoom) {
let scale = this.scale * zoom;
let minScale = this.minScale / this.overdoScaling;
let maxScale = this.maxScale * this.overdoScaling;
if (scale < minScale) {
scale = minScale;
zoom = scale / this.scale;
}
if (scale > maxScale) {
scale = maxScale;
zoom = scale / this.scale;
}
if (this.scaleAutoClose)
this._updateTransparency();
return { zoom, scale }
}
_updateTransparency() {
if (this.scale < this.minScale + this.scaleCloseThreshold) {
let transparency = this.calculateScaleTransparency();
this.element.style.opacity = transparency;
} else this.element.style.opacity = 1;
}
calculateScaleTransparency() {
let transparency = (this.scale - this.minScale) / this.scaleCloseThreshold;
transparency = (transparency > 1) ? 1 : (transparency < 0) ? 0 : transparency;
return transparency
}
resizeAfterTransform(zoom) {
// Overwrite this in subclasses.
}
validScale(scale) {
scale = Math.max(scale, this.minScale);
scale = Math.min(scale, this.maxScale);
return scale
}
animateZoomBounce(dt = 1) {
if (this.zoomAnchor != null) {
let zoom = 1;
let amount = Math.min(0.01, 0.3 * dt / 100000.0);
if (this.scale < this.minScale) zoom = 1 + amount;
if (this.scale > this.maxScale) zoom = 1 - amount;
if (zoom != 1) {
this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor);
requestAnimationFrame(dt => {
this.animateZoomBounce(dt);
});
return
}
this.zoomAnchor = null;
}
}
checkScaling(about, delay = 0) {
this.zoomAnchor = about;
clearTimeout(this.animateZoomBounce.bind(this));
setTimeout(this.animateZoomBounce.bind(this), delay);
}
onMouseWheel(event) {
if (event.claimedByScatter) {
if (event.claimedByScatter != this) return
}
this.killAnimation();
this.targetScale = null;
let direction = event.detail < 0 || event.wheelDelta > 0;
let globalPoint = { x: event.clientX, y: event.clientY };
let centerPoint = this.mapPositionToContainerPoint(globalPoint);
if (event.shiftKey) {
let degrees = direction ? 5 : -5;
let rad = Angle.degree2radian(degrees);
return this.transform({ x: 0, y: 0 }, 1.0, rad, centerPoint)
}
const zoomFactor = this.mouseZoomFactor;
let zoom = direction ? zoomFactor : 1 / zoomFactor;
this.transform({ x: 0, y: 0 }, zoom, 0, centerPoint);
this.checkScaling(centerPoint, 200);
if (this.scaleAutoClose) {
if (this.scale <= this.minScale + this.scaleCloseThreshold) {
if (this.scaleAutoCloseTimeout) clearTimeout(this.scaleAutoCloseTimeout);
this.scaleAutoCloseTimeout = setTimeout(() => {
this._checkAutoClose();
}, 600);
}
this._updateTransparency();
}
//
// if (this.onTransform != null) {
// let event = new ScatterEvent(this, {
// translate: {x: 0, y: 0},
// scale: this.scale,
// rotate: 0,
// about: null,
// fast: false,
// type: ZOOM
// })
// this.onTransform.forEach(function(f) {
// f(event)
// })
// }
}
onStart(event, interaction) {
if (this.startGesture(interaction)) {
this.dragging = true;
this.interactionAnchor = null;
}
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
translate: { x: 0, y: 0 },
scale: this.scale,
rotate: 0,
about: null,
fast: false,
type: START
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
onMove(event, interaction) {
/** As long as mouseout && mouseleave interrupt we cannot be sure that
* dragging remains correct.
*/
if (this.dragging) {
this.gesture(interaction);
}
}
onEnd(event, interaction) {
//console.log("Scatter.onEnd", this.dragging)
if (interaction.isFinished()) {
this.endGesture(interaction);
this.dragging = false;
for (let key of interaction.ended.keys()) {
if (interaction.isTap(key)) {
let point = interaction.ended.get(key);
this.onTap(event, interaction, point);
}
}
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
translate: { x: 0, y: 0 },
scale: this.scale,
rotate: 0,
about: null,
fast: false,
type: END
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
let about = this.interactionAnchor;
if (about != null) {
this.checkScaling(about, 100);
}
}
onTap(event, interaction, point) { }
onDragUpdate(delta) {
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
fast: true,
translate: delta,
scale: this.scale,
about: this.currentAbout,
type: null
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
onDragComplete() {
if (this.onTransform) {
let event = new ScatterEvent(this, {
scale: this.scale,
about: this.currentAbout,
fast: false,
type: null
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
onMoved(dx, dy, about) {
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
translate: { x: dx, y: dy },
about: about,
fast: true,
type: null
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
onResizing() {
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
scale: this.scale,
fast: false,
type: null
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
onZoomed(about) {
if (this.scaleAutoClose)
this._updateTransparency();
if (this.onTransform != null) {
let event = new ScatterEvent(this, {
scale: this.scale,
about: about,
fast: false,
type: null
});
this.onTransform.forEach(function (f) {
f(event);
});
}
}
}
class DOMScatter extends AbstractScatter {
constructor(
element,
container,
{
startScale = 1.0,
minScale = 0.1,
maxScale = 1.0,
overdoScaling = 1.5,
autoBringToFront = true,
translatable = true,
scalable = true,
rotatable = true,
movableX = true,
movableY = true,
rotationDegrees = null,
rotation = null,
onTransform = null,
transformOrigin = 'center center',
// extras which are in part needed
x = 0,
y = 0,
width = null, // required
height = null, // required
resizable = false,
simulateClick = false,
verbose = true,
onResize = null,
touchAction = 'none',
throwVisibility = 44,
throwDamping = 0.95,
autoThrow = true,
scaleAutoClose = false,
onClose = null,
scaleCloseThreshold = 0.10,
scaleCloseBuffer = 0.05
} = {}
) {
super({
minScale,
maxScale,
startScale,
overdoScaling,
autoBringToFront,
translatable,
scalable,
rotatable,
movableX,
movableY,
resizable,
rotationDegrees,
rotation,
onTransform,
throwVisibility,
throwDamping,
autoThrow,
scaleAutoClose,
scaleCloseThreshold,
scaleCloseBuffer,
onClose
});
if (container == null || width == null || height == null) {
throw new Error('Invalid value: null')
}
element.scatter = this;
this.element = element;
this.x = x;
this.y = y;
this.oldX = 0;
this.oldY = 0;
this.meanX = x;
this.meanY = y;
this.width = width;
this.height = height;
this.throwVisibility = Math.min(width, height, throwVisibility);
this.container = container;
this.simulateClick = simulateClick;
this.scale = startScale;
this.rotationDegrees = this.startRotationDegrees;
this.transformOrigin = transformOrigin;
this.initialValues = {
x: x,
y: y,
width: width,
height: height,
scale: startScale,
rotation: this.startRotationDegrees,
transformOrigin: transformOrigin
};
// For tweenlite we need initial values in _gsTransform
TweenLite.set(element, this.initialValues);
this.onResize = onResize;
this.verbose = verbose;
if (touchAction !== null) {
Elements$1.setStyle(element, { touchAction });
}
this.resizeButton = null;
if (resizable) {
let button = document.createElement("div");
button.style.position = "absolute";
button.style.right = "0px";
button.style.bottom = "0px";
button.style.width = "50px";
button.style.height = "50px";
// button.style.borderRadius = "100% 0px 0px 0px";
// button.style.background = this.element.style.backgroundColor
button.className = "interactiveElement";
this.element.appendChild(button);
button.addEventListener('pointerdown', (e) => {
this.startResize(e);
});
button.addEventListener('pointermove', (e) => {
this.resize(e);
});
button.addEventListener('pointerup', (e) => {
this.stopResize(e);
});
this.resizeButton = button;
}
container.add(this);
}
/** Returns geometry data as object. **/
getState() {
return {
scale: this.scale,
x: this.x,
y: this.y,
rotation: this.rotation
}
}
close() {
super.close();
let parent = this.element.parentNode;
if (parent) parent.removeChild(this.element);
}
get rotationOrigin() {
return this.center
}
get x() {
return this._x
}
get y() {
return this._y
}
set x(value) {
this._x = value;
TweenLite.set(this.element, { x: value });
}
set y(value) {
this._y = value;
TweenLite.set(this.element, { y: value });
}
get position() {
let transform = this.element._gsTransform;
let x = transform.x;
let y = transform.y;
return { x, y }
}
get origin() {
let p = this.fromNodeToPage(0, 0);
return Points.fromPageToNode(this.container.element, p)
}
get bounds() {
let stage = this.container.element.getBoundingClientRect();
let rect = this.element.getBoundingClientRect();
return {
top: rect.top - stage.top,
left: rect.left - stage.left,
width: rect.width,
height: rect.height
}
}
get center() {
let r = this.bounds;
let w2 = r.width / 2;
let h2 = r.height / 2;
// if (this.resizable) {
// w2 *= this.scale
// h2 *= this.scale
// }
var x = r.left + w2;
var y = r.top + h2;
return { x, y }
}
set rotation(radians) {
let rad = radians; // Angle.normalize(radians)
let degrees = Angle.radian2degree(rad);
TweenLite.set(this.element, { rotation: degrees });
this._rotation = rad;
}
set rotationDegrees(degrees) {
let deg = degrees; // Angle.normalizeDegree(degrees)
TweenLite.set(this.element, { rotation: deg });
this._rotation = Angle.degree2radian(deg);
}
get rotation() {
return this._rotation
}
get rotationDegrees() {
return this._rotation
}
set scale(scale) {
TweenLite.set(this.element, {
scale: scale,
transformOrigin: this.transformOrigin
});
this._scale = scale;
}
get scale() {
return this._scale
}
get containerBounds() {
return this.container.bounds
}
get containerPolygon() {
return this.container.polygon
}
mapPositionToContainerPoint(point) {
return this.container.mapPositionToPoint(point)
}
capture(event) {
return true
}
reset() {
TweenLite.set(this.element, this.initialValues);
}
hide() {
TweenLite.to(this.element, 0.1, {
display: 'none',
onComplete: e => {
this.element.parentNode.removeChild(this.element);
}
});
}
show() {
TweenLite.set(this.element, { display: 'block' });
}
showAt(p, rotationDegrees) {
TweenLite.set(this.element, {
display: 'block',
x: p.x,
y: p.y,
rotation: rotationDegrees,
transformOrigin: this.transformOrigin
});
}
bringToFront() {
// this.element.parentNode.appendChild(this.element)
// uo: On Chome and Electon appendChild leads to flicker
TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ });
}
toggleVideo(element) {
if (element.paused) {
element.play();
} else {
element.pause();
}
}
onTap(event, interaction, point) {
if (this.simulateClick) {
let p = Points.fromPageToNode(this.element, point);
let iframe = this.element.querySelector('iframe');
if (iframe) {
let doc = iframe.contentWindow.document;
let element = doc.elementFromPoint(p.x, p.y);
if (element == null) {
return
}
switch (element.tagName) {
case 'VIDEO':
console.log(element.currentSrc);
if (PopupMenu) {
PopupMenu.open(
{
Fullscreen: () =>
window.open(element.currentSrc),
Play: () => element.play()
},
{ x, y }
);
} else {
this.toggleVideo(element);
}
break
default:
element.click();
}
}
}
}
isDescendant(parent, child) {
let node = child.parentNode;
while (node != null) {
if (node == parent) {
return true
}
node = node.parentNode;
}
return false
}
fromPageToNode(x, y) {
return Points.fromPageToNode(this.element, { x, y })
}
fromNodeToPage(x, y) {
return Points.fromNodeToPage(this.element, { x, y })
}
_move(delta) {
// UO: We need to keep TweenLite's _gsTransform and the private
// _x and _y attributes aligned
let x = this.element._gsTransform.x;
let y = this.element._gsTransform.y;
if (this.movableX) {
x += delta.x;
}
if (this.movableY) {
y += delta.y;
}
this._x = x;
this._y = y;
TweenLite.set(this.element, { x: x, y: y });
}
resizeAfterTransform(zoom) {
// let w = this.width * this.scale
// let h = this.height * this.scale
// TweenLite.set(this.element, { width: w, height: h })
if (this.onResize) {
let event = new ResizeEvent(this, { width: w, height: h });
this.onResize(event);
}
if (this.resizeButton != null) ;
}
startResize(e) {
e.preventDefault();
let event = new CustomEvent('resizeStarted');
let oldPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
this.bringToFront();
this.element.style.transformOrigin = "0% 0%";
let newPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
let offset = Points.subtract(oldPostition, newPostition);
this.oldX = e.clientX;
this.oldY = e.clientY;
e.target.setAttribute('resizing', "true");
e.target.setPointerCapture(e.pointerId);
TweenLite.to(this.element, 0, { css: { left: "+=" + offset.x + "px" } });
TweenLite.to(this.element, 0, { css: { top: "+=" + offset.y + "px" } });
this.element.dispatchEvent(event);
}
resize(e) {
e.preventDefault();
let rotation = Angle.radian2degree(this.rotation);
rotation = (rotation + 360) % 360;
let event = new CustomEvent('resized');
if (e.target.getAttribute('resizing') == "true") {
let deltaX = (e.clientX - this.oldX);
let deltaY = (e.clientY - this.oldY);
let r = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
let phi = Angle.radian2degree(Math.atan2(deltaX, deltaY));
phi = ((phi) + 630) % 360;
let rot = ((rotation + 90) + 630) % 360;
let diffAngle = ((0 + rot) + 360) % 360;
let phiCorrected = (phi + diffAngle + 360) % 360;
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
if (this.element.offsetWidth + resizeW / this.scale > this.width * 0.3 && this.element.offsetHeight + resizeH / this.scale > this.height * 0.3) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
this.oldX = e.clientX;
this.oldY = e.clientY;
this.onResizing();
this.element.dispatchEvent(event);
}
}
stopResize(e) {
e.preventDefault();
let event = new CustomEvent('resizeEnded');
let oldPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
this.element.style.transformOrigin = "50% 50%";
let newPostition = { x: $(this.element).position().left, y: $(this.element).position().top };
let offset = Points.subtract(oldPostition, newPostition);
TweenLite.to(this.element, 0, { css: { left: "+=" + offset.x + "px" } });
TweenLite.to(this.element, 0, { css: { top: "+=" + offset.y + "px" } });
e.target.setAttribute('resizing', "false");
this.element.dispatchEvent(event);
}
}
DOMScatter.zIndex = 1000;
class CardLoader {
constructor(
src,
{
x = 0,
y = 0,
width = 1000,
height = 800,
maxWidth = null,
maxHeight = null,
scale = 1,
minScale = 0.5,
maxScale = 1.5,
rotation = 0
} = {}
) {
this.src = src;
this.x = x;
this.y = y;
this.scale = scale;
this.rotation = 0;
this.maxScale = maxScale;
this.minScale = minScale;
this.wantedWidth = width;
this.wantedHeight = height;
this.maxWidth = maxWidth != null ? maxWidth : window.innerWidth;
this.maxHeight = maxHeight != null ? maxHeight : window.innerHeight;
this.addedNode = null;
console.log({
width,
height,
maxWidth,
maxHeight,
});
}
unload() {
if (this.addedNode) {
this.addedNode.remove();
this.addedNode = null;
}
}
}
class DOMFlip {
constructor(
domScatterContainer,
flipTemplate,
frontLoader,
backLoader,
{
closeOnMinScale = false,
flipDuration = 1,
fadeDuration = 0.2,
overdoScaling = 1,
autoLoad = false,
center = null,
preloadBack = false,
translatable = true,
scalable = true,
rotatable = true,
onFront = null,
onBack = null,
onClose = null,
onUpdate = null,
onRemoved = null,
onLoaded = null
} = {}
) {
this.domScatterContainer = domScatterContainer;
this.id = getId();
this.flipDuration = flipDuration;
this.fadeDuration = fadeDuration;
this.closeOnMinScale = closeOnMinScale;
this.flipTemplate = flipTemplate;
this.frontLoader = frontLoader;
this.backLoader = backLoader;
this.translatable = translatable;
this.scalable = scalable;
this.rotatable = rotatable;
this.onFrontFlipped = onFront;
this.onBackFlipped = onBack;
this.onClose = onClose;
this.onRemoved = onRemoved;
this.onUpdate = onUpdate;
this.onLoaded = onLoaded;
this.center = center;
this.preloadBack = preloadBack;
this.overdoScaling = overdoScaling;
if (autoLoad) {
this.load();
}
}
load() {
return new Promise((resolve, reject) => {
let t = this.flipTemplate;
let dom = this.domScatterContainer.element;
let wrapper = t.content.querySelector('.flipWrapper');
wrapper.id = this.id;
let clone = document.importNode(t.content, true);
dom.appendChild(clone);
// We cannot use the document fragment itself because it
// is not part of the main dom tree. After the appendChild
// call we can access the new dom element by id
this.cardWrapper = dom.querySelector('#' + this.id);
let front = this.cardWrapper.querySelector('.front');
this.frontLoader.load(front).then(loader => {
this.frontLoaded(loader).then((obj) => {
if (this.onLoaded) this.onLoaded();
resolve(this);
});
});
})
}
frontLoaded(loader) {
return new Promise((resolve, reject) => {
let scatter = new DOMScatter(
this.cardWrapper,
this.domScatterContainer,
{
x: loader.x,
y: loader.y,
startScale: loader.scale,
scale: loader.scale,
maxScale: loader.maxScale,
minScale: loader.minScale,
width: loader.wantedWidth,
height: loader.wantedHeight,
rotation: loader.rotation,
translatable: this.translatable,
scalable: this.scalable,
rotatable: this.rotatable,
overdoScaling: this.overdoScaling
}
);
if (this.center) {
scatter.centerAt(this.center);
}
if (this.closeOnMinScale) {
const removeOnMinScale = function () {
if (scatter.scale <= scatter.minScale) {
this.flippable.close();
// 'Disable' overdoscaling to avoid weird jumps on close.
scatter.minScale /= scatter.overdoScaling;
scatter.overdoScaling = 1;
//Remove callback
if (scatter.onTransform) {
let callbackIdx = scatter.onTransform.indexOf(removeOnMinScale);
scatter.onTransform.splice(callbackIdx, 1);
}
}
}.bind(this);
scatter.addTransformEventCallback(removeOnMinScale);
}
let flippable = new DOMFlippable(this.cardWrapper, scatter, this);
let back = this.cardWrapper.querySelector('.back');
if (this.preloadBack) {
this.backLoader.load(back).then(loader => {
this.setupFlippable(flippable, loader);
});
}
this.flippable = flippable;
resolve(this);
})
}
centerAt(p) {
this.center = p;
this.flippable.centerAt(p);
}
zoom(scale) {
this.flippable.zoom(scale);
}
setupFlippable(flippable, loader) {
flippable.wantedWidth = loader.wantedWidth;
flippable.wantedHeight = loader.wantedHeight;
flippable.wantedScale = loader.scale;
flippable.minScale = loader.minScale;
flippable.maxScale = loader.maxScale;
flippable.scaleButtons();
}
start({ targetCenter = null } = {}) {
console.log('DOMFlip.start', targetCenter);
if (this.preloadBack) this.flippable.start({ duration: this.flipDuration, targetCenter });
else {
let back = this.cardWrapper.querySelector('.back');
let flippable = this.flippable;
this.backLoader.load(back).then(loader => {
this.setupFlippable(flippable, loader);
flippable.start({ duration: this.flipDuration, targetCenter });
});
}
}
fadeOutAndRemove() {
TweenLite.to(this.cardWrapper, this.fadeDuration, {
opacity: 0,
onComplete: () => {
this.cardWrapper.remove();
}
});
}
closed() {
this.unload();
}
unload() {
if (!this.preloadBack) {
this.backLoader.unload();
}
}
}
class DOMFlippable {
constructor(element, scatter, flip) {
// Set log to console.log or a custom log function
// define data structures to store our touchpoints in
this.element = element;
this.flip = flip;
this.card = element.querySelector('.flipCard');
this.front = element.querySelector('.front');
this.back = element.querySelector('.back');
this.flipped = false;
this.scatter = scatter;
this.onFrontFlipped = flip.onFrontFlipped;
this.onBackFlipped = flip.onBackFlipped;
this.onClose = flip.onClose;
this.onRemoved = flip.onRemoved;
this.onUpdate = flip.onUpdate;
this.flipDuration = flip.flipDuration;
this.fadeDuration = flip.fadeDuration;
scatter.addTransformEventCallback(this.scatterTransformed.bind(this));
console.log('lib.DOMFlippable', 5000);
TweenLite.set(this.element, { perspective: 5000 });
TweenLite.set(this.card, { transformStyle: 'preserve-3d' });
TweenLite.set(this.back, { rotationY: -180 });
TweenLite.set([this.back, this.front], {
backfaceVisibility: 'hidden',
perspective: 5000
});
TweenLite.set(this.front, { visibility: 'visible' });
this.infoBtn = element.querySelector('.infoBtn');
this.backBtn = element.querySelector('.backBtn');
this.closeBtn = element.querySelector('.closeBtn');
/* Buttons are not guaranteed to exist. */
if (this.infoBtn) {
InteractionMapper$1.on('tap', this.infoBtn, event => this.flip.start());
this.enable(this.infoBtn);
}
if (this.backBtn) {
InteractionMapper$1.on('tap', this.backBtn, event => this.start());
}
if (this.closeBtn) {
InteractionMapper$1.on('tap', this.closeBtn, event => this.close());
this.enable(this.closeBtn);
}
this.scaleButtons();
this.bringToFront();
}
close() {
this.disable(this.infoBtn);
this.disable(this.closeBtn);
if (this.onClose) {
this.onClose(this);
this.flip.closed();
} else {
this.scatter.zoom(0.1, {
animate: this.fadeDuration,
onComplete: () => {
this.element.remove();
this.flip.closed();
if (this.onRemoved) {
this.onRemoved.call(this);
}
}
});
}
}
showFront() {
TweenLite.set(this.front, { visibility: 'visible' });
}
centerAt(p) {
this.scatter.centerAt(p);
}
zoom(scale) {
this.scatter.zoom(scale);
}
get buttonScale() {
let iscale = 1.0;
if (this.scatter != null) {
let scale = this.scatter.scale || 1;
iscale = 1.0 / scale;
}
return iscale
}
scaleButtons() {
//This also works for svgs.
// if (this.infoBtn)
// this.infoBtn.style.transform = "scale(" + this.buttonScale + ")"
// if (this.backBtn)
// this.backBtn.style.transform = "scale(" + this.buttonScale + ")"
// if (this.closeBtn)
// this.closeBtn.style.transform = "scale(" + this.buttonScale + ")"
console.log(this.buttonScale);
//// This did not work with svgs!
TweenLite.set([this.infoBtn, this.backBtn, this.closeBtn], {
scale: this.buttonScale
});
}
bringToFront() {
this.scatter.bringToFront();
TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ });
}
clickInfo() {
this.bringToFront();
this.infoBtn.click();
}
scatterTransformed(event) {
this.scaleButtons();
}
targetRotation(alpha) {
let ortho = 90;
let rest = alpha % ortho;
let delta = 0.0;
if (rest > ortho / 2.0) {
delta = ortho - rest;
} else {
delta = -rest;
}
return delta
}
infoValues(info) {
let startX = this.element._gsTransform.x;
let startY = this.element._gsTransform.y;
let startAngle = this.element._gsTransform.rotation;
let startScale = this.element._gsTransform.scaleX;
let w = this.element.style.width;
let h = this.element.style.height;
console.log(info, startX, startY, startAngle, startScale, w, h);
}
show(element, duration = 0, alpha = 1) {
if (element) {
TweenLite.to(element, duration, { autoAlpha: alpha }); // visibility: 'visible', display: 'initial'})
}
}
hide(element, duration = 0, alpha = 0) {
if (element) {
TweenLite.to(element, duration, { autoAlpha: alpha }); // {visibility: 'hidden', display: 'none'})
}
}
enable(button) {
this.show(button, this.fadeDuration);
if (button) {
TweenLite.set(button, { pointerEvents: 'auto' });
}
}
disable(button) {
this.hide(button, this.fadeDuration);
if (button) {
TweenLite.set(button, { pointerEvents: 'none' });
}
}
start({ targetCenter = null } = {}) {
this.bringToFront();
if (!this.flipped) {
this.startX = this.element._gsTransform.x;
this.startY = this.element._gsTransform.y;
this.startAngle = this.element._gsTransform.rotation;
this.startScale = this.element._gsTransform.scaleX;
this.startWidth = this.element.style.width;
this.startHeight = this.element.style.height;
this.scatterStartWidth = this.scatter.width;
this.scatterStartHeight = this.scatter.height;
this.show(this.back);
this.disable(this.infoBtn);
this.disable(this.closeBtn);
} else {
this.show(this.front, this.fadeDuration);
this.disable(this.backBtn);
}
let { scalable, translatable, rotatable } = this.scatter;
this.saved = { scalable, translatable, rotatable };
this.scatter.scalable = false;
this.scatter.translatable = false;
this.scatter.rotatable = false;
this.scatter.killAnimation();
this.flipped = !this.flipped;
let targetY = this.flipped ? 180 : 0;
let targetZ = this.flipped
? this.startAngle + this.targetRotation(this.startAngle)
: this.startAngle;
let targetScale = this.flipped ? this.wantedScale : this.startScale;
let w = this.flipped ? this.wantedWidth : this.startWidth;
let h = this.flipped ? this.wantedHeight : this.startHeight;
let dw = this.wantedWidth - this.scatter.width;
let dh = this.wantedHeight - this.scatter.height;
let tc = targetCenter;
let xx = tc != null ? tc.x - w / 2 : this.startX - dw / 2;
let yy = tc != null ? tc.y - h / 2 : this.startY - dh / 2;
let x = this.flipped ? xx : this.startX;
let y = this.flipped ? yy : this.startY;
console.log("DOMFlippable.start", this.flipped, targetCenter, x, y, this.saved);
let onUpdate = this.onUpdate !== null ? () => this.onUpdate(this) : null;
console.log(this.flipDuration);
TweenLite.to(this.card, this.flipDuration, {
rotationY: targetY,
ease: Power1.easeOut,
transformOrigin: '50% 50%',
onUpdate,
onComplete: e => {
if (this.flipped) {
//this.hide(this.front)
this.enable(this.backBtn);
this.show(this.backBtn);
if (this.onFrontFlipped) {
this.onFrontFlipped(this);
}
} else {
if (this.onBackFlipped == null) {
this.enable(this.infoBtn, this.fadeDuration);
this.enable(this.closeBtn, this.fadeDuration);
} else {
this.onBackFlipped(this);
}
this.flip.unload();
}
this.scatter.scale = targetScale;
this.scaleButtons();
this.scatter.rotationDegrees = targetZ;
this.scatter.width = this.flipped ? w : this.scatterStartWidth;
this.scatter.height = this.flipped ? h : this.scatterStartHeight;
let { scalable, translatable, rotatable } = this.saved;
this.scatter.scalable = scalable;
this.scatter.translatable = translatable;
this.scatter.rotatable = rotatable;
},
force3D: true
});
// See https://greensock.com/forums/topic/7997-rotate-the-shortest-way/
TweenLite.to(this.element, this.flipDuration / 2, {
scale: targetScale,
ease: Power1.easeOut,
rotationZ: targetZ + '_short',
transformOrigin: '50% 50%',
width: w,
height: h,
x: x,
y: y,
onComplete: e => {
if (this.flipped) {
this.hide(this.front);
// this.hide(this.infoBtn)
} else {
this.hide(this.back);
// this.show(this.infoBtn)
}
}
});
}
}
const deepZoomTileCache = new Map();
/** The current Tile implementation simply uses PIXI.Sprites.
*
* BTW: PIXI.extras.TilingSprite is not appropriate. It should be used for
* repeating patterns.
**/
class Tile extends PIXI.Sprite {
constructor(texture, url) {
super(texture);
this.url = url;
this.register(url);
}
static fromImage(imageId, crossorigin, scaleMode) {
return new Tile(PIXI.Texture.fromImage(imageId, crossorigin, scaleMode), imageId)
}
/**
* Registers the tile in the global reference counter for textures
*
* @param {*} url
* @param {boolean} [debug=false]
* @memberof Tile
*/
register(url, debug = false) {
if (deepZoomTileCache.has(url)) {
let tiles = deepZoomTileCache.get(url);
tiles.add(this);
if (debug) console.log("Tile.register", url, tiles.size);
}
else {
deepZoomTileCache.set(url, new Set([this]));
if (debug) console.log("Tile.register", url, 1);
}
}
/**
* Unregisters the rile in the global reference counter for textures
*
* @returns {number} The number of how often a texture is used.
* @memberof Tile
*/
unregister() {
let tiles = deepZoomTileCache.get(this.url);
tiles.delete(this);
if (tiles.size == 0) {
deepZoomTileCache.delete(this.url);
}
return tiles.size
}
/**
* Destroys this sprite and optionally its texture and children
*
* @param {*} options Part of the PIXI API, but ignored in the implementation
* @memberof Tile
*/
destroy(options, debug = false) {
if (this.parent != null) ;
let count = this.unregister();
if (count <= 0) {
let opts = { children: true, texture: true, baseTexture: true };
super.destroy(opts);
if (debug) console.log("Tile.destroy", deepZoomTileCache.size, opts);
}
else {
let opts = { children: true, texture: false, baseTexture: false };
if (debug) console.log("Tile.destroy", deepZoomTileCache.size, opts);
super.destroy(opts);
}
}
}
/**
* A Tile Loader component that can be plugged into a Tiles Layer.
*/
class TileLoader {
constructor(tiles) {
this.debug = false;
this.tiles = tiles;
this.setup();
}
/** Setup collections and instance vars. */
setup() {
this.map = new Map(); // Map {url : [ col, row]}
this.loading = new Set(); // Set url
this.loaded = new Map(); // Map {url : sprite }
this.loadQueue = [];
}
/** Schedules a tile url for loading. The loading itself must be triggered
by a call to loadOneTile or loadAll
* @param {String} url - the url of the texture / tile
* @param {Number} col - the tile col
* @param {Number} row - the tile row
**/
schedule(url, col, row) {
if (this.loaded.has(url)) return false
if (this.loading.has(url)) return false
this.map.set(url, [col, row]);
this.loading.add(url);
this.loadQueue.push(url);
return true
}
unschedule(url) {
if (this.loaded.has(url)) this.loaded.delete(url);
if (this.loading.has(url)) this.loading.delete(url);
this.loadQueue = this.loadQueue.filter(item => item != url);
}
/** Cancels loading by clearing the load queue **/
cancel() {
this.loadQueue = [];
this.loading.clear();
}
/** Destroys alls collections. **/
destroy() {
this.setup();
}
/** Private method. Informs the tile layer about a texture for a given url.
* Creates the sprite for the loaded texture and informs the tile layer.
* @param {String} url - the url
* @param {Object} texture - the loaded resource
**/
_textureAvailable(url, col, row, texture) {
let tile = this.loaded.get(url);
if (tile != null) {
console.warn("Tile already loaded");
tile.unregister();
}
tile = new Tile(texture, url);
this.loaded.set(url, tile);
this.tiles.tileAvailable(tile, col, row, url);
}
}
/**
* Uses the PIXI Loader but can be replaced with othe loaders implementing
* the public methods without underscore.
* Calls the Tiles.tileAvailable method if the texture is available.
**/
class PIXITileLoader extends TileLoader {
constructor(tiles, compression) {
super(tiles);
this.destroyed = false;
this.loader = new PIXI.loaders.Loader();
this.loader.on('load', this._onLoaded.bind(this));
this.loader.on('error', this._onError.bind(this));
if (compression) {
this.loader.pre(PIXI.compressedTextures.imageParser());
}
}
schedule(url, col, row) {
// Overwritten schedule to avoid BaseTexture and Texture already loaded errors.
if (this.loaded.has(url)) return false
if (this.loading.has(url)) return false
if (deepZoomTileCache.has(url)) {
let tiles = deepZoomTileCache.get(url);
for (let tile of tiles.values()) {
//console.log("Reusing cached texture", tile.parent)
let texture = tile.texture;
this._textureAvailable(url, col, row, texture);
return false
}
}
let texture = PIXI.utils.TextureCache[url];
if (texture) {
if (this.debug) console.log('Texture already loaded', texture);
this._textureAvailable(url, col, row, texture);
return false
}
let base = PIXI.utils.BaseTextureCache[url];
if (base) {
if (this.debug) console.log('BaseTexture already loaded', base);
let texture = new PIXI.Texture(base);
this._textureAvailable(url, col, row, texture);
return false
}
return super.schedule(url, col, row)
}
/** Load one and only one of the scheduled tiles **/
loadOneTile() {
if (this.destroyed)
return
this._loadOneTile();
}
/** Load all scheduled tiles **/
loadAll() {
if (this.destroyed)
return
this._loadAllTiles();
}
/** Destroys the loader completly **/
destroy() {
this.destroyed = true;
super.destroy();
try {
this.loader.reset();
} catch (error) {
console.warn("Error while resetting loader", error);
}
}
_onError(loader, error) {
console.warn('Cannot load', error);
}
/** Private method. Called by the PIXI loader after each successfull
* loading of a single tile.
* Creates the sprite for the loaded texture and informs the tile layer.
* @param {Object} loader - the loader instance
* @param {Object} resource - the loaded resource with url and texture attr
**/
_onLoaded(loader, resource) {
if (this.destroyed) {
let texture = resource.texture;
let destroyBase = !deepZoomTileCache.has(resource.url);
texture.destroy(destroyBase);
console.warn("Received resource after destroy", texture);
return
}
try {
let [col, row] = this.map.get(resource.url);
this._textureAvailable(resource.url, col, row, resource.texture);
}
catch (err) {
console.warn("Texture unavailable: " + err.message);
}
}
/** Private method: loads one tile from the queue. **/
_loadOneTile(retry = 1) {
//console.log("_loadOneTile")
if (this.destroyed) {
//console.warn("_loadOneTile after destroy")
return
}
if (this.loader.loading) {
setTimeout(() => {
this._loadOneTile();
}, retry);
return
}
if (this.loadQueue.length > 0) {
let url = this.loadQueue.pop();
this.loader.add(url, url);
this.loader.load();
}
}
/** Private method: loads all tiles from the queue in batches. Batches are
helpfull to avoid loading tiles that are no longer needed because the
user has already zoomed to a different level.**/
_loadAllTiles(batchSize = 8, retry = 16) {
if (this.destroyed) {
return
}
if (this.loadQueue.length > 0) {
if (this.loader.loading) {
//console.log("Loader busy", this.loadQueue.length)
setTimeout(() => {
this._loadAllTiles();
}, retry);
return
}
let i = 0;
let urls = [];
while (i < batchSize && this.loadQueue.length > 0) {
let url = this.loadQueue.pop();
if (!this.loaded.has(url)) {
let resource = this.loader.resources[url];
if (resource) {
console.log("Resource already added", url);
}
else {
urls.push(url);
i += 1;
}
}
}
this.loader.add(urls).load(() => {
this._loadAllTiles();
});
}
}
}
/**
* Uses Workers but can be replaced with other loaders implementing
* the public methods without underscore.
* Calls the Tiles.tileAvailable method if the texture is available.
**/
class WorkerTileLoader extends TileLoader {
constructor(tiles) {
super(tiles);
let worker = this.worker = new Worker("../../lib/pixi/deepzoom/tileloader.js");
worker.onmessage = (event) => {
if (event.data.success) {
let { url, col, row, buffer } = event.data;
//console.log("WorkerTileLoader.loaded", url, buffer)
let CompressedImage = PIXI.compressedTextures.CompressedImage;
let compressed = CompressedImage.loadFromArrayBuffer(buffer, url);
let base = new PIXI.BaseTexture(compressed);
let texture = new PIXI.Texture(base);
this._textureAvailable(url, col, row, texture);
}
};
}
loadOne() {
if (this.loadQueue.length > 0) {
let url = this.loadQueue.pop();
let [col, row] = this.map.get(url);
let tile = [col, row, url];
this.worker.postMessage({ command: "load", tiles: [tile] });
}
}
loadAll() {
let tiles = [];
while (this.loadQueue.length > 0) {
let url = this.loadQueue.pop();
let [col, row] = this.map.get(url);
tiles.push([col, row, url]);
}
this.worker.postMessage({ command: "load", tiles });
}
cancel() {
super.cancel();
this.worker.postMessage({ command: "abort" });
}
destroy() {
this.worker.postMessage({ command: "abort" });
this.worker.terminate();
this.worker = null;
super.destroy();
}
}
/**
* A layer of tiles that represents a zoom level of a DeepZoomImage as a grid
* of sprites.
* @constructor
* @param {number} level - the zoom level of the tile layer
* @param {DeepZoomImage} view - the zoomable image the layer belongs to
* @param {number} scale - the scale of the tile layer
* @param {number} cols - the number of columns of the layer
* @param {number} rows - the number of rows of the layer
* @param {number} width - the width of the layer in pixel
* @param {number} height - the height of the layer in pixel
* @param {number} tileSize - the size of a single tile in pixel
* @param {number} overlap - the overlap of the tiles in pixel
* @param {number} fadeInTime - time needed to fade in tiles if TweenLite is set
**/
class Tiles extends PIXI.Container {
constructor(
level,
view,
scale,
cols,
rows,
width,
height,
tileSize,
overlap,
fadeInTime = 0.33
) {
super();
this.debug = false;
this.showGrid = false;
this.view = view;
this.level = level;
this.cols = cols;
this.rows = rows;
this.pixelWidth = width;
this.pixelHeight = height;
this.tileSize = tileSize;
this.overlap = overlap;
this.needed = new Map(); // url as key, [col, row] as value
this.requested = new Set();
this.available = new Map();
this.scale.set(scale, scale);
this.tileScale = scale;
this.fadeInTime = fadeInTime;
this.keep = false;
if (this.view.preferWorker && view.info.compression.length > 0)
this.loader = new WorkerTileLoader(this);
else
this.loader = new PIXITileLoader(this, view.info.compression);
this.interactive = false;
this._highlight = null;
this._info = null;
this._centerPoint = null;
this._boundsRect = null;
this.infoColor = Colors.random();
this.pprint();
this.destroyed = false;
}
/** Tests whether all tiles are loaded. **/
isComplete() {
return this.cols * this.rows === this.children.length
}
/** Returns the highligh graphics layer for debugging purposes.
**/
get highlight() {
if (this._highlight == null) {
let graphics = new PIXI.Graphics();
graphics.beginFill(0xffff00, 0.1);
graphics.lineStyle(2, 0xffff00);
graphics.drawRect(1, 1, this.tileSize - 2, this.tileSize - 2);
graphics.endFill();
graphics.interactive = false;
this._highlight = graphics;
}
return this._highlight
}
/** Returns the highligh graphics layer for debugging purposes.
**/
get info() {
if (this._info == null) {
let graphics = new PIXI.Graphics();
graphics.lineStyle(4, 0xff0000);
graphics.interactive = false;
this._info = graphics;
this.addChild(this._info);
}
return this._info
}
/** Helper method pretty printing debug information. **/
pprint() {
if (this.debug)
console.log(
'Tiles level: ' +
this.level +
' scale: ' +
this.scale.x +
' cols: ' +
this.cols +
' rows: ' +
this.rows +
' w: ' +
this.pixelWidth +
' h: ' +
this.pixelHeight +
' tsize:' +
this.tileSize
);
}
/** Computes the tile position and obeys the overlap.
* @param {number} col - The column of the tile
* @param {number} row - The row of the tile
* @returns {PIXI.Point} obj
**/
tilePosition(col, row) {
let x = col * this.tileSize;
let y = row * this.tileSize;
let overlap = this.overlap;
if (col != 0) {
x -= overlap;
}
if (row != 0) {
y -= overlap;
}
return new PIXI.Point(x, y)
}
/** Computes the tile size without overlap
* @param {number} col - The column of the tile
* @param {number} row - The row of the tile
* @returns {PIXI.Point} obj
**/
tileDimensions(col, row) {
let w = this.tileSize;
let h = this.tileSize;
let pos = this.tilePosition(col, row);
if (col == this.cols - 1) {
w = this.pixelWidth - pos.x;
}
if (row == this.rows - 1) {
h = this.pixelHeight - pos.y;
}
return new PIXI.Point(w, h)
}
/** Method to support debugging. Highlights the specified tile at col, row **/
highlightTile(col, row) {
if (col > -1 && row > -1 && col < this.cols && row < this.rows) {
let graphics = this.highlight;
let dim = this.tileDimensions(col, row);
graphics.position = this.tilePosition(col, row);
graphics.clear();
graphics.beginFill(0xff00ff, 0.1);
graphics.lineStyle(2, 0xffff00);
graphics.drawRect(1, 1, dim.x - 2, dim.y - 2);
graphics.endFill();
this.addChild(this.highlight);
} else {
this.removeChild(this.highlight);
}
}
/** Loads the tiles for the given urls and adds the tiles as sprites.
* @param {array} urlpos - An array of URL, pos pairs
* @param {boolean} onlyone - Loads only on tile at a time if true
**/
loadTiles(urlpos, onlyone, refCol, refRow) {
if (this.showGrid) {
this.highlightTile(refCol, refRow);
}
urlpos.forEach(d => {
let [url, col, row] = d;
if (this.loader.schedule(url, col, row)) {
if (onlyone) {
return this.loader.loadOneTile()
}
}
});
this.loader.loadAll();
}
/** Private method: add a red border to a tile for debugging purposes. **/
_addTileBorder(tile, col, row) {
let dim = this.tileDimensions(col, row);
let graphics = new PIXI.Graphics();
graphics.beginFill(0, 0);
graphics.lineStyle(2, 0xff0000);
graphics.drawRect(1, 1, dim.x - 2, dim.y - 2);
graphics.endFill();
tile.addChild(graphics);
}
/** Adds a tile. **/
addTile(tile, col, row, url) {
if (this.available.has(url)) {
console.warn('Trying to add available tile');
return
}
this.addChildAt(tile, 0);
this.available.set(url, tile);
if (this.destroyed) {
console.warn('Adding to destroyed tiles layer');
}
// this._addTileBorder(tile, col, row)
}
/** Called by the loader after each successfull loading of a single tile.
* Adds the sprite to the tile layer.
* @param {Object} tile - the loaded tile sprite
* @param {Number} col - the col position
* @param {Number} row - the rowposition
**/
tileAvailable(tile, col, row, url) {
let pos = this.tilePosition(col, row);
if (this.showGrid) {
this._addTileBorder(tile, col, row);
}
tile.position = pos;
tile.interactive = false;
if (TweenLite) {
tile.alpha = 0;
TweenLite.to(tile, this.fadeInTime, { alpha: this.alpha });
}
this.addTile(tile, col, row, url);
}
/** Destroys the tiles layer and destroys the loader. Async load calls are
* cancelled.
**/
destroy() {
this.destroyed = true;
this.loader.destroy();
super.destroy({ children: true }); // Calls destroyChildren
this.available.clear();
this.requested.clear();
this.needed.clear();
}
destroyTile(url, tile) {
this.loader.unschedule(url);
this.removeChild(tile);
tile.destroy();
this.available.delete(url);
}
destroyTileByUrl(url) {
if (this.available.has(url)) {
let tile = this.available.get(url);
this.destroyTile(url, tile);
}
}
/* Destroys the tiles which are not with the bounds of the app to free
* memory.
**/
destroyTiles(quadTrees) {
let count = 0;
for (let [url, tile] of this.available.entries()) {
if (!quadTrees.has(url)) {
this.destroyTile(url, tile);
count += 1;
}
}
if (count && this.debug)
console.log('destroyTiles', this.level, count);
}
destroyUnneededTiles() {
let count = 0;
for (let [url, tile] of this.available.entries()) {
if (!this.needed.has(url)) {
this.destroyTile(url, tile);
count += 1;
}
}
if (count && this.debug)
console.log('destroyUnneededTiles', this.level, count);
}
highlightInfos() {
let graphics = this.info;
let color = this.infoColor;
graphics.clear();
graphics.lineStyle(2, color);
for (let [col, row] of this.needed.values()) {
let dim = this.tileDimensions(col, row);
let pos = this.tilePosition(col, row);
graphics.beginFill(color, 0.2);
graphics.drawRect(pos.x + 1, pos.y + 1, dim.x - 2, dim.y - 2);
graphics.endFill();
}
let r = this._boundsRect;
if (r != null) {
graphics.lineStyle(20, color);
graphics.drawRect(r.x, r.y, r.width, r.height);
graphics.moveTo(r.x, r.y);
graphics.lineTo(r.x + r.width, r.y + r.height);
graphics.moveTo(r.x, r.y + r.height);
graphics.lineTo(r.x + r.width, r.y);
}
let p = this._centerPoint;
if (p != null) {
graphics.drawCircle(p.x, p.y, 20);
}
}
tintTiles(quadTrees) {
for (let [url, tile] of this.available.entries()) {
if (!quadTrees.has(url)) tile.tint = 0xff0000;
}
}
untintTiles() {
for (let [url, tile] of this.available.entries()) {
tile.tint = 0xffffff;
}
}
}
function isEven(n) {
return n % 2 == 0
}
function printTileCacheInfos() {
let references = new Map();
let multiples = 0;
for (let [url, tiles] of deepZoomTileCache.entries()) {
let count = tiles.size;
references.set(url, count);
if (count > 1) {
multiples += 1;
}
}
console.log({ multiples, references });
}
/**
* A utility class that holds information typically provided by DZI files, i.e.
* height and width of the overall image, overlap, and image type.
*
* @constructor
* @param {obj} attrs - A JSON-Object holding the listed keys and values
* @example
* {
* "tileSize": 1024,
* "format": "jpeg",
* "overlap": 1,
* "height": 4794,
* "width": 4095,
* "clip": { "minLevel": 12, "maxLevel": 20, "startCol": 301436, "startRow": 354060 },
* // optional: minLevel and maxLevel define the level bounds
* // startCol: first col at maxLevel
* // startRow: first row at maxLevel
* "path": "var/Vermeer/Vermeer_files",
* "type": "dzi", // optional: dzi (default) or map
* "urlTileTemplate": "{path}/{level}/{column}/{row}.{format}"
* // optional: {path}/{level}/{column}_{row}.{format} (default) or
* // a template String with the format of the URL
* }
*/
class DeepZoomInfo {
constructor(attrs) {
for (let key in attrs) {
this[key] = attrs[key];
}
this.maxLevel = 0; // The highest level number, typically corresponds to the
// number in the file system for the folder with tiles
this.clip = this.clip || null; // e.g. { level: 12, col: 301436, row: 354060 }
this.type = this.type || 'dzi';
this.urlTileTemplate =
this.urlTileTemplate || '{path}/{level}/{column}_{row}.{format}';
this.setupDimensions();
}
/* Computes the needed number of layers from the width and height
* of the image. Note that this includes the level 0, i.e. 0 ... 4
* means that 5 levels exist.
**/
numLevels() {
let maxDimension = Math.max(this.width, this.height);
let boundary = this.type === 'dzi' ? 1 : this.tileSize;
let numLevels = 0;
while (maxDimension >= boundary) {
maxDimension /= 2;
numLevels++;
}
return numLevels
}
/** Computes the scale at the given level.
* @param {number} level - The level of the wanted layer
* @returns {number} scale
**/
getScale(level) {
let scale = 1;
if (this.type === 'dzi') {
scale = Math.pow(0.5, this.maxLevel - level + 1);
} else {
scale = Math.pow(0.5, this.maxLevel - level);
}
return scale
}
/** Computes the scaled width and height of the given level.
* @param {number} level - The level of the wanted layer
* @returns {array} size - The width and height
**/
getDimensions(level) {
let scale = this.getScale(level);
let w = Math.ceil(this.width * scale);
let h = Math.ceil(this.height * scale);
return [w, h]
}
/** Computes the number of cols and rows of tiles.
* @param {number} level - The level of the wanted layer
* @returns {array} size - The cols and rows
**/
getNumTiles(level) {
let dim = this.getDimensions(level);
let cols = Math.ceil(dim[0] / this.tileSize);
let rows = Math.ceil(dim[1] / this.tileSize);
if (this.clip) {
let rest = this.rests[level];
if (rest) {
if (rest.restCol) {
cols += 1;
}
if (rest.restRows) {
rows += 1;
}
}
}
return [cols, rows]
}
setupDimensions(loadBaseImage = false) {
/** Setup instance variables and load the base image, i.e. the largest
image that can be represented as a single tile.
@private
**/
let ww = this.width;
let hh = this.height;
let scale = 1.0;
let level = 0;
let single = 0;
const tsize = this.tileSize;
if (this.clip) {
this.baseLevel = this.clip.minLevel;
this.maxLevel = this.clip.maxLevel;
this.baseImage = null;
this.size = this.getDimensions(this.baseLevel);
this.offsets = {};
this.rests = {};
let startCol = this.clip.startCol;
let startRow = this.clip.startRow;
let floatStartCol = startCol;
let floatStartRow = startRow;
for (let i = this.maxLevel; i >= this.baseLevel; i--) {
this.offsets[i] = { startCol, startRow };
let restCol = floatStartCol % 1;
let restRow = floatStartRow % 1;
this.rests[i] = { restCol, restRow };
startCol = Math.floor(startCol / 2);
startRow = Math.floor(startRow / 2);
floatStartCol /= 2;
floatStartRow /= 2;
}
} else {
const boundary = this.type === 'dzi' ? 1.0 : tsize;
while (ww > boundary && hh > boundary) {
if (ww >= tsize && hh >= tsize) {
single += 1;
}
scale = scale / 2.0;
ww = Math.ceil(this.width * scale);
hh = Math.ceil(this.height * scale);
level += 1;
}
this.baseLevel = level - single;
this.maxLevel = this.numLevels() - 1;
this.baseURL = this.urlForTile(this.baseLevel, 0, 0, false);
if (loadBaseImage) {
this.imageForURL(this.baseURL, e => {
this.size = [e.target.naturalWidth, e.target.naturalHeight];
this.baseImage = e.target;
});
} else {
this.baseImage = null;
this.size = this.getDimensions(this.baseLevel);
}
}
}
get maxLoadableLevel() {
if (this.clip) {
return this.maxLevel
}
return this.type === 'dzi' ? this.maxLevel : this.maxLevel
}
/** Computes the url for the given level, column and and row.
* @param {number} level - The level of the wanted layer
* @param {number} column - The column of the tile
* @param {number} row - The row of the tile
* @returns {string} url
**/
urlForTile(level, column, row, compressed = true) {
let format = this.format;
if (compressed && this.compression) {
let supported = Capabilities.isIOS ? 'pvr' : 'dds';
if (this.compression.indexOf(supported) >= 0) {
format = supported;
}
}
if (this.clip) {
let offset = this.offsets[level];
if (offset) {
let { startCol, startRow } = offset;
column += startCol;
row += startRow;
}
}
let url = this.urlTileTemplate
.replace(/\{path\}/g, this.path)
.replace(/\{level\}/g, level)
.replace(/\{row\}/g, row)
.replace(/\{column\}/g, column)
.replace(/\{format\}/g, format);
return url
}
/** Loads the image for the given url and executes a callback function
on completion.
* @param {string} url - The url of the tile
* @param {function} complete - The callback function
* @returns {Image} obj
**/
imageForURL(url, complete) {
let img = new Image();
img.onload = complete.bind(this);
img.src = url;
return img
}
/** Computes the columns and rows as well as scaled width and height.
* @param {number} level - The level of the wanted layer
* @returns {array} [cols, rows, width, height]
**/
dimensions(level) {
let dim = this.getDimensions(level);
let tiles = this.getNumTiles(level);
return [tiles[0], tiles[1], dim[0], dim[1]]
}
test() {
//console.log("w=" + this.width + " h=" + this.height + " maxlevel=" + this.maxLevel + " base=" + this.baseLevel)
for (let i = 0; i <= this.maxLevel; i++) {
console.log(
' ' +
i +
' -> ' +
this.getScale(i) +
' [' +
this.dimensions(i) +
']'
);
}
console.log(this.urlForTile(this.baseLevel, 0, 0));
}
}
/**
* A utility class that describes a quad tree of tiles. Each tile on a given
* level has up to four corresponding tiles on the next level. A TileQuadNode
* uses the attributes nw (i.e. northwest), ne, sw, se to link to the
* quad nodes on the next level. The previous attributes links to the quad
* one level below that holds the given quad as nw, ne, sw, or se.
* We use this node class because we need a representation of tiles that are
* needed but not loaded yet to compute tiles which can be abandoned to reduce
* the memory pressure.
*
* @constructor
* @param {level} Number - The level the quad node belongs to
* @param {col} Number - The col of the quad
* @param {row} Number - The level the quad node belongs to
* @param {url} String - The level the quad node belongs to
*/
class TileQuadNode {
constructor(level, col, row, url) {
this.level = level;
this.col = col;
this.row = row;
this.url = url;
this.nw = null;
this.ne = null;
this.sw = null;
this.se = null;
this.previous = null;
}
/** Return True if this node has no successors and can be used as
an indicator of tiles to free.
**/
noQuads() {
if (this.previous === null) return false
return (
this.nw === null &&
this.ne === null &&
this.sw === null &&
this.se === null
)
}
/** Unlink the given quad node
* @param {node} TileQuadNode - The TileQuadNode to remove
**/
unlink(node) {
if (this.nw === node) this.nw = null;
if (this.ne === node) this.ne = null;
if (this.sw === node) this.sw = null;
if (this.se === node) this.se = null;
}
/** Link this quad node to the given previous node. Use the north
* and west flags to address nw, ne, sw, and se.
* @param {node} TileQuadNode - The TileQuadNode to remove
* @param {north} Boolean - Link to north (true) or south (false)
* @param {west} Boolean - Link to west (true) or east (false)
**/
link(north, west, previous) {
this.previous = previous;
if (north) {
if (west) {
previous.nw = this;
} else {
previous.ne = this;
}
} else {
if (west) {
previous.sw = this;
} else {
previous.se = this;
}
}
}
}
/**
* The main class of a deeply zoomable image that is represented by a hierarchy
* of tile layers for each zoom level. This gives the user the impression that
* even huge pictures (up to gigapixel-images) can be zoomed instantaneously,
* since the tiles at smaller levels are scaled immediately and overloaded by
* more detailed tiles at the larger level as fast as possible.
* @constructor
* @param {DeepZoomInfo} deepZoomInfo - Information extracted from a JSON-Object
*/
class DeepZoomImage extends PIXI.Container {
constructor(
deepZoomInfo,
{
debug = false,
shadow = false,
center = false,
world = null, // Defines the world bounds the images lives in
highResolution = true,
autoLoadTiles = true,
preferWorker = false,
minimumLevel = 0,
alpha = 1,
app = window.app
} = {}
) {
super();
this.app = app;
this.debug = debug;
this.shadow = shadow;
this.world = world;
this.preferWorker = preferWorker;
this.resolution = highResolution
? Math.round(window.devicePixelRatio)
: 1;
this.alpha = alpha;
this.fastLoads = 0;
this.autoLoadTiles = autoLoadTiles;
this.minimumLevel = minimumLevel;
this.quadTrees = new Map(); // url as keys, TileQuadNodes as values
this.setup(deepZoomInfo, center);
}
get point() {
if (this._point == null) {
let graphics = new PIXI.Graphics();
graphics.lineStyle(2, 0x00ff00);
graphics.drawCircle(0, 0, 2);
graphics.interactive = false;
this._point = graphics;
}
return this._point
}
/** Reads the DeepZoomInfo object and initializes all tile layers.
* Called by the constructor.
* Creates the sprite for the loaded texture and add the sprite to the tile
* layer.
* @param {Object} deepZoomInfo - the DeepZoomInfo instance
* @param {boolean} center - If true ensures that the pivot is set to the center
**/
setup(deepZoomInfo, center) {
this.info = deepZoomInfo;
this.interactive = true;
this.tileLayers = {};
this._foreground = null;
this.tileContainer = new PIXI.Container();
this.tileContainer.interactive = false;
let [w, h] = this.baseSize;
if (this.shadow) {
this.filters = [new PIXI.filters.DropShadowFilter(45, 3)];
}
this.addChild(this.tileContainer);
if (deepZoomInfo.clip) {
let mask = new PIXI.Graphics();
mask.beginFill(1, 1);
mask.drawRect(0, 0, w, h);
mask.endFill();
this.mask = mask;
mask.alpha = 0;
this.addChild(mask);
this.minimumLevel = deepZoomInfo.baseLevel;
}
this.currentLevel = Math.max(this.minimumLevel, deepZoomInfo.baseLevel);
console.log("autoLoadTiles", this.autoLoadTiles);
if (this.autoLoadTiles) {
this.setupTiles(center);
}
}
/** Default setup method for tiles. Loads all tiles of the current level.
Can be overwritten in subclasses.
@param {boolean} center - If true ensures that the pivot is set to the center
**/
setupTiles(center = false) {
// First load background tile
let tiles = this.ensureAllTiles(this.currentLevel);
if (center) {
this.pivot.set(w / 2, h / 2);
}
let scaleLevel = this.levelForScale(1);
this.ensureAllTiles(scaleLevel);
}
removeTileQuadNode(level, col, row, url) {
if (this.quadTrees.has(url)) {
let quad = this.quadTrees.get(url);
this.tileQuadRemoved(quad);
this.quadTrees.delete(url);
}
}
addTileQuadNode(level, col, row, url) {
if (this.quadTrees.has(url)) return this.quadTrees.get(url)
let quad = new TileQuadNode(level, col, row, url);
this.quadTrees.set(url, quad);
this.tileQuadAdded(quad);
return quad
}
tileQuadRemoved(quad) {
let below = quad.previous;
// if (this.debug) console.log("tileQuadRemoved", quad)
if (below) {
below.unlink(quad);
if (below.noQuads()) {
if (this.debug) console.log('Removed tile below');
let levelBelow = quad.level - 1;
if (levelBelow < this.minimumLevel) return
let c = Math.floor(quad.col / 2);
let r = Math.floor(quad.row / 2);
let urlBelow = this.info.urlForTile(levelBelow, c, r);
if (this.quadTrees.has(urlBelow)) {
this.removeTileQuadNode(levelBelow, c, r, urlBelow);
}
}
}
}
tileQuadAdded(quad) {
let levelBelow = quad.level - 1;
if (levelBelow < this.minimumLevel) return
//if (this.debug) console.log("tileQuadAdded", quad)
let c = Math.floor(quad.col / 2);
let r = Math.floor(quad.row / 2);
let urlBelow = this.info.urlForTile(levelBelow, c, r);
let below = null;
if (!this.quadTrees.has(urlBelow)) {
below = this.addTileQuadNode(levelBelow, c, r, urlBelow);
quad.link(isEven(quad.row), isEven(quad.col), below);
}
}
/** Returns the tile layer level that corresponds to the given scale.
* @param {number} scale - the scale factor
**/
levelForScale(scale) {
let level = Math.round(Math.log2(scale * this.resolution)); // Math.floor(Math.log2(event.scale))+1
let newLevel = this.info.baseLevel + Math.max(level, 0);
return Math.min(newLevel, this.info.maxLoadableLevel)
}
/** Returns the tile layer level that corresponds to the given scale.
* @param {number} scale - the scale factor
**/
levelAndAlphaForScale(scale) {
let value = Math.log2(scale * this.resolution);
let level = Math.round(value);
let newLevel = this.info.baseLevel + Math.max(level, 0);
return { level: Math.min(newLevel, this.info.maxLoadableLevel), alpha: value - level }
}
/** Adds a tile layer to the DeepZoomImage.
* @param {string} key - the access key
* @param {Tiles} tiles - the tile layer object
**/
addTiles(key, tiles) {
if (key in this.tileLayers) {
console.warn('Tiles already availabl', key);
}
this.tileContainer.addChild(tiles);
this.tileLayers[key] = tiles;
}
destroyTiles(key) {
let tiles = this.tileLayers[key];
this.tileContainer.removeChild(tiles);
tiles.destroy();
delete this.tileLayers[key];
}
/** Getter for PIXI.Container foreground layer.
* Adds a PIXI.Container if necessary.
**/
get foreground() {
if (this._foreground == null) {
this._foreground = new PIXI.Container();
this.addChild(this._foreground);
}
return this._foreground
}
/** Getter for the DeepZoomInfo base level size.
**/
get baseSize() {
return this.info.getDimensions(this.info.baseLevel)
}
/** Getter for the current scaled size in pixels.
**/
get pixelSize() {
let [w, h] = this.baseSize;
return [w * this.scale.x, h * this.scale.y]
}
/** Getter for the max scale factor.
**/
get maxScale() {
let delta = this.info.maxLevel - this.info.baseLevel;
return Math.pow(2, delta) / this.resolution * 2
}
/** Getter for the current width.
**/
get width() {
return this.pixelSize[0]
}
/** Getter for the current height.
**/
get height() {
return this.pixelSize[1]
}
/* Overrides PIXI.Container.hitArea()
* Allows to optimize the hit testing. Container with hit areas are directly
* hit tested without consideration of children.
*/
get hitArea() {
// Defining the hitArea resulted hitting the scatter in masked area
// when a mask was used (@Tüsch[submaps]). Removing the hitArea() altogether
// broke the interaction in other projects (@googleart).
// Fix: When masked, the hitArea is ignored by returning null.
// TODO: test if childs are hittested, without setting interactiveChildren.
// Opel, 03-05-2018
if (this.mask) {
return null
}
return this
}
/* Overrides PIXI.Container.contains()
* Allows to optimize the hit testing.
*/
contains(x, y) {
let [w, h] = this.baseSize;
return x >= 0 && x <= w && y >= 0 && y <= h
}
/** Overrides PIXI.Container._calculateBounds()
* Only considers the base size and reduces the calculation to a single
* rect.
*/
_calculateBounds() {
let [w, h] = this.baseSize;
this._bounds.addFrame(this.transform, 0, 0, w, h);
}
/** Overrides PIXI.Container.calculateBounds()
* Skips the children and only considers the deep zoom base size. Calls
* the also overwritten _calculateBounds method.
*/
calculateBounds() {
this._bounds.clear();
this._calculateBounds();
this._lastBoundsID = this._boundsID;
}
/** Returns a single sprite that can be used a thumbnail representation of
* large images.
* @return {Sprite} sprite - A sprite with a single tile texture
*/
thumbnail() {
return new PIXI.Sprite.fromImage(this.info.baseURL)
}
/** Returns a list of all tiles of a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @return {Array[]} - An array of [url, col, row] arrays
**/
allTiles(tiles, level) {
let result = [];
for (let col = 0; col < tiles.cols; col++) {
for (let row = 0; row < tiles.rows; row++) {
let url = this.info.urlForTile(level, col, row);
result.push([url, col, row]);
}
}
return result
}
worldBounds() {
let viewBounds = this.app.scene.bounds;
// Using getBounds extends visible scope after loading tiles and leads
// to excessive loading
if (this.world != null) {
let bounds = this.world.bounds;
let x = Math.max(-bounds.width, bounds.x);
let y = Math.max(-bounds.height, bounds.y);
let width = Math.min(viewBounds.width, bounds.width);
let height = Math.min(viewBounds.height, bounds.height);
//console.log("worldBounds new", { x, y, width, height })
return { x, y, width, height }
}
//console.log("worldBounds old", viewBounds)
return viewBounds
}
/** Loads all tiles that are needed to fill the app bounds.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @param {boolean} debug
* @return {Array[]} - An array of [url, col, row] arrays
*/
neededTiles(tiles, level, debug = false) {
let needed = [];
let tsize = tiles.tileSize;
let worldBounds = this.worldBounds();
let maxWidth = worldBounds.width;
let maxHeight = worldBounds.height;
let pointInWindow = new PIXI.Point();
let worldTopLeft = new PIXI.Point(worldBounds.x, worldBounds.y);
let worldBottomRight = new PIXI.Point(worldBounds.x + maxWidth, worldBounds.y + maxHeight);
let worldCenter = new PIXI.Point(worldBounds.x + maxWidth / 2, worldBounds.y + maxHeight / 2);
let tilesCenter = tiles.toLocal(worldCenter);
let topLeft = tiles.toLocal(worldTopLeft);
let bottomRight = tiles.toLocal(worldBottomRight);
tiles._centerPoint = tilesCenter;
let bounds = new PIXI.Rectangle(
topLeft.x,
topLeft.y,
bottomRight.x - topLeft.x,
bottomRight.y - topLeft.y);
tiles._boundsRect = bounds;
/* UO: we need a toLocal call here since the transform may need an update
which is guaranteed by the toLocal method. */
let centerCol = Math.floor(tilesCenter.x / tsize);
let centerRow = Math.floor(tilesCenter.y / tsize);
// Expand because we want to test for included centers
bounds.x -= tsize / 2;
bounds.y -= tsize / 2;
bounds.width += tsize;
bounds.height += tsize;
try {
let maxTilesWidth = Math.ceil(maxWidth / tsize);
let maxTilesHeight = Math.ceil(maxHeight / tsize);
maxTilesWidth += 2;
maxTilesHeight += 2;
let startCol = Math.max(0, centerCol - maxTilesWidth);
let endCol = Math.min(tiles.cols, centerCol + maxTilesWidth);
let startRow = Math.max(0, centerRow - maxTilesHeight);
let endRow = Math.min(tiles.rows, centerRow + maxTilesHeight);
for (let col = startCol; col < endCol; col++) {
let cx = (col + 0.5) * tsize;
for (let row = startRow; row < endRow; row++) {
let cy = (row + 0.5) * tsize;
let tileCenter = new PIXI.Point(cx, cy);
if (bounds.contains(tileCenter.x, tileCenter.y)) {
let url = this.info.urlForTile(level, col, row);
needed.push([url, col, row]);
}
}
}
} catch (error) {
console.warn(error.message);
}
return { centerCol, centerRow, needed }
}
/** Returns all changed tiles for a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @return {object} - An object with the keys added and removed which values are [url, col, row] arrays
*/
changedTiles(tiles, level) {
if (this.debug) console.time('changedTiles');
let changed = { added: [], removed: [] };
let newNeeded = new Map();
let { centerCol, centerRow, needed } = this.neededTiles(tiles, level);
needed.forEach(d => {
let [url, col, row] = d;
newNeeded.set(url, [col, row]);
if (!tiles.requested.has(url)) {
changed.added.push(d);
}
});
for (let url of tiles.needed.keys()) {
if (!newNeeded.has(url)) {
let [col, row] = tiles.needed.get(url);
changed.removed.push([url, col, row]);
}
}
tiles.needed = newNeeded;
if (this.debug) console.log(newNeeded);
if (this.debug) console.timeEnd('changedTiles');
return { centerCol, centerRow, changed }
}
/** Populates all tiles for a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
*/
populateAllTiles(tiles, level) {
let all = this.allTiles(tiles, level);
for (let [url, col, row] of all) {
this.addTileQuadNode(level, col, row, url);
}
tiles.loadTiles(all, false, 0, 0);
}
/** Loads all tiles that are needed to fill the browser window.
* If the optional about parameter is provided (as a point with col as x,
* and row as y attr) the tiles are sorted by the distance to this point.
*
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* Optional parameter:
* @param {boolean} onlyone - if true only one tile is loaded
* @param {PIXI.Point} about - point of interaction
*/
populateTiles(tiles, level, { onlyone = false, about = null } = {}) {
if (tiles.isComplete())
return
let referenceCol = -1;
let referenceRow = -1;
let { centerCol, centerRow, changed } = this.changedTiles(tiles, level);
if (about != null) {
// We want to load tiles in the focus of the user first, therefore
// we sort according to the distance of the focus of interaction
let refPoint = this.toLocal(about);
let scaledTileSize = tiles.tileSize * tiles.tileScale;
referenceCol = Math.floor(refPoint.x / scaledTileSize);
referenceRow = Math.floor(refPoint.y / scaledTileSize);
}
else {
referenceCol = centerCol;
referenceRow = centerRow;
}
referenceCol = centerCol;
referenceRow = centerRow;
let removed = changed.removed;
for (let [url, col, row] of removed) {
this.removeTileQuadNode(level, col, row, url);
}
let added = changed.added;
if (added.length == 0) return
for (let [url, col, row] of added) {
this.addTileQuadNode(level, col, row, url);
}
let ref = new PIXI.Point(referenceCol, referenceRow);
// Note: The array must be sorted in a way that the nearest tiles
// are at the end of the array since the load queue uses Array.push
// Array.pop
added.sort((a, b) => {
let aa = new PIXI.Point(a[1], a[2]);
let bb = new PIXI.Point(b[1], b[2]);
let da = Points.distance(aa, ref);
let db = Points.distance(bb, ref);
return db - da
});
tiles.loadTiles(added, onlyone, referenceCol, referenceRow);
}
/** Private method: creates all tiles for a given level.
* @param {number} level - The zoom level of the grid
* @return {Tiles} - tiles
*/
_createTiles(key, level) {
let [cols, rows, w, h] = this.info.dimensions(level);
let increasedLevels = level - this.info.baseLevel;
let invScale = Math.pow(0.5, increasedLevels);
let tiles = new Tiles(
level,
this,
invScale,
cols,
rows,
w,
h,
this.info.tileSize,
this.info.overlap
);
this.addTiles(key, tiles);
if (this.info.clip) {
let rest = this.info.rests[level];
if (rest) {
let x = rest.restCol * this.info.tileSize * invScale;
let y = rest.restRow * this.info.tileSize * invScale;
tiles.x = -x;
tiles.y = -y;
}
}
return tiles
}
/** Ensures that all needed tiles of a given level are loaded. Creates
* a new Tiles layer if necessary
* @param {number} level - The zoom level of the grid
* @return {Tiles} tiles
*/
ensureTiles(level, about) {
let key = level.toString();
if (key in this.tileLayers) {
let tiles = this.tileLayers[key];
this.populateTiles(tiles, level, { about: about });
return tiles
}
let tiles = this._createTiles(key, level);
this.populateTiles(tiles, level, { about: about });
//console.log("ensureTiles", level)
return tiles
}
untintTiles(level) {
let key = level.toString();
if (key in this.tileLayers) {
let tiles = this.tileLayers[key];
}
}
/** Ensures that all tiles of a given level are loaded.
* @param {number} level - The zoom level of the grid
*/
ensureAllTiles(level) {
let key = level.toString();
if (key in this.tileLayers) {
let tiles = this.tileLayers[key];
this.populateAllTiles(tiles, level);
tiles.keep = true;
return
}
let tiles = this._createTiles(key, level);
this.populateAllTiles(tiles, level);
tiles.keep = true;
return tiles
}
hideTilesAboveLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (tiles.level > level) {
tiles.visible = false;
}
});
}
/** Destroys all tiles above a given level to ensure that the memory can
* be reused.
* @param {number} level - The zoom level of the grid
*/
destroyTilesAboveLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (tiles.level > level && !tiles.keep) {
for (let url of tiles.available.keys()) {
let quad = this.quadTrees.get(url);
if (quad) this.removeTileQuadNode(quad);
}
this.destroyTiles(key);
}
});
}
destroyAllTiles() {
Object.keys(this.tileLayers).forEach(key => {
this.destroyTiles(key);
});
}
/**
* Tint tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
tintObsoleteTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
tiles.untintTiles();
if (!tiles.keep) {
tiles.tintObsoleteTiles();
}
});
}
/**
* Destroy tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
destroyUnneededTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (!tiles.keep) {
tiles.destroyUnneededTiles();
}
});
}
/**
* Destroy tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
destroyObsoleteTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (!tiles.keep) {
tiles.destroyObsoleteTiles();
}
});
}
/**
* Destroy tiles in all layers that are not part of the
* visible quadTrees
*
* @memberof DeepZoomImage
*/
destroyTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (!tiles.keep) {
tiles.destroyTiles(this.quadTrees);
}
});
}
/* Tint all tiles
* @param {number} level - The zoom level of the grid
*/
tintTilesBelowLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key];
if (tiles.level < level) {
tiles.tintTiles(this.quadTrees);
}
});
}
/**
* Ensure that the given tiles layer is the topmost one and visible.
* @param {*} tiles
*/
bringTilesToFront(tiles) {
this.tileContainer.addChild(tiles);
tiles.visible = true;
}
/** A callback function that can be used by a Scatter view to inform
* the zoomable image that it has been moved, rotated or scaled, and should
* load tiles accordingly.
* @param {PIXI.Point} translated - the movement of the scatter
* @param {number} scale - the zoom factor
* @param {PIXI.Point} about - the anchor point of the zoom
* @param {boolean} fast - informs the callback to return as fast as possible,
* i.e. after loading a single tile
* @param {boolean} debug - log debug infos
*/
transformed(event) {
let key = this.currentLevel.toString();
let currentTiles = this.tileLayers[key];
if (typeof currentTiles == 'undefined') {
return
}
if (event.fast) {
this.fastLoads += 1;
this.populateTiles(currentTiles, this.currentLevel, {
onlyone: false,
about: event.about
});
if (this.fastLoads == 3) {
this.fastLoads = 0;
}
else {
return
}
}
if (event.scale == null) {
this.ensureTiles(this.currentLevel, event.about);
return
}
let level = this.levelForScale(event.scale);
let newLevel = Math.max(level, this.minimumLevel);
if (newLevel != this.currentLevel) {
if (!currentTiles.keep) {
currentTiles.loader.cancel();
}
this.hideTilesAboveLevel(newLevel);
currentTiles = this.ensureTiles(newLevel, event.about);
this.currentLevel = newLevel;
} else {
this.ensureTiles(this.currentLevel, event.about);
}
this.bringTilesToFront(currentTiles);
if (this._foreground) {
this.addChild(this._foreground);
}
}
/**
*Activates the textures on the DeepZoomImage.
*
* @memberof DeepZoomImage
*/
activate() {
this.destroyTilesAboveLevel(this.currentLevel);
this.ensureTiles(this.currentLevel, null);
//console.log("Activate Textures!", this.currentLevel)
}
/**
*Dectivates the textures on the DeepZoomImage.
*
* @memberof DeepZoomImage
*/
deactivate() {
this.destroyAllTiles();
Object.keys(this.tileLayers).forEach(key => {
this.destroyTiles(key);
});
this.tileContainer.destroy({ children: true });
printTileCacheInfos();
}
throwFinished() {
console.log("throwFinished");
let key = this.currentLevel.toString();
let currentTiles = this.tileLayers[key];
if (typeof currentTiles == 'undefined') {
return
}
this.ensureTiles(this.currentLevel);
// let all = new Set()
// for (let tile of currentTiles.children) {
// all.add(tile.url)
// }
// let { centerCol, centerRow, needed } = this.neededTiles(currentTiles, this.currentLevel)
// for (let [url, col, row] of needed) {
// all.delete(url)
// }
// for (let url of all) {
// currentTiles.destroyTileByUrl(url)
// }
// currentTiles.loader.loader.reset()
}
}
let globalScatterLoaderCanvas = null;
class ScatterLoader extends CardLoader {
get scatter() {
return this.src
}
unscaledSize() {
let displayObject = this.scatter.displayObject;
let w = displayObject.width;
let h = displayObject.height;
return [w / displayObject.scale.x, h / displayObject.scale.y]
}
scaledSize() {
let displayObject = this.scatter.displayObject;
let w = displayObject.width;
let h = displayObject.height;
return [w, h]
}
cloneScatterImage() {
let w = this.scatter.width;
let h = this.scatter.height;
let isSprite = this.scatter.displayObject instanceof PIXI.Sprite;
let isDeepZoom = this.scatter.displayObject instanceof DeepZoomImage;
let resolution = app.renderer.resolution;
if (isSprite) {
w = this.scatter.displayObject.texture.width;
h = this.scatter.displayObject.texture.height;
}
else if (isDeepZoom) {
let [ww, hh] = this.scatter.displayObject.baseSize;
w = ww;
h = hh;
}
if (globalScatterLoaderCanvas === null) {
globalScatterLoaderCanvas = document.createElement('canvas');
}
let canvas = globalScatterLoaderCanvas;
canvas.width = w;
canvas.height = h;
let renderer = new PIXI.WebGLRenderer(w, h, {
view: canvas,
resolution: resolution});
let displayObject = this.scatter.displayObject;
let x = displayObject.x;
let y = displayObject.y;
let rot = displayObject.rotation;
let sx = displayObject.scale.x;
let sy = displayObject.scale.y;
displayObject.rotation = 0;
// The Safari WebGLRenderer wants everything flipped
// See https://github.com/pixijs/pixi.js/issues/2283
displayObject.x = 0;
if (Capabilities.isSafari) {
displayObject.y = h;
displayObject.scale.set(1, -1); // sx, -sy)
}
else {
displayObject.y = 0;
displayObject.scale.set(1, 1);
}
if (isSprite) {
displayObject.width = w;
displayObject.height = h;
}
renderer.render(displayObject);
displayObject.rotation = rot;
displayObject.x = x;
displayObject.y = y;
displayObject.scale.set(sx, sy);
let url = canvas.toDataURL();
return [x, y, w, h, url]
}
load(domNode) {
return new Promise((resolve, reject) => {
let isImage = domNode instanceof HTMLImageElement;
let isSprite = this.scatter.displayObject instanceof PIXI.Sprite;
let image = (isImage) ? domNode : document.createElement("img");
let [x, y, w, h, cloneURL] = this.cloneScatterImage();
let [ww, hh] = this.unscaledSize();
image.onload = (e) => {
if (!isImage)
domNode.appendChild(image);
this.x = x;
this.y = y;
this.wantedWidth = ww;
this.wantedHeight = hh;
this.scale = 1;
this.rotation = this.scatter.rotation;
resolve(this);
};
image.onerror = (e) => {
reject(this);
};
image.src = cloneURL;
})
}
}
class FlipEffect {
constructor(scatter, domScatterContainer, flipTemplate, backLoader) {
this.flipped = false;
this.scatter = scatter;
this.backLoader = backLoader;
this.scatterLoader = new ScatterLoader(scatter);
this.domFlip = new DOMFlip(domScatterContainer, flipTemplate,
this.scatterLoader,
backLoader, {
onBack: this.backCardClosed.bind(this)
});
this.setupInfoButton();
}
startFlip() {
let center = this.flipCenter();
let loader = this.backLoader;
this.domFlip.load().then((domFlip) => {
this.scatter.displayObject.visible = false;
domFlip.centerAt(center);
domFlip.zoom(this.scatter.scale);
let target = this.constraintFlipCenter(center, loader);
console.log("FlipEffect.startFlip", target, loader);
domFlip.start({targetCenter: target});
});
}
unscaledSize() {
return this.scatterLoader.unscaledSize()
}
flipCenter() {
let isSprite = this.scatter.displayObject instanceof PIXI.Sprite;
let resolution = (isSprite) ? app.renderer.resolution : 1;
let center = this.scatter.center;
let canvas = app.renderer.view;
let domNode = this.domFlip.domScatterContainer.element;
let page = window.convertPointFromNodeToPage(canvas,
center.x*resolution,
center.y*resolution);
let local = window.convertPointFromPageToNode(domNode, page.x, page.y);
return local
}
constraintFlipCenter(center, loader) {
let w = loader.wantedWidth;
let h = loader.wantedHeight;
console.log("constraintFlipCenter", w, h);
let canvas = app.renderer.view;
let x = center.x;
let y = center.y;
if (x < w/2)
x = w/2;
if (y < h/2)
y = h/2;
if (x > canvas.width)
x = canvas.width - w/2;
if (y > canvas.height)
y = canvas.height - h/2;
return { x, y }
}
setupInfoButton() {
let iscale = 1.0 / this.scatter.scale;
this.infoBtn = new PIXI.Graphics();
this.infoBtn.beginFill(0x333333);
this.infoBtn.lineStyle(4, 0xFFFFFF);
this.infoBtn.drawCircle(0, 0, 22);
this.infoBtn.endFill();
this.infoBtn.beginFill(0xFFFFFF);
this.infoBtn.lineStyle(0);
this.infoBtn.drawCircle(0, -8, 4);
this.infoBtn.endFill();
this.infoBtn.lineStyle(6, 0xFFFFFF);
this.infoBtn.moveTo(0, -2);
this.infoBtn.lineTo(0, 14);
this.infoBtn.endFill();
this.infoBtn.on('click', (e) => { this.infoSelected(); });
this.infoBtn.on('tap', (e) => { this.infoSelected(); });
this.infoBtn.interactive = true;
this.infoBtn.width = 44;
this.infoBtn.height = 44;
this.infoBtn.pivot.x = 30;
this.infoBtn.pivot.y = 30;
let displayObject = this.scatter.displayObject;
let [w, h] = this.unscaledSize();
this.infoBtn.position = new PIXI.Point(w, h);
if (displayObject.foreground) {
this.infoBtn.scale.x = iscale;
this.infoBtn.scale.y = iscale;
displayObject.foreground.addChild(this.infoBtn);
}
else {
displayObject.addChild(this.infoBtn);
}
this.scatter.addTransformEventCallback(e => {
let displayObject = this.scatter.displayObject;
if (displayObject.foreground) {
if (e.scale) {
let iscale = 1.0 / e.scale;
this.infoBtn.scale.x = iscale;
this.infoBtn.scale.y = iscale;
}
}
});
}
setupButton(url) {
let svgImage = new Image();
let canvas = document.createElement('canvas');
canvas.width = 88 * 4;
canvas.height = 44 * 4;
svgImage.onload = e => {
let displayObject = this.scatter.displayObject;
canvas.getContext ('2d').drawImage(svgImage, 0, 0,
canvas.width, canvas.height);
let texure = new PIXI.Texture(new PIXI.BaseTexture(canvas));
this.infoBtn = new PIXI.Sprite(texure);
this.infoBtn.anchor.set(0.5, 0.5);
if (displayObject.foreground) {
displayObject.foreground.addChild(this.infoBtn);
}
else {
displayObject.addChild(this.infoBtn);
}
this.infoBtn.scale.set(0.5, 0.5);
let [w, h] = this.unscaledSize();
this.infoBtn.position = new PIXI.Point(w, h);
this.infoBtn.interactive = true;
this.infoBtn.updateTransform();
this.infoBtn.on('click', (e) => { this.infoSelected(); });
this.infoBtn.on('tap', (e) => { this.infoSelected(); });
};
svgImage.src = url;
}
infoSelected() {
this.startFlip();
}
backSelected() {
this.domFlip.start();
}
backCardClosed() {
/*** The flip effect should now be in it's initial state again. All
memory should be freed. ***/
let displayObject = this.scatter.displayObject;
displayObject.visible = true;
this.domFlip.fadeOutAndRemove();
this.flipped = false;
}
targetRotation(alpha) {
let ortho = 90;
let rest = alpha % ortho;
let delta = 0.0;
if (rest > (ortho / 2.0)) {
delta = ortho - rest;
}
else {
delta = -rest;
}
return delta
}
}
/* globals Power2, Sine */
/*eslint no-console: ["error", { allow: ["log", "info", "error"] }]*/
/**
* Callback for the flippable onStart function.
*
* @callback onStartCallback
* @param {Flippable} flippable - A reference to the flippable (also this refers to the flippable).
*/
/**
* Callback for the flippable onUpdate function.
*
* @callback onUpdateCallback
* @param {Flippable} flippable - A reference to the flippable (also this refers to the flippable).
*/
/**
* Callback for the flippable onComplete function.
*
* @callback onCompleteCallback
* @param {Flippable} flippable - A reference to the flippable (also this refers to the flippable).
*/
/**
* Class that represents a PixiJS Flippable.
*
* @example
* const front = PIXI.Sprite.fromImage('./assets/front.jpg')
* const back = PIXI.Sprite.fromImage('./assets/back.jpg')
* app.scene.addChild(front)
*
* // Create the flippable
* const flippable = new Flippable(front, back, app.renderer)
*
* front.interactive = true
* front.on('click', event => flippable.toggle())
*
* @class
* @extends PIXI.projection.Camera3d
* @see {@link https://github.com/pixijs/pixi-projection|PixiJS Projection}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/flippable.html|DocTest}
*/
class Flippable extends PIXI.projection.Camera3d {
/**
* Creates an instance of a Flippable.
*
* @constructor
* @param {PIXI.DisplayObject} front - The object to show initially. Should have been added to the scene.
* @param {PIXI.DisplayObject} back - The object to show on the backside. Should have not been added to the scene.
* @param {PIXI.WebGLRenderer|PIXI.CanvasRenderer} renderer - The renderer of the application.
* @param {object} [opts] - An options object which can contain the following properties.
* @param {number} [opts.duration=1] - The duration of the flip animation in seconds.
* @param {GSAP.Ease} [opts.ease=Power2.easeOut] - The ease of the flip animation.
* @param {boolean} [opts.shadow=false] - Should be a shadow been display during the animation?
* @param {numer} [opts.eulerX=0] - The shift of the x-axis during the animation.
* @param {numer} [opts.eulerY=0] - The shift of the y-axis during the animation.
* @param {GSAP.Ease} [opts.eulerEase=Sine.easeOut] - The ease of the shift.
* @param {boolean} [opts.useBackTransforms=false] - When set to true, the flip animation also animates to the transform parameters of the back-object.
* @param {GSAP.Ease} [opts.transformEase=Power2.easeOut] - The ease of the transform.
* @param {numer} [opts.focus=800] - The value of the focus of the 3D camera (see pixi-projection).
* @param {numer} [opts.near=10] - The near value of the 3D camera (see pixi-projection).
* @param {numer} [opts.far=10000] - The far value of the 3D camera (see pixi-projection).
* @param {boolean} [opts.orthographic=false] - Should the flip animation be an orthographic animation?
* @param {function} [opts.onStart=null] - A callback executed on start of the flip animation.
* @param {function} [opts.onUpdate=null] - A callback executed on each step of the flip animation.
* @param {function} [opts.onComplete=null] - A callback executed when the flip animation is finished.
*/
constructor(front, back, renderer, opts = {}) {
super();
this.opts = Object.assign({}, {
front,
back,
renderer,
duration: 1,
ease: Power2.easeOut,
shadow: false,
eulerX: 0,
eulerY: 0,
eulerEase: Sine.easeOut,
useBackTransforms: false,
transformEase: Power2.easeOut,
focus: 800,
near: 10,
far: 10000,
orthographic: false
}, opts);
// planes
//--------------------
this.setPlanes(this.opts.focus, this.opts.near, this.opts.far, this.opts.orthographic);
// flipped
//--------------------
this._flipped = false;
// objects
//--------------------
this.objects = {};
// setup
//--------------------
this.setup();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Flippable} A reference to the flippable for chaining.
*/
setup() {
const scale = .5;
// filters
//--------------------
const blurFilter = new PIXI.filters.BlurFilter();
blurFilter.blur = 0.2;
this.objects.blurFilter = blurFilter;
// outer
//--------------------
const outer = new PIXI.projection.Container3d();
outer.scale3d.set(scale);
this.addChild(outer);
this.objects.outer = outer;
// shadow
//--------------------
const shadow = new PIXI.projection.Sprite3d(PIXI.Texture.fromImage('../../assets/images/shadow.png'));
shadow.renderable = false;
shadow.anchor.set(0.5);
shadow.scale3d.set(.98);
shadow.alpha = 0.7;
shadow.filters = [blurFilter];
shadow.visible = this.opts.shadow;
outer.addChild(shadow);
this.objects.shadow = shadow;
// inner
//--------------------
const inner = new PIXI.projection.Container3d();
inner.euler.y = Math.PI;
outer.addChild(inner);
this.objects.inner = inner;
// front
//--------------------
const front = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY);
front.scale.set(-1 / scale, 1 / scale);
front.renderable = true;
front.anchor.set(.5);
inner.addChild(front);
this.objects.front = front;
// back
//--------------------
const back = new PIXI.projection.Sprite3d(PIXI.Texture.EMPTY);
back.scale.set(1 / scale, 1 / scale);
back.renderable = false;
back.anchor.set(.5);
inner.addChild(back);
this.objects.back = back;
return this
}
/**
* Gets or sets the flipped state.
*
* @member {boolean}
*/
get flipped() {
return this._flipped
}
set flipped(toBack) {
this._flipped = toBack;
// references
//--------------------
const front = this.objects.front;
const back = this.objects.back;
const inner = this.objects.inner;
const shadow = this.objects.shadow;
const blurFilter = this.objects.blurFilter;
const half = this.opts.duration / 2;
const ease = this.opts.eulerEase;
const fromObject = toBack ? this.opts.front : this.opts.back;
const toObject = toBack ? this.opts.back : this.opts.front;
// set textures for virtual front and virtual back
//--------------------
front.texture = this.generateTexture(this.opts.front);
back.texture = this.generateTexture(this.opts.back);
// switch objects and set params for virtual objects
//--------------------
const fromCenter = this.anchorToCenter(fromObject);
const toCenter = this.anchorToCenter(toObject);
// from values
//--------------------
this.x = fromCenter.x;
this.y = fromCenter.y;
front.width = fromObject.width * 2;
front.height = fromObject.height * 2;
back.width = fromObject.width * 2;
back.height = fromObject.height * 2;
this.rotation = fromObject.rotation;
this.skew.x = fromObject.skew.x;
this.skew.y = fromObject.skew.y;
// calculate to values
//--------------------
const to = {
x: this.opts.useBackTransforms ? toCenter.x : fromCenter.x,
y: this.opts.useBackTransforms ? toCenter.y : fromCenter.y,
anchorX: this.opts.useBackTransforms ? toObject.x : fromObject.x,
anchorY: this.opts.useBackTransforms ? toObject.y : fromObject.y,
width: this.opts.useBackTransforms ? toObject.width * 2 : fromObject.width * 2,
height: this.opts.useBackTransforms ? toObject.height * 2 : fromObject.height * 2,
rotation: this.opts.useBackTransforms ? toObject.rotation : fromObject.rotation,
skewX: this.opts.useBackTransforms ? toObject.skew.x : fromObject.skew.x,
skewY: this.opts.useBackTransforms ? toObject.skew.y : fromObject.skew.y
};
// set toObject end values
//--------------------
toObject.x = to.anchorX;
toObject.y = to.anchorY;
toObject.width = to.width / 2;
toObject.height = to.height / 2;
toObject.rotation = to.rotation;
toObject.skew.x = to.skewX;
toObject.skew.y = to.skewY;
// flip
//--------------------
TweenLite.to(inner.euler, this.opts.duration, {
y: toBack ? 0 : Math.PI,
ease: this.opts.ease,
onStart: () => {
this.switchDisplayObject(fromObject, this);
shadow.renderable = true;
if (this.opts.onStart) {
this.opts.onStart(this, this);
}
},
onUpdate: () => {
this.layout();
if (this.opts.onUpdate) {
this.opts.onUpdate(this, this);
}
},
onComplete: () => {
this.switchDisplayObject(this, toObject);
shadow.renderable = false;
if (this.opts.onComplete) {
this.opts.onComplete(this, this);
}
}
});
// x & y
//--------------------
TweenLite.to(this, this.opts.duration, {
x: to.x,
y: to.y,
ease: this.opts.transformEase
});
// width & height
//--------------------
TweenLite.to([front, back], this.opts.duration, {
width: to.width,
height: to.height,
ease: this.opts.transformEase
});
// rotation
//--------------------
TweenLite.to(this, this.opts.duration, {
directionalRotation: {
rotation: `${to.rotation}_short`,
useRadians: true
},
ease: this.opts.transformEase
});
// skewX & skewY
//--------------------
TweenLite.to(this.skew, this.opts.duration, {
x: to.skewX,
y: to.skewY,
ease: this.opts.transformEase
});
// camera
//--------------------
new TimelineMax()
.to(this.euler, half, {x: this.opts.eulerX, y: this.opts.eulerY, ease})
.to(this.euler, half, {x: 0, y: 0, ease});
// shadow
//--------------------
new TimelineMax()
.to(shadow, half, {alpha: .3, ease})
.to(shadow, half, {alpha: .7, ease});
// blurfilter
//--------------------
new TimelineMax()
.to(blurFilter, half, {blur: 6, ease})
.to(blurFilter, half, {blur: .2, ease});
}
/**
* Should be called to refresh the layout of the camera.
*
* @return {Flippable} A reference to the flippable for chaining.
*/
layout() {
const front = this.objects.front;
const back = this.objects.back;
const shadow = this.objects.shadow;
const inner = this.objects.inner;
inner.position3d.z = -Math.sin(inner.euler.y) * front.texture.baseTexture.width * 2;
//this.objects.shadow.euler = this.objects.inner.euler
shadow.euler.x = -inner.euler.x;
shadow.euler.y = -inner.euler.y;
if (this.frontSideInFront) {
front.renderable = true;
back.renderable = false;
shadow.width = front.width;
shadow.height = front.height;
} else {
front.renderable = false;
back.renderable = true;
shadow.width = back.width;
shadow.height = back.height;
}
return this
}
/**
* Toggles the flippable. Switches the sides.
*
* @private
* @return {Flippable} A reference to the flippable for chaining.
*/
toggle() {
this.flipped = !this.flipped;
return this
}
/**
* Gets the alignment state. true if the front side is in front, false otherwise.
*
* @member {boolean}
*/
get frontSideInFront() {
return !this.objects.inner.isFrontFace()
}
/**
* Calculates the center point of an PIXI.DisplayObject.
*
* @private
* @param {PIXI.DisplayObject} displayObject - The DisplayObject from which to calculate the center.
* @return {object} Return an object with x and y.
*/
anchorToCenter(displayObject) {
const bounds = displayObject.getBounds();
return {
x: bounds.x + bounds.width / 2,
y: bounds.y + bounds.height / 2
}
}
/**
* Creates children and instantiates everything.
*
* @private
* @param {PIXI.DisplayObject} displayObject - The DisplayObject from which to generate the texture.
* @return {PIXI.Texture} The generated PIXI.Texture.
*/
generateTexture(displayObject) {
// renderTexture
//--------------------
const renderTexture = PIXI.RenderTexture.create(displayObject.width, displayObject.height);
// save position
const transform = [displayObject.x, displayObject.y, displayObject.scale.x, displayObject.scale.y, displayObject.rotation, displayObject.skew.x, displayObject.skew.y, displayObject.pivot.x, displayObject.pivot.y];
displayObject.position.set(0, 0);
displayObject.skew.set(0, 0);
displayObject.rotation = 0;
// render
//--------------------
this.opts.renderer.render(displayObject, renderTexture);
// restore position
displayObject.setTransform(...transform);
return renderTexture
}
/**
* Removed the first DisplayObject and adds the second one at the exactly same position.
*
* @private
* @param {PIXI.DisplayObject} first - The old DisplayObject.
* @param {PIXI.DisplayObject} second - The new DisplayObject.
* @return {Flippable} A reference to the flippable for chaining.
*/
switchDisplayObject(first, second) {
if (first && second && first.parent) {
const parent = first.parent;
const index = parent.getChildIndex(first);
parent.addChildAt(second, index);
parent.removeChild(first);
}
return this
}
}
/**
*
*/
class Popover extends PIXI.Graphics {
constructor({title = null, text = null, x = 0, y = 0, placement = 'top', width = 250, titleStyle = {}, textStyle = {fontSize: '1.6em'}} = {}) {
super();
this.opts = {title, text, x, y, placement, width, titleStyle, textStyle};
this.padding = 12;
let style = {
fontFamily: 'Arial',
fontSize: '2em',
stroke: '#f6f6f6',
strokeThickness: 3,
wordWrap: true,
wordWrapWidth: width - (this.padding * 2)
};
this.titleTextStyle = new PIXI.TextStyle(Object.assign({}, style, titleStyle));
this.textTextStyle = new PIXI.TextStyle(Object.assign({}, style, textStyle));
if (title || text) {
this.setup();
this.draw();
this.positioning();
}
}
setup() {
this.removeChildren();
if (this.opts.title) {
this.titleText = new PIXI.Text(this.opts.title, this.titleTextStyle);
this.titleText.position.set(this.padding, this.padding);
this.addChild(this.titleText);
}
this.titleY = this.titleText ? this.titleText.y : 0;
this.titleHeight = this.titleText ? this.titleText.height : 0;
if (this.opts.text) {
this.textText = new PIXI.Text(this.opts.text, this.textTextStyle);
this.textText.position.set(this.padding, this.titleY + this.titleHeight + this.padding);
this.addChild(this.textText);
}
this.textY = this.textText ? this.textText.y : 0;
this.textHeight = this.textText ? this.textText.height : 0;
}
close() {
this.parent.removeChild(this);
}
draw() {
this.clear();
this.beginFill(0xffffff, 1);
this.lineStyle(1, 0x282828, .5);
// Draw rounded rectangle
const height = this.height + this.padding;
this.drawRoundedRect(0, 0, this.opts.width, height, 8);
// Draw anchor
this.drawAnchor(this.opts.placement);
// Draw title background
if (this.opts.title) {
this.lineStyle(0);
this.beginFill(0xf7f7f7, 1);
let x = 1;
let y = this.titleText.x + this.titleText.height + (this.padding / 2);
this.moveTo(x, y);
y = 9;
this.lineTo(x, y);
this.quadraticCurveTo(x, y - 8, x + 8, y - 8);
x += this.opts.width - 7;
y -= 8;
this.lineTo(x, y);
this.quadraticCurveTo(x + 5, y, x + 5, y + 8);
x += 5;
y += this.titleText.x + this.titleText.height + (this.padding / 2);
this.lineTo(x, y);
if (this.opts.text) {
x = 1;
this.lineTo(x, y);
} else {
this.quadraticCurveTo(x, y, x - 5, y + 4);
x = 6;
y += 4;
this.lineTo(x, y);
this.quadraticCurveTo(x, y, x - 5, y - 4);
}
}
this.endFill();
}
drawAnchor(placement) {
let x = 0;
let y = 0;
switch (placement) {
case 'bottom':
if (this.opts.title) {
this.beginFill(0xf7f7f7, 1);
}
x = (this.width / 2) - 10;
y = 1;
this.moveTo(x, y);
x += 10;
y -= 10;
this.lineTo(x, y);
x += 10;
y += 10;
this.lineTo(x, y);
break
case 'right':
x = 1;
y = (this.height / 2) - 10;
if (this.titleY + this.titleHeight > y) {
this.beginFill(0xf7f7f7, 1);
}
this.moveTo(x, y);
x -= 10;
y += 10;
this.lineTo(x, y);
x += 10;
y += 10;
this.lineTo(x, y);
break
case 'left':
x = this.width - 2;
y = (this.height / 2) - 10;
if (this.titleY + this.titleHeight > y) {
this.beginFill(0xf7f7f7, 1);
}
this.moveTo(x, y);
x += 10;
y += 10;
this.lineTo(x, y);
x -= 10;
y += 10;
this.lineTo(x, y);
break
default:
x = (this.width / 2) - 10;
y = this.height - 2;
this.moveTo(x, y);
x += 10;
y += 10;
this.lineTo(x, y);
x += 10;
y -= 10;
this.lineTo(x, y);
break
}
}
positioning() {
const x = this.opts.x;
const y = this.opts.y;
switch (this.opts.placement) {
case 'bottom':
this.position.set(x - (this.width / 2), y + 10);
break
case 'right':
this.position.set(x, y - (this.height / 2));
break
case 'left':
this.position.set(x - this.width, y - (this.height / 2));
break
default:
this.position.set(x - (this.width / 2), y - this.height);
break
}
}
}
/** A container for scatter objects, which uses a single InteractionMapper
* for all children. This reduces the number of registered event handlers
* and covers the common use case that multiple objects are scattered
* on the same level.
*/
class ScatterContainer extends PIXI.Graphics {
/**
* @constructor
* @param {PIXI.Renderer} renderer - PIXI renderer, needed for hit testing
* @param {Bool} stopEvents - Whether events should be stopped or propagated
* @param {Bool} claimEvents - Whether events should be marked as claimed
* if findTarget return as non-null value.
* @param {PIXI.Container} container - A container for the scatter
* @param {Bool} showBounds - Show bounds for debugging purposes.
* @param {Bool} showTouches - Show touches and pointer for debugging purposes.
* @param {Color} backgroundColor - Set background color if specified.
* @param {PIXIApp} app - Needed if showBounds is true to register
* update handler.
*/
constructor(renderer, {
stopEvents = true,
claimEvents = true,
container = null,
showBounds = false,
showPolygon = false,
showTouches = false,
backgroundColor = null,
app = window.app
} = {}) {
super();
this.container = container;
if (this.container)
this.containerDimensions = {
x: this.container.width,
y: this.container.height
};
this.backgroundWidth = null;
this.backgroundHeight = null;
this.app = app;
this.renderer = renderer;
this.stopEvents = stopEvents;
this.claimEvents = claimEvents;
this.delegate = new InteractionMapper$1(this.eventReceiver, this);
this.showBounds = showBounds;
this.showTouches = showTouches;
this.showPolygon = showPolygon;
this.backgroundColor = backgroundColor;
if (showBounds || showTouches || showPolygon) {
//console.log("Show TOUCHES!!!")
this.app.ticker.add((delta) => this.update(delta), this);
}
if (backgroundColor) {
this.updateBackground();
}
}
updateBackground() {
this.clear();
let rect = this.bounds;
this.beginFill(this.backgroundColor, 1);
this.drawRect(0, 0, rect.width, rect.height);
this.endFill();
}
get eventReceiver() {
return this.renderer.plugins.interaction.interactionDOMElement
}
get bounds() {
let x = 0;
let y = 0;
// @container: We need to call the constant values, as the container
// gets resized, when a child moves outside the original boundaries.
let w = (this.container) ? this.containerDimensions.x : (this.backgroundWidth || this.app.width);
let h = (this.container) ? this.containerDimensions.y : (this.backgroundHeight || this.app.height);
if (this.app.fullscreen && this.app.monkeyPatchMapping) {
let fixed = this.mapPositionToPoint({ x: w, y: 0 });
if (fixed.x < w) {
w = fixed.x;
}
if (fixed.y > 0) {
y += fixed.y;
h -= fixed.y;
}
}
return new PIXI.Rectangle(x, y, w, h)
}
get center() {
let r = this.bounds;
return { x: r.width / 2, y: r.height / 2 }
}
get polygon() {
let r = this.bounds;
let w2 = r.width / 2;
let h2 = r.height / 2;
let center = { x: w2, y: h2 };
let polygon = new Polygon(center);
polygon.addPoint({ x: -w2, y: -h2 });
polygon.addPoint({ x: w2, y: -h2 });
polygon.addPoint({ x: w2, y: h2 });
polygon.addPoint({ x: -w2, y: h2 });
return polygon
}
update(dt) {
this.clear();
this.lineStyle(1, 0x0000FF);
if (this.showBounds) {
for (let child of this.children) {
if (child.scatter) {
//let {x, y, width, height} = child.scatter.throwBounds()
// new PIXI.Rectangle(x, y, width, height)
this.drawShape(child.scatter.bounds);
let center = child.scatter.center;
this.drawCircle(center.x, center.y, 4);
this.drawCircle(child.scatter.x, child.scatter.y, 4);
}
}
this.lineStyle(2, 0x0000FF);
this.drawShape(this.bounds);
}
if (this.showPolygon) {
this.lineStyle(2, 0xFF0000);
for (let child of this.children) {
if (child.scatter) {
let polygon = child.scatter.polygon;
let shape = new PIXI.Polygon(polygon.flatAbsolutePoints());
shape.close();
this.drawShape(shape);
}
}
}
if (this.showTouches) {
let current = this.delegate.interaction.current;
for (let [key, point] of current.entries()) {
let local = this.mapPositionToPoint(point);
this.drawCircle(local.x, local.y, 12);
}
}
}
capture(event) {
if (this.stopEvents)
Events$1.stop(event);
return true
}
fakeInteractionEvent(point, key) {
return { data: { global: point, key: key } }
}
findHitScatter(data, displayObject, hit) {
// if (hit) {
// console.log("findHitScatter", displayObject)
// }
if (hit && this.hitScatter === null && typeof (displayObject) != undefined) {
this.hitScatter = (displayObject.scatter) ? displayObject.scatter : null;
}
}
mapPositionToPoint(point, element = null) {
// In case of nested scatters we get an additional parameter that
// contains the found scatter
let local = new PIXI.Point();
let interactionManager = this.renderer.plugins.interaction;
interactionManager.mapPositionToPoint(local, point.x, point.y);
if (element instanceof DisplayObjectScatter && element.displayObject.parent != null) {
return element.displayObject.parent.toLocal(local)
}
return local
}
/**
* New method hitTest implemented (in InteractionManager, since 4.5.0).
* See https://github.com/pixijs/pixi.js/pull/3878
*/
findTarget(event, local, global) {
if (event.claimedByScatter) {
return null
}
this.hitScatter = null;
let interactionManager = this.renderer.plugins.interaction;
let fakeEvent = this.fakeInteractionEvent(local);
interactionManager.processInteractive(fakeEvent,
this,
this.findHitScatter.bind(this), true);
if (this.claimEvents)
event.claimedByScatter = this.hitScatter;
return this.hitScatter
}
findTargetNew(event, local, global) {
// UO: still problematic. Does not find non interactive elements
// which are needed for some stylus applications
if (event.claimedByScatter) {
return null
}
this.hitScatter = null;
let interactionManager = this.renderer.plugins.interaction;
let displayObject = interactionManager.hitTest(local, this);
if (displayObject != null && displayObject.scatter != null)
this.hitScatter = displayObject.scatter;
if (this.claimEvents)
event.claimedByScatter = this.hitScatter;
return this.hitScatter
}
onStart(event, interaction) {
}
onMove(event, interaction) {
}
onEnd(event, interaction) {
for (let key of interaction.ended.keys()) {
let point = interaction.ended.get(key);
if (interaction.isLongPress(key)) {
this.onLongPress(key, point);
}
if (interaction.isTap(key)) {
this.onTap(key, point);
}
}
}
onTap(key, point) {
console.info('ScatterContainer.onTap');
}
onLongPress(key, point) {
console.info('ScatterContainer.onLongPress');
}
bringToFront(displayObject) {
this.addChild(displayObject);
}
layout(width, height) {
this.backgroundWidth = width;
this.backgroundHeight = height;
if (this.backgroundColor) {
this.updateBackground();
}
}
}
/** A wrapper for child elements of a ScatterContainer. Can be used
* to combine scattered objects with non-scattered objects. Any
* PIXI.DisplayObject can be wrapped.
*/
class DisplayObjectScatter extends AbstractScatter {
constructor(displayObject, renderer,
{ x = null, y = null,
minScale = 0.1,
maxScale = 1.0,
startScale = 1.0,
autoBringToFront = true,
translatable = true, scalable = true, rotatable = true, resizable = false,
movableX = true,
movableY = true,
throwVisibility = 44,
throwDamping = 0.95,
autoThrow = true,
rotationDegrees = null,
rotation = null,
overdoScaling = 1.5,
onTransform = null,
onThrowFinished = null } = {}) {
// For the simulation of named parameters,
// see: http://exploringjs.com/es6/ch_parameter-handling.html
super({
overdoScaling,
minScale, maxScale,
startScale,
autoBringToFront,
translatable, scalable, rotatable, resizable,
movableX, movableY, throwVisibility, throwDamping,
autoThrow,
onThrowFinished,
rotationDegrees, rotation,
onTransform
});
this.displayObject = displayObject;
this.displayObject.scatter = this;
this.renderer = renderer;
this.scale = startScale;
this.rotationDegrees = this.startRotationDegrees;
// Only set x and y if they are specified.
// Otherwise the displayobject gets corrupted.
if (x != null) this.x = x;
if (y != null) this.y = y;
}
getWorldScatter() {
return this
}
/** Returns geometry data as object. **/
getState() {
return {
scale: this.scale,
x: this.x,
y: this.y,
rotation: this.rotation
}
}
setup() {
this.setupMouseWheelInteraction();
}
roundPixel(value) {
// UO: Should be obsolete because Renderer supports roundPixels by default
return value
let res = this.renderer.resolution;
return Math.round(value * res) / res
}
get container() {
// return this.displayObject.parent
let obj = this.displayObject;
while (obj.parent != null && !(obj.parent instanceof ScatterContainer))
obj = obj.parent;
return obj.parent
}
get x() {
return this.position.x
}
set x(value) {
this.position.x = value;
}
get y() {
return this.position.y
}
set y(value) {
this.position.y = value;
}
get polygon() {
let polygon = new Polygon(this.center);
let w2 = this.width / 2;
let h2 = this.height / 2;
polygon.addPoint({ x: -w2, y: -h2 });
polygon.addPoint({ x: w2, y: -h2 });
polygon.addPoint({ x: w2, y: h2 });
polygon.addPoint({ x: -w2, y: h2 });
polygon.rotate(this.rotation);
return polygon
}
get containerBounds() {
return this.container.bounds
}
get containerPolygon() {
let container = this.container;
if (container == null) return null
return container.polygon
}
get position() {
return this.displayObject.position
}
set position(value) {
this.displayObject.position = value;
}
get scale() {
return this.displayObject.scale.x
}
set scale(value) {
this.displayObject.scale.x = value;
this.displayObject.scale.y = value;
}
get width() {
return this.displayObject.width
}
get height() {
return this.displayObject.height
}
get bounds() {
return this.displayObject.getBounds()
}
get pivot() {
return this.displayObject.pivot
}
get rotation() {
return this.displayObject.rotation
}
set rotation(value) {
this.displayObject.rotation = value;
}
get rotationDegrees() {
return Angle.radian2degree(this.displayObject.rotation)
}
set rotationDegrees(value) {
this.displayObject.rotation = Angle.degree2radian(value);
}
get center() {
let w2 = this.width / 2;
let h2 = this.height / 2;
let dist = Math.sqrt(w2 * w2 + h2 * h2);
let angle = Points.angle({ x: w2, y: h2 }, { x: 0, y: 0 });
let p = this.displayObject.x;
let c = Points.arc(this.position, this.rotation + angle, dist);
return c // Points.subtract(c, this.pivot)
}
get rotationOrigin() {
// In PIXI the default rotation and scale origin is the position
return this.position // Points.add(this.position, this.pivot)
}
mapPositionToContainerPoint(point) {
// UO: We need the coordinates related to this scatter in case
// of nested scatters
if (this.container != null)
return this.container.mapPositionToPoint(point, this)
return point
}
capture(event) {
return true
}
bringToFront() {
if (this.autoBringToFront) {
if (this.displayObject.parent instanceof ScatterContainer) {
let scatterContainer = this.displayObject.parent;
scatterContainer.bringToFront(this.displayObject);
} else if (this.displayObject.parent != null && this.displayObject.parent.scatter) {
this.displayObject.parent.scatter.toFront(this.displayObject);
}
}
}
toFront(displayObject) {
this.displayObject.addChild(displayObject);
}
validScale(scale) {
scale = Math.max(scale, this.minScale);
scale = Math.min(scale, this.maxScale);
return scale
}
}
/**
*
*/
class Command extends PIXI.Graphics {
/*** Abstract base class for record, play, and stop commands. ***/
constructor(tools, selectedColor, shape) {
super();
this.tools = tools;
this.shape = shape;
this.selected = false;
this.disabled = false;
this.selectedColor = selectedColor;
this.draw();
this.setup();
}
setup() {
}
draw() {
this.clear();
var color = (this.selected) ? this.selectedColor : 0xFFFFFF;
this.lineStyle(0);
this.beginFill(color, 1);
this.drawShape(this.shape);
this.endFill();
}
select() {
this.selected = true;
this.draw();
}
deselect() {
this.selected = false;
this.draw();
}
toggle() {
this.selected = !this.selected;
this.draw();
}
stop() {
this.selected = false;
this.draw();
}
}
class RecordCommand extends Command {
/*** Records events for later replay. ***/
setup() {
this.recorder = new EventRecorder();
}
toggle() {
super.toggle();
if (!this.selected) {
this.recorder.stopRecording();
}
}
recordEvent(event) {
this.recorder.record(event);
}
normalize(value, limit) {
return value / limit
}
normalizeX(value) {
return this.normalize(value, window.innerWidth)
}
normalizeY(value) {
return this.normalize(value, window.innerHeight)
}
whileNotStopped() {
return this.tools.play.selected
}
startReplay() {
let whileCondition = this.whileNotStopped.bind(this);
this.recorder.startReplay(whileCondition, () => this.tools.play.stop());
}
}
class PlayCommand extends Command {
/*** Plays recorded events. ***/
toggle() {
super.toggle();
if (this.selected && this.tools.record.recorder.recorded.length > 0) {
this.tools.startReplay();
}
}
}
class StopCommand extends Command {
/*** Stops recording and playing. ***/
toggle() {
super.toggle();
this.tools.record.stop();
this.tools.play.stop();
setTimeout(this.deselect.bind(this), 500);
}
}
class RecorderTools extends PIXI.Container {
constructor(renderer) {
super(renderer);
this.renderer = renderer;
this.setupToolbar();
this.replayRate = 100.0;
this.onReset = null;
this.touchGraphics = new PIXI.Graphics();
this.showTouches();
}
setup(container) {
// Since this delegate might shadow another delegate, we mus avoid
// capturing PointerEvents.
this.delegate = new InteractionMapper(container, this, { capturePointerEvents: false });
}
findTarget(event, local, global) {
return this
}
setupToolbar() {
this.toolbar = new PIXI.Graphics();
this.record = new RecordCommand(this, 0xCC0000, new PIXI.Circle(0, 0, 16));
this.play = new PlayCommand(this, 0x0000CC, new PIXI.Polygon(0, 16,
32, 16 + 16,
0, 16 + 32,
0, 16));
this.stop = new StopCommand(this, 0x0000CC,
new PIXI.Rectangle(0, 0, 32, 32));
this.toolbar.addChild(this.record).position.set(44, 48);
this.toolbar.addChild(this.play).position.set(44 + 44, 16);
this.toolbar.addChild(this.stop).position.set(44 + 44 + 44 + 16, 32);
this.updateToolbar();
this.addChild(this.toolbar);
}
updateToolbar() {
var graphics = this.toolbar;
graphics.clear();
graphics.beginFill(0x000000, 0.5);
graphics.lineStyle(2, 0xFFFFFF, 1);
graphics.drawRoundedRect(16, 16, 44 * 4 + 8, 64, 8);
graphics.endFill();
}
onMouseWheel(event) {
console.log('onMouseWheel missing');
}
onPress(point) {
if (this.record.containsPoint(point)) {
this.record.toggle();
}
if (this.play.containsPoint(point)) {
this.play.toggle();
}
if (this.stop.containsPoint(point)) {
this.stop.toggle();
if (this.onReset) {
this.onReset();
}
}
}
mapPositionToPoint(point) {
let local = new PIXI.Point();
this.renderer.plugins.interaction.mapPositionToPoint(local, point.x, point.y);
return local
}
extractLocal(event) {
return this.mapPositionToPoint(Events.extractPoint(event))
}
capture(event) {
if (typeof event.mouseDownSubstitute != 'undefined')
return false
return true
}
startReplay() {
if (this.onReset) {
this.onReset();
}
this.record.startReplay();
}
showTouches() {
this.addChild(this.touchGraphics);
}
recordEvent(event) {
if (this.record.selected) {
this.record.recordEvent(event);
}
}
onStart(event, interaction) {
let local = this.extractLocal(event);
if (!this.toolbar.containsPoint(local)) {
this.recordEvent(event);
this.updateTouchGraphics(interaction);
}
}
onMove(event, interaction) {
let local = this.extractLocal(event);
if (!this.toolbar.containsPoint(local)) {
this.recordEvent(event);
this.updateTouchGraphics(interaction);
}
}
onEnd(event, interaction) {
let local = this.extractLocal(event);
if (this.toolbar.containsPoint(local)) {
this.onPress(local);
}
else {
this.recordEvent(event);
this.updateTouchGraphics(interaction);
}
}
updateTouchGraphics(interaction) {
let current = interaction.current;
let graphics = this.touchGraphics;
if (graphics != null) {
graphics.clear();
for (let key of current.keys()) {
if (interaction.ended.has(key)) {
continue
}
let p = current.get(key);
if (key == 'mouse') {
graphics.beginFill(0xCC0000, 0.5);
} else {
graphics.beginFill(0xCCCCCC, 0.5);
}
graphics.drawCircle(p.x, p.y, 20);
}
graphics.endFill();
}
}
}
class AppTest extends PIXIApp {
constructor(canvas, container) {
super({ view: canvas, backgroundColor: 0x000000 });
this.container = container;
}
sceneFactory() {
return new RecorderTools(this.renderer)
}
setup() {
super.setup();
this.scene.setup(this.container);
}
run(reset = null) {
this.scene.onReset = reset;
console.log('Running AppTest');
return this
}
}
/**
* Defines usefull default text styles.
*/
class FontInfo {
static get small() {
return app.theme.textStyleSmall
}
static get normal() {
return app.theme.textStyle
}
static get centered() {
return Object.assign({}, app.theme.textStyle, { align: 'center' })
}
}
/**
* Static methods to support hyphenation of lines.
*
* @class Hypenate
*/
class Hypenate {
static splitPart(part) {
let parts = part.split('-');
if (parts.length == 1)
return [part]
let result = [];
let last = parts.pop();
for (let p of parts) {
result.push(p + '-');
}
result.push(last);
return result.filter(p => p.length > 0)
}
static splitWord(word) {
if (typeof (language) == 'undefined') {
if (word.indexOf('-') > -1) {
return word.split('-')
}
return [word]
}
let parts = language.hyphenate(word);
let result = [];
for (let part of parts) {
for (let splitted of this.splitPart(part)) {
result.push(splitted);
}
}
return result
}
static abbreviateLine(label, style, width) {
const pixiStyle = new PIXI.TextStyle(style);
let metrics = PIXI.TextMetrics.measureText(label, pixiStyle);
while(metrics.width > width && label.length > 3) {
label = label.slice(0, label.length-1);
metrics = PIXI.TextMetrics.measureText(label, pixiStyle);
}
label = label.slice(0, label.length-1);
return label + '…'
}
static splitLine(line, pixiStyle, width, space, minus) {
let x = 0;
let result = '';
let words = line.split(' ');
for (let word of words) {
let wordMetrics = PIXI.TextMetrics.measureText(word, pixiStyle);
if (x + wordMetrics.width >= width) {
let parts = this.splitWord(word);
let newWord = '';
if (parts.length == 1) {
newWord += '\n' + word + ' ';
x = wordMetrics.width + space.width;
}
else {
let first = true;
let lastPart = '';
for (let part of parts) {
let partMetrics = PIXI.TextMetrics.measureText(part, pixiStyle);
if (x + partMetrics.width + space.width > width) {
newWord += ((first || lastPart.endsWith('-')) ? '\n' : '-\n') + part;
x = partMetrics.width;
}
else {
newWord += part;
x += partMetrics.width;
}
lastPart = part;
first = false;
}
x += space.width;
}
result += newWord + ' ';
}
else {
result += word + ' ';
x += wordMetrics.width + space.width;
}
}
return result
}
/**
* Main method and entry point for text hyphenation
*
* @static
* @param {*} text
* @param {*} style
* @param {*} width
* @returns
* @memberof Hypenate
*/
static splitLines(text, style, width) {
const pixiStyle = new PIXI.TextStyle(style);
const lines = text.split('\n');
const space = PIXI.TextMetrics.measureText(' ', pixiStyle);
const minus = PIXI.TextMetrics.measureText('-', pixiStyle);
let result = [];
for (let line of lines) {
result.push(this.splitLine(line, pixiStyle, width, space, minus));
}
return result.join('\n')
}
}
/**
* A specialization of the PIXI.Graphics class that allows to
* resuse and place labels across different layout variants
*
* @export
* @class LabeledGraphics
* @extends {PIXI.Graphics}
*/
class LabeledGraphics extends PIXI.Graphics {
/**
* Creates an instance of LabeledGraphics and defines a local label cache.
*
* @memberof LabeledGraphics
*/
constructor() {
super();
this.labels = new Map();
}
_createText(label, fontInfo) {
return new PIXI.Text(label, fontInfo)
}
/**
* Main additional method. Ensures that a text object is created that is cached
* under the given key.
*
* @param {*} key - The cache key
* @param {*} label - The label to show
* @param {*} [attrs={}] - Defines attributes of the text object.
* align: 'right', 'left', or 'center'
* justify: 'top', 'bottom', or 'center'
* maxLines: {integer} truncates the text and adds ellipsis
* maxHeight: {number} truncates text that needs more space and adds ellipsis
* maxWidth: {number} word wraps text using hyphenation if possible
* @param {*} [fontInfo=FontInfo.normal] - Defines PIXI.TextStyle attributes
* @returns {PIXI.Text} instance
* @memberof LabeledGraphics
*/
ensureLabel(key, label, attrs = {}, fontInfo = FontInfo.normal) {
if (attrs.maxWidth && attrs.maxLines == 1) {
label = Hypenate.abbreviateLine(label, fontInfo, attrs.maxWidth);
}
else {
if (attrs.maxWidth) {
label = Hypenate.splitLines(label, fontInfo, attrs.maxWidth);
}
if (attrs.maxLines) {
label = this.truncateLabel(label, fontInfo, attrs.maxLines);
}
if (attrs.maxHeight) {
let styleInfo = new PIXI.TextStyle(fontInfo);
let metrics = PIXI.TextMetrics.measureText(label, styleInfo);
let maxLines = Math.max(attrs.maxHeight / metrics.lineHeight, 1);
label = this.truncateLabel(label, fontInfo, maxLines);
}
}
if (!this.labels.has(key)) {
let text = this._createText(label, fontInfo);
this.labels.set(key, text);
this.addChild(text);
}
let text = this.labels.get(key);
for (let k in attrs) {
text[k] = attrs[k];
}
if (label != text.text)
text.text = label;
// We do not follow the flexbox jargon and use align for x and justify for y axis
// This deviation is needed to ensure backward compatability
switch (attrs.justify || null) {
case 'top':
text.anchor.y = 0;
break
case 'bottom':
text.anchor.x = 1;
break
default:
text.anchor.y = 0.5;
break
}
switch (attrs.align) {
case 'right':
text.anchor.x = 1;
break
case 'center':
text.anchor.x = 0.5;
break
default:
text.anchor.x = 0;
break
}
text.visible = true;
return text
}
/**
* Private method that truncates the text and adds an ellipsis if there are more lines
* than wanted
*
* @param {*} text
* @param {*} style
* @param {*} [maxLines=Infinity]
* @returns
* @memberof LabeledGraphics
*/
truncateLabel(text, style, maxLines = Infinity) {
if (maxLines === Infinity) {
return text
}
const { wordWrapWidth } = style;
const pixiStyle = new PIXI.TextStyle(style);
const { lines } = PIXI.TextMetrics.measureText(text, pixiStyle);
let newText = text;
if (lines.length > maxLines) {
const truncatedLines = lines.slice(0, maxLines);
const lastLine = truncatedLines[truncatedLines.length - 1];
const words = lastLine.split(' ');
const wordMetrics = PIXI.TextMetrics.measureText(`\u00A0\n...\n${words.join('\n')}`, pixiStyle);
const [spaceLength, dotsLength, ...wordLengths] = wordMetrics.lineWidths;
const { text: newLastLine } = wordLengths.reduce((data, wordLength, i) => {
if (data.length + wordLength + spaceLength >= wordWrapWidth) {
return { ...data, length: wordWrapWidth }
}
return {
text: `${data.text}${i > 0 ? ' ' : ''}${words[i]}`,
length: data.length + wordLength + spaceLength,
};
}, { text: '', length: dotsLength });
truncatedLines[truncatedLines.length - 1] = `${newLastLine}...`;
newText = truncatedLines.join('\n');
}
return newText
}
/**
* Returns the label for the given key.
*
* @param {*} key
* @returns
* @memberof LabeledGraphics
*/
getLabel(key) {
return this.labels.get(key)
}
/**
* Hides the label with the given key.
* @param {*} key
* @memberof LabeledGraphics
*/
hideLabel(key) {
let label = this.labels.get(key);
if (label) {
label.visible = false;
}
}
/**
* Removes the label with the given key.
* @param {*} key
* @memberof LabeledGraphics
*/
removeLabel(key) {
let label = this.labels.get(key);
this.labels.delete(key);
label.destroy();
}
/**
* Ensures that labels are hidden on clear.
*
* @memberof LabeledGraphics
*/
clear() {
super.clear();
for (let key of this.labels.keys()) {
this.hideLabel(key);
}
}
/**
* Logs debugging infos
*
* @memberof LabeledGraphics
*/
debugInfos() {
console.log({ size: this.labels.size, labels: this.labels });
}
}
const labelCache = new Map();
function getTexture(label, fontInfo = FontInfo.normal) {
let key = label + fontInfo.fontFamily + fontInfo.fontSize;
if (labelCache.has(key)) {
return labelCache.get(key)
}
let expandedFont = Object.assign({}, fontInfo);
expandedFont.fontSize *= window.devicePixelRatio;
let text = new PIXI.Text(label, expandedFont);
text.updateText();
labelCache.set(key, text.texture);
return text.texture
}
class SpriteLabel extends PIXI.Sprite {
constructor(label, fontInfo) {
let texture = getTexture(label, fontInfo);
super(texture);
this.label = label;
this.fontInfo = fontInfo;
this.scale.set(0.8 / window.devicePixelRatio);
}
set text(label) {
this.label = label;
this.texture = getTexture(label, this.fontInfo);
}
get text() {
return this.label
}
}
class BitmapLabeledGraphics extends LabeledGraphics {
_createText(label, fontInfo) {
let texture = getTexture(label, fontInfo);
return new SpriteLabel(texture)
}
}
class Ticks {
get reservedPrefixes() {
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
}
get minWidth() {
return 10
}
format(available) {
return { year: '2-digit', timeZone: 'UTC' }
}
get minLabelWidth() {
return 44
}
get formatKey() {
return this.key
}
dateKey(date) {
return this.key + date.getFullYear()
}
*iter(start, end) {
let date = this.iterStart(start);
while (date <= end) {
yield date;
date = this.next(date);
}
yield date;
}
*iterRanges(range) {
for (let date of this.iter(range.start, range.end)) {
let next = this.next(date);
yield { start: date, end: next };
}
}
selectedRange(timeline, info) {
let first = null;
let last = null;
let visibleFirst = null;
let visibleLast = null;
let units = 0;
for (let { start, end } of this.iterRanges(info)) {
if (timeline.visibleRange(start, end)) {
if (first == null) {
first = start;
}
last = end;
}
if (timeline.visibleDate(start) && timeline.visibleDate(end)) {
units += 1;
if (visibleFirst == null) {
visibleFirst = start;
}
visibleLast = end;
}
}
if (first == null)
return info
return { start: first, end: last, visibleStart: visibleFirst, visibleEnd: visibleLast, units: units }
}
drawTick(timeline, x, y, date) {
let visible = date > timeline.start && date < timeline.end;
if (!visible)
return false
timeline.drawTick(x);
return true
}
toLocaleString(date, format) {
return date.toLocaleDateString('de', format)
}
draw(timeline, range, width, height, available, format, nextFormat, level) {
let first = null;
let last = null;
let keyedFormat = (format) ? format[this.formatKey] : null;
let keyedNextFormat = (nextFormat) ? nextFormat[this.formatKey] : null;
let redundant = (nextFormat) ? this.formatKey in nextFormat : false;
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat;
let y = timeline.getY();
for (let { start, end } of this.iterRanges(range)) {
let x = timeline.toX(start);
let xx = x;
let yy = y + timeline.tickLabelOffset(-1);
if (this.drawTick(timeline, x, y, start) && format) {
let key = this.dateKey(start);
let text = this.toLocaleString(start, format);
let align = 'center';
let downTick = false;
if (nextFormat) {
yy = y + timeline.tickLabelOffset(-1, 1);
align = 'left';
timeline.drawTick(x, 4.2);
let nextX = timeline.toX(end) - 100;
if (x < 0 && nextX > -100 && !redundant) {
xx = Math.min(4, nextX);
}
else {
xx -= 2;
}
downTick = true;
}
else if (level > 0) {
xx = x + available / 2;
}
else {
downTick = true;
}
if (!fullyRedundant) {
timeline.ensureLabel(key, text,
{ x: xx, y: yy, align },
FontInfo.small);
}
if (downTick) timeline.drawTick(x, -1);
}
if (timeline.visibleRange(start, end)) {
if (first == null)
first = start;
last = end;
}
}
if (first == null)
return null
return { start: first, end: last }
}
}
class DecadeTicks extends Ticks {
get milliseconds() {
return 10 * 365 * 24 * 60 * 60 * 1000
}
format(available) {
return { year: 'numeric', timeZone: 'UTC' }
}
selection(timeline, dates, selected) {
return dates
}
get key() {
return 'decade'
}
get formatKey() {
return 'year'
}
iterStart(start) {
let modulo = start.getFullYear() % 10;
let year = start.getFullYear() - modulo;
return Dates.create(year, 0, 1)
}
next(decade) {
return Dates.nextYear(decade, 10)
}
}
class YearTicks extends Ticks {
get milliseconds() {
return 365 * 24 * 60 * 60 * 1000
}
format(available) {
if (available < 44)
return { year: '2-digit', timeZone: 'UTC' }
return { year: 'numeric', timeZone: 'UTC' }
}
get minLabelWidth() {
return 22
}
get key() {
return 'year'
}
iterStart(start) {
return Dates.create(start.getFullYear(), 0, 1)
}
next(year) {
return Dates.nextYear(year)
}
}
class MonthTicks extends Ticks {
get milliseconds() {
return (365 / 12) * 24 * 60 * 60 * 1000
}
format(available) {
let format = { month: 'narrow', timeZone: 'UTC' };
if (available > 44)
format.month = 'short';
if (available > 66)
format.year = '2-digit';
if (available > 100) {
format.month = 'long';
format.year = 'numeric';
}
return format
}
get minLabelWidth() {
return 32
}
get key() {
return 'month'
}
dateKey(date) {
return this.key + date.getFullYear() + date.getMonth()
}
iterStart(start) {
return Dates.create(start.getFullYear(), start.getMonth(), 1)
}
next(month) {
return Dates.nextMonth(month)
}
}
class DayTicks extends Ticks {
get milliseconds() {
return 24 * 60 * 60 * 1000
}
format(available) {
let format = { day: 'numeric', timeZone: 'UTC' };
if (available > 44)
format.month = 'short';
if (available > 100) {
format.month = 'long';
format.year = '2-digit';
}
if (available > 150) {
format.weekday = 'short';
}
if (available > 200) {
format.year = 'numeric';
format.weekday = 'long';
}
return format
}
get key() {
return 'day'
}
dateKey(date) {
return this.key + date.getFullYear() + date.getMonth() + date.getDate()
}
iterStart(start) {
return Dates.create(start.getFullYear(), start.getMonth(), start.getDate())
}
next(date) {
return Dates.nextDay(date)
}
}
class TimeTicks {
constructor(...ticks) {
this.ticks = ticks;
}
selectedRange(timeline) {
let info = { start: timeline.start, end: timeline.end, units: 0 };
for (let ticks of this.ticks) {
info = ticks.selectedRange(timeline, info);
if (info.units > 1) {
timeline.selection = [info.visibleStart, info.visibleEnd];
return
}
}
timeline.selection = [info.start, info.end];
}
draw(timeline, width, height) {
let range = timeline;
let start = timeline.toX(range.start);
let end = timeline.toX(range.end);
let size = end - start;
let duration = timeline.end - timeline.start;
let formats = new Map();
let nextFormats = new Map();
let availables = new Map();
let previous = null;
let visible = [];
for (let ticks of this.ticks) {
let amount = ticks.milliseconds / duration;
let available = amount * size;
availables.set(ticks, available);
if (available < ticks.minWidth)
break
formats.set(ticks, (available < ticks.minLabelWidth) ? null : ticks.format(available));
nextFormats.set(previous, formats.get(ticks));
previous = ticks;
visible.push(ticks);
}
let level = 0;
for (let ticks of visible) {
if (range == null)
return
range = ticks.draw(timeline, range, width, height,
availables.get(ticks),
formats.get(ticks),
nextFormats.get(ticks), level);
level += 1;
}
}
}
class ColorRanges {
constructor(label, color, ranges) {
this.label = label;
this.color = color;
this.ranges = ranges;
}
draw(timeline, width, height, size = 12) {
let minimum = 1 / Capabilities.devicePixelRatio;
let h2 = size;
timeline.lineStyle(size, this.color);
for (let range of this.ranges) {
if (range.to === null) {
range.to = Dates.nextDay(range.from);
}
let start = timeline.toX(range.from);
let end = timeline.toX(range.to);
if (end < start + minimum) {
end = start + minimum;
}
timeline.moveTo(start, h2);
timeline.lineTo(end, h2);
}
}
}
class Timeline extends BitmapLabeledGraphics {
constructor(width, height, { ticks = null,
baseLine = 0.5, showRange = true } = {}) {
super();
this.wantedWidth = width;
this.wantedHeight = height;
this.extraLeft = 0;
this.extraRight = 0;
this.inset = 5;
this.showRange = showRange;
this.baseLine = baseLine;
this.tickHeight = 4;
this.zoom = 1;
this.minZoom = 1;
this.maxZoom = 12000;
this.scroll = 0;
this.deltas = [];
this.labelDates = [];
this.colorRanges = [];
this.rangeColors = new Cycle(Colors.eminence,
Colors.steelblue,
Colors.ochre,
Colors.turquoise);
this.callbacks = [];
this.onTapCallbacks = [];
this.onDoubleTapCallbacks = [];
this.onLongPressCallbacks = [];
this.progress = null;
this.start = null;
this.end = null;
this.selection = null;
this.autoScroll = false;
this.direction = -1;
this.timeticks = ticks || new TimeTicks(new DecadeTicks(),
new YearTicks(),
new MonthTicks(),
new DayTicks());
this.labelPrefix = '__';
}
updateSelection() {
if (this.visibleDate(this.start) && this.visibleDate(this.end)) {
this.selection = [this.start, this.end];
}
else {
this.timeticks.selectedRange(this);
}
return this.selection
}
addCallback(callback) {
this.callbacks.push(callback);
}
addTabCallback(callback) {
this.onTapCallbacks.push(callback);
}
addDoubleTapCallback(callback) {
this.onDoubleTapCallbacks.push(callback);
}
addLongPressCallback(callback) {
this.onLongPressCallbacks.push(callback);
}
addLabels(labels) {
this.labelDates = labels;
}
range(start, end) {
this.start = start;
this.end = end;
}
draw(width, height) {
this.wantedWidth = width;
this.wantedHeight = height;
this.redraw();
}
updateColorRanges(w, h) {
let xx = w - this.inset;
let size = FontInfo.small.fontSize;
let yy = h - size;
for (let i = this.colorRanges.length - 1; i >= 0; i--) {
let cr = this.colorRanges[i];
let label = cr.label;
cr.draw(this, w, h);
let current = this.ensureLabel('colorRange:' + label, label,
{ x: xx, y: yy, align: 'right' }, FontInfo.small);
let r = current.getBounds();
xx -= r.width + 16;
this.lineStyle(size, cr.color);
this.moveTo(xx, yy);
this.lineTo(xx + size, yy);
xx -= size + 4;
}
}
drawSelectedRamge(selected) {
this.lineStyle(2, app.theme.primaryColor);
let start = this.toX(selected[0]);
let end = this.toX(selected[1]);
this.moveTo(start, 0);
this.lineTo(end, 0);
this.drawTick(start, -1.5, 0);
this.drawTick(end, -1.5, 0);
}
redraw() {
this.clear();
let h = this.wantedHeight;
let w = this.wantedWidth;
let y = this.getY();
this.prepareLabels();
this.updateColorRanges(w, h);
this.lineStyle(2, 0xFFFFFF);
if (this.start != null && this.end != null) {
this.moveTo(this.toX(this.start), y);
this.lineTo(this.toX(this.end), y);
this.updateTicksAndLabels(w, h);
this.updateSelection();
let selected = this.selection;
if (selected[0] != this.start && selected[1] != this.end) {
if (this.showRange)
this.drawSelectedRamge(selected);
}
for (let callback of this.callbacks) {
callback(this.scroll, this.zoom, this.selection);
}
}
else {
this.moveTo(this.inset, y);
this.lineTo(w - this.inset, y);
}
if (this.progress != null && this.progress < 1) {
this.lineStyle(2, 0xCCCCFF);
this.moveTo(this.inset, y);
this.lineTo((w - this.inset) * this.progress, y);
}
}
totalWidth(bounded = false) {
let w = this.wantedWidth - (2 * this.inset);
return w * this.validZoom(this.zoom, bounded)
}
validZoom(zoom, bounded = true) {
let overshoot = (bounded) ? 1.0 : 2.0;
zoom = Math.max(zoom, this.minZoom / overshoot);
zoom = Math.min(zoom, this.maxZoom * overshoot);
return zoom
}
getY() {
return this.wantedHeight * this.baseLine
}
toX(date) {
let total = this.end - this.start;
let offset = this.inset + this.scroll;
let width = this.totalWidth();
let delta = date - this.start;
let ratio = delta / total;
return offset + ratio * width
}
fromX(value) {
let total = this.end - this.start;
let offset = this.inset + this.scroll;
let width = this.totalWidth();
let ratio = (value - offset) / width;
let time = this.start.getTime() + total * ratio;
let date = new Date(time);
return date
}
drawTick(x, direction = 1, y = null) {
if (y == null) {
y = this.getY();
}
this.moveTo(x, y);
this.lineTo(x, y - (this.tickHeight * direction * this.direction));
}
prepareLabels() {
for (let key of this.labels.keys()) {
if (!key.startsWith(this.labelPrefix))
this.labels.get(key).visible = false;
}
}
updateTicksAndLabels(width, height) {
this.drawTick(this.toX(this.start));
this.drawTick(this.toX(this.end));
this.timeticks.draw(this, width, height);
this.updateLabels(width, height);
}
visibleDate(date, offset = 0) {
if (date >= this.start && date <= this.end) {
let x = this.toX(date) + offset;
return (x > 0 && x < this.wantedWidth)
}
return false
}
visibleRange(start, end) {
let x = this.toX(start);
if (x > this.wantedWidth)
return false
x = this.toX(end);
if (x < 0)
return false
return true
}
tickLabelOffset(direction = 1, level = 0) {
let fs = FontInfo.small.fontSize;
let dh = fs + (level * (fs + 2));
return this.direction * direction * dh
}
updateLabels(width, height) {
let h2 = height / 2;
if (this.labelDates) {
let last = null;
let y = h2 + this.tickLabelOffset();
for (let i = this.labelDates.length - 1; i >= 0; i--) {
let [label, date] = this.labelDates[i];
let align = 'center'; // (last == null) ? 'right' : 'left'
let x = this.toX(date);
let current = this.ensureLabel(this.labelPrefix + label, label,
{
x: x, y: y,
align
},
FontInfo.small);
let r = current.getBounds();
current.visible = !(last != null && r.x + r.width > last.x);
if (current.visible) {
this.drawTick(x, -1);
last = r;
}
}
}
else {
let start = this.start.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' });
let end = this.end.toLocaleDateString('de', { year: 'numeric', month: 'numeric', day: 'numeric' });
this.ensureLabel(this.labelPrefix + 'start', start, { x: this.toX(this.start), y: h2 });
this.ensureLabel(this.labelPrefix + 'end', end, { x: this.toX(this.end), y: h2, align: 'right' });
}
}
onZoom(zoom, anchor) {
let date = this.fromX(anchor.x);
let newZoom = this.validZoom(this.zoom * zoom, false);
this.zoom = newZoom;
let newX = this.toX(date);
this.scroll += anchor.x - newX;
}
onStart(event, interaction) {
this.killTweens();
this.deltas = [];
this.validScroll();
ThrowPropsPlugin.track(this, 'delta');
}
onMove(event, interaction) {
let delta = interaction.delta();
this.scroll += delta.x;
while (this.deltas.length > 10) {
this.deltas.pop(0);
}
this.deltas.push(delta.x);
if (interaction.current.size > 1) {
this.onZoom(delta.zoom, delta.about);
}
this.redraw();
}
onEnd(event, interaction) {
let vel = ThrowPropsPlugin.getVelocity(this, 'delta');
ThrowPropsPlugin.untrack(this);
this.killTweens();
this.redraw();
let delta = 0;
for (let d of this.deltas) {
delta += d;
}
if (this.deltas.length > 0) {
delta /= this.deltas.length;
}
this.autoScroll = true;
let anchor = interaction.current.mean();
this.keepInBounds(delta, anchor);
for(let key of interaction.ended.keys()) {
if (interaction.isDoubleTap(key)) {
this.onDoubleTap(event, interaction, key);
}
else if (interaction.isTap(key)) {
this.onTap(event, interaction, key);
}
else if (interaction.isLongPress(key)) {
this.onLongPress(event, interaction, key);
}
}
}
onLongPress(event, interaction, key) {
for(let callback of this.onLongPressCallbacks) {
callback(event, interaction, key);
}
}
onTap(event, interaction, key) {
for(let callback of this.onTapCallbacks) {
callback(event, interaction, key);
}
}
onDoubleTap(event, interaction, key) {
for(let callback of this.onDoubleTapCallbacks) {
callback(event, interaction, key);
}
}
_scrollMinimum(bounded) {
let total = this.totalWidth(bounded);
return -total + this.wantedWidth - 2 * this.inset
}
_scrollMaximum(bounded) {
let total = this.totalWidth(bounded);
let limit = this.wantedWidth;
if (total > limit)
return 0
let w = limit - 2 * this.inset;
return (w - total) / 2
}
scrollMinimum(bounded) {
return this._scrollMinimum(bounded) - this.extraRight
}
scrollMaximum(bounded) {
return this._scrollMaximum(bounded) + this.extraLeft
}
killTweens() {
TweenLite.killTweensOf(this);
this.autoScroll = false;
}
validScroll(bounded = true) {
let minimum = this.scrollMinimum(bounded);
let maximum = this.scrollMaximum(bounded);
if (this.scroll < minimum) {
this.scroll = minimum;
}
if (this.scroll > maximum) {
this.scroll = maximum;
}
}
keepInBounds(delta, anchor) {
let bounded = true;
let minimum = this.scrollMinimum(bounded);
let maximum = this.scrollMaximum(bounded);
let tweens = {};
if (this.zoom > this.maxZoom) {
tweens.zoom = this.maxZoom;
let date = this.fromX(anchor.x);
let oldZoom = this.zoom;
this.zoom = this.maxZoom;
let newX = this.toX(date);
tweens.scroll = this.scroll + anchor.x - newX;
this.zoom = oldZoom;
}
else {
if (this.zoom < this.minZoom) {
tweens.zoom = this.minZoom;
}
if (this.scroll > maximum) {
tweens.scroll = maximum;
}
if (this.scroll < minimum) {
tweens.scroll = minimum;
}
}
if (!isEmpty(tweens)) {
tweens.onUpdate = () => { this.redraw(); };
TweenLite.to(this, 0.5, tweens).delay(0.1);
return
}
this.scroll += delta;
delta *= 0.985;
this.redraw();
if (Math.abs(delta) > 1 && this.autoScroll) {
setTimeout(() => this.keepInBounds(delta, anchor), 1000 / 100);
}
}
onMouseWheel(event) {
this.killTweens();
let direction = event.detail < 0 || event.wheelDelta > 0;
let anchor = { x: event.clientX, y: event.clientY };
const zoomFactor = 1.5;
this.onZoom((direction) ? zoomFactor : 1 / zoomFactor, anchor);
this.redraw();
this.keepInBounds(0, anchor);
}
showRanges(ranges, label = "Untitled", color = null) {
for (let cr of this.colorRanges) {
if (cr.label == label)
return
}
while (this.colorRanges.length >= this.rangeColors.length) {
this.colorRanges.shift();
}
this.colorRanges.push(new ColorRanges(label, color, ranges));
this.redraw();
}
}
/**
* Callback for the slider action onStart.
*
* @callback onStartCallback
* @param {object} event - The event object.
* @param {Slider} slider - A reference to the slider (also this refers to the slider).
*/
/**
* Callback for the slider action onUpdate.
*
* @callback onUpdateCallback
* @param {object} event - The event object.
* @param {Slider} slider - A reference to the slider (also this refers to the slider).
*/
/**
* Callback for the slider action onComplete.
*
* @callback onCompleteCallback
* @param {object} event - The event object.
* @param {Slider} slider - A reference to the slider (also this refers to the slider).
*/
/**
* Class that represents a PixiJS Slider.
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* // Create the slider
* const slider = new Slider({
* x: 10,
* y: 20
* })
*
* // Add the slider to a DisplayObject
* app.scene.addChild(slider)
*
* @class
* @extends PIXI.Container
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/slider.html|DocTest}
*/
class Slider extends PIXI.Container {
/**
* Creates an instance of a Slider.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the slider.
* @param {number} [opts.id=auto generated] - The id of the slider.
* @param {number} [opts.x=0] - The x position of the slider. Can be also set after creation with slider.x = 0.
* @param {number} [opts.y=0] - The y position of the slider. Can be also set after creation with slider.y = 0.
* @param {string|Theme} [opts.theme=dark] - The theme to use for this slider. Possible values are dark, light, red
* or a Theme object.
* @param {number} [opts.width=250] - The width of the slider.
* @param {number} [opts.height=2] - The height of the slider.
* @param {PIXI.DisplayObject} [opts.container=window.app|object] - The container where the slider events should be attached to.
* @param {number} [opts.fill=Theme.fill] - The color of the slider background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=Theme.strokeWidth] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.controlFill=Theme.stroke] - The color of the slider control background as a hex value.
* @param {number} [opts.controlFillAlpha=Theme.strokeAlpha] - The alpha value of the background.
* @param {number} [opts.controlStroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.controlStrokeWidth=Theme.strokeWidth * 0.8] - The width of the border in pixel.
* @param {number} [opts.controlStrokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.controlRadius=16] - The radius of the slider control.
* @param {boolean} [opts.disabled=false] - Is the slider disabled? When disabled, the slider has a lower alpha value
* and cannot be clicked (interactive is set to false).
* @param {onStartCallback} [opts.onStart] - Executed when the slider control starts to move.
* @param {onUpdateCallback} [opts.onUpdate] - Executed when the slider control is moved.
* @param {onCompleteCallback} [opts.onComplete] - Executed when the slider control was dropped.
* @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip
* to display.
* @param {boolean} [opts.visible=true] - Is the slider initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
x: 0,
y: 0,
width: 250,
height: 2,
container: null,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
stroke: theme.stroke,
strokeWidth: theme.strokeWidth,
strokeAlpha: theme.strokeAlpha,
controlFill: theme.fill,
controlFillAlpha: .5,
controlStroke: theme.primaryColor,
controlStrokeWidth: 2,
controlStrokeAlpha: theme.strokeAlpha,
controlRadius: 16,
orientation: 'horizontal',
min: 0,
max: 100,
value: 0,
disabled: false,
onStart: null,
onUpdate: null,
onComplete: null,
tooltip: null,
visible: true
}, opts);
this.opts.container = this.opts.container || this;
// Validation
//-----------------
if (this.opts.height > this.opts.width) {
this.opts.height = this.opts.width;
}
if (this.opts.value < this.opts.min) {
this.opts.value = this.opts.min;
}
if (this.opts.value > this.opts.max) {
this.opts.value = this.opts.max;
}
// Properties
//-----------------
this.id = this.opts.id;
this.radius = this.opts.height / 2;
this._value = this.opts.value;
this._disabled = null;
this.sliderObj = null;
this.control = null;
this.tooltip = null;
this.visible = this.opts.visible;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Slider} A reference to the slider for chaining.
*/
setup() {
// Container events
//-----------------
const container = this.opts.container;
this.on('pointermove', e => {
if (this.control.dragging) {
const moveX = this.control.event.data.getLocalPosition(this.control.parent).x;
this._value = this.pixelToValue(moveX - this.control.delta - this.opts.controlRadius);
let x = this.valueToPixel(this._value) + this.opts.controlRadius;
this.control.x = x;
if (this.opts.onUpdate) {
this.opts.onUpdate.call(this, e, this);
}
}
});
if (container instanceof Element) {
container.addEventListener('pointerup', e => this.onEnd(e), false);
container.addEventListener('pointercancel', e => this.onEnd(e), false);
container.addEventListener('pointerleave', e => this.onEnd(e), false);
container.addEventListener('pointerout', e => this.onEnd(e), false);
container.addEventListener('mouseup', e => this.onEnd(e), false);
container.addEventListener('mousecancel', e => this.onEnd(e), false);
container.addEventListener('mouseleave', e => this.onEnd(e), false);
container.addEventListener('mouseout', e => this.onEnd(e), false);
} else {
container.interactive = true;
container.on('pointerup', e => this.onEnd(e));
container.on('pointercancel', e => this.onEnd(e));
container.on('pointerleave', e => this.onEnd(e));
container.on('pointerout', e => this.onEnd(e));
}
// Slider
//-----------------
let sliderObj = new PIXI.Graphics();
this.sliderObj = sliderObj;
this.addChild(sliderObj);
// Control
//-----------------
let control = new PIXI.Graphics();
control.x = this.opts.controlRadius + this.valueToPixel(this.opts.value);
control.y = this.opts.controlRadius;
// pointerdown on the control for dragndrop
control.on('pointerdown', e => {
control.event = e;
control.delta = e.data.getLocalPosition(this.control).x;
control.dragging = true;
if (this.opts.onStart) {
this.opts.onStart.call(this, e, this);
}
});
this.control = control;
this.addChild(this.control);
// interaction
//-----------------
this.sliderObj.on('pointerover', e => {
TweenLite.to(this.control, this.theme.fast, {alpha: .83});
});
this.sliderObj.on('pointerout', e => {
TweenLite.to(this.control, this.theme.fast, {alpha: 1});
});
this.sliderObj.on('pointerdown', e => {
this.sliderObj.pointerdowned = true;
TweenLite.to(this.control, this.theme.fast, {alpha: .7});
});
// Click on the slider bar
this.sliderObj.on('pointerup', e => {
if (this.sliderObj.pointerdowned) {
this.sliderObj.pointerdowned = false;
const position = e.data.getLocalPosition(this.control.parent);
this.value = this.pixelToValue(position.x - this.opts.controlRadius);
TweenLite.to(this.control, this.theme.fast, {alpha: .83});
}
});
// disabled
//-----------------
this.disabled = this.opts.disabled;
// tooltip
//-----------------
if (this.opts.tooltip) {
if (typeof this.opts.tooltip === 'string') {
this.tooltip = new Tooltip({
object: this,
content: this.opts.tooltip
});
} else {
this.opts.tooltip.object = this;
this.tooltip = new Tooltip(this.opts.tooltip);
}
}
return this
}
/**
* Should be called to refresh the layout of the slider. Can be used after resizing.
*
* @return {Slider} A reference to the slider for chaining.
*/
layout() {
// set position
//-----------------
this.position.set(this.opts.x, this.opts.y);
// draw
//-----------------
this.draw();
return this
}
/**
* Draws the slider to the canvas.
*
* @private
* @return {Slider} A reference to the slider for chaining.
*/
draw() {
const r = this.radius;
const cr = this.opts.controlRadius;
const w = this.opts.width;
const h = this.opts.height;
const x = cr + r;
const y = cr + r - h;
this.sliderObj.clear();
this.sliderObj.beginFill(0xffffff, 0);
this.sliderObj.drawRect(0, 0, x + w + cr, cr * 2);
this.sliderObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.sliderObj.beginFill(this.opts.fill, this.opts.fillAlpha);
this.sliderObj.moveTo(x, y);
this.sliderObj.lineTo(x + w, y);
this.sliderObj.arcTo(x + w + r, y, x + w + r, y + r, r);
this.sliderObj.lineTo(x + w + r, y + r + 1); // BUGFIX: If not specified, there is a small area without a stroke.
this.sliderObj.arcTo(x + w + r, y + h, x + w, y + h, r);
this.sliderObj.lineTo(x, y + h);
this.sliderObj.arcTo(x - r, y + h, x - r, y + r, r);
this.sliderObj.arcTo(x - r, y, x, y, r);
this.sliderObj.endFill();
// Draw control
this.control.clear();
this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha);
this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha);
this.control.drawCircle(0, 0, cr - 1);
this.control.beginFill(this.opts.controlStroke, this.opts.controlStrokeAlpha);
this.control.drawCircle(0, 0, cr / 6);
this.control.endFill();
return this
}
/**
* Executed, when the slider control movement ended.
*
* @private
* @return {Slider} A reference to the slider for chaining.
*/
onEnd(e) {
if (this.control.dragging) {
this.control.event = null;
this.control.dragging = false;
if (this.opts.onComplete) {
this.opts.onComplete.call(this, e, this);
}
}
return this
}
/**
* Calculates the value for a given pixel.
*
* @private
* @param {number} value
* @returns {number} The calucalted pixel.
*/
valueToPixel(value) {
if (value < this.opts.min) {
value = this.opts.min;
} else if (value > this.opts.max) {
value = this.opts.max;
}
return this.opts.width * (value - this.opts.min) / (this.opts.max - this.opts.min)
}
/**
* Calculates the pixel for a given value.
*
* @private
* @param {number} pixel
* @returns {number} The calucalted value.
*/
pixelToValue(pixel) {
if (pixel < 0) {
pixel = 0;
} else if (pixel > this.opts.width) {
pixel = this.opts.width;
}
return this.opts.min + ((this.opts.max - this.opts.min) * pixel / this.opts.width)
}
/**
* Gets or sets the value.
*
* @member {number}
*/
get value() {
return Math.round(this._value)
}
set value(value) {
if (value < this.opts.min) {
value = this.opts.min;
} else if (value > this.opts.max) {
value = this.opts.max;
}
this._value = value;
const x = this.valueToPixel(value) + this.opts.controlRadius;
TweenLite.to(this.control, this.theme.fast, {x});
}
/**
* Gets or sets the disabled state. When disabled, the slider cannot be clicked.
*
* @member {boolean}
*/
get disabled() {
return this._disabled
}
set disabled(value) {
this._disabled = value;
if (this._disabled) {
this.interactive = false;
this.sliderObj.interactive = false;
this.control.interactive = false;
this.control.buttonMode = false;
this.alpha = .5;
} else {
this.interactive = true;
this.sliderObj.interactive = true;
this.control.interactive = true;
this.control.buttonMode = true;
this.alpha = 1;
}
}
/**
* Shows the slider (sets his alpha values to 1).
*
* @return {Slider} A reference to the slider for chaining.
*/
show() {
this.opts.strokeAlpha = 1;
this.opts.fillAlpha = 1;
this.opts.controlStrokeAlpha = 1;
this.opts.controlFillAlpha = 1;
this.layout();
return this
}
/**
* Hides the slider (sets his alpha values to 1).
*
* @return {Slider} A reference to the slider for chaining.
*/
hide() {
this.opts.strokeAlpha = 0;
this.opts.fillAlpha = 0;
this.opts.controlStrokeAlpha = 0;
this.opts.controlFillAlpha = 0;
this.layout();
return this
}
}
/**
* Callback for the switch action.
*
* @callback actionCallback
* @param {object} event - The event object.
* @param {Switch} switch - A reference to the switch (also this refers to the switch).
*/
/**
* Callback for the switch action.
*
* @callback actionActiveCallback
* @param {object} event - The event object.
* @param {Switch} switch - A reference to the switch (also this refers to the switch).
*/
/**
* Callback for the switch beforeAction.
*
* @callback beforeActionCallback
* @param {object} event - The event object.
* @param {Switch} switch - A reference to the switch (also this refers to the switch).
*/
/**
* Callback for the switch afterAction.
*
* @callback afterActionCallback
* @param {object} event - The event object.
* @param {Switch} switch - A reference to the switch (also this refers to the switch).
*/
/**
* Class that represents a PixiJS Switch.
*
* @example
* // Create the app
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* // Create the switch
* const switch1 = new Switch({
* x: 10,
* y: 20
* })
*
* // Add the switch to a DisplayObject
* app.scene.addChild(switch1)
*
* @class
* @extends PIXI.Container
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PIXI.Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/switch.html|DocTest}
*/
class Switch extends PIXI.Container {
/**
* Creates an instance of a Switch.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the switch.
* @param {number} [opts.id=auto generated] - The id of the switch.
* @param {number} [opts.x=0] - The x position of the switch. Can be also set after creation with switch.x = 0.
* @param {number} [opts.y=0] - The y position of the switch. Can be also set after creation with switch.y = 0.
* @param {string|Theme} [opts.theme=dark] - The theme to use for this switch. Possible values are dark, light, red
* or a Theme object.
* @param {number} [opts.width=44] - The width of the switch.
* @param {number} [opts.height=28] - The height of the switch.
* @param {number} [opts.fill=Theme.fill] - The color of the switch background as a hex value.
* @param {number} [opts.fillAlpha=Theme.fillAlpha] - The alpha value of the background.
* @param {number} [opts.fillActive=Theme.fillActive] - The color of the switch background when activated.
* @param {number} [opts.fillActiveAlpha=Theme.fillActiveAlpha] - The alpha value of the background when activated.
* @param {number} [opts.stroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.strokeWidth=Theme.strokeWidth] - The width of the border in pixel.
* @param {number} [opts.strokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.strokeActive=Theme.strokeActive] - The color of the border when activated.
* @param {number} [opts.strokeActiveWidth=Theme.strokeActiveWidth] - The width of the border in pixel when activated.
* @param {number} [opts.strokeActiveAlpha=Theme.strokeActiveAlpha] - The alpha value of the border when activated.
* @param {number} [opts.controlFill=Theme.stroke] - The color of the switch control background as a hex value.
* @param {number} [opts.controlFillAlpha=Theme.strokeAlpha] - The alpha value of the background.
* @param {number} [opts.controlFillActive=Theme.stroke] - The color of the switch control background when activated.
* @param {number} [opts.controlFillActiveAlpha=Theme.strokeAlpha] - The alpha value of the background when activated.
* @param {number} [opts.controlStroke=Theme.stroke] - The color of the border as a hex value.
* @param {number} [opts.controlStrokeWidth=Theme.strokeWidth * 0.8] - The width of the border in pixel.
* @param {number} [opts.controlStrokeAlpha=Theme.strokeAlpha] - The alpha value of the border.
* @param {number} [opts.controlStrokeActive=Theme.stroke] - The color of the border when activated.
* @param {number} [opts.controlStrokeActiveWidth=Theme.strokeActiveWidth * 0.8] - The width of the border in pixel when activated.
* @param {number} [opts.controlStrokeActiveAlpha=Theme.strokeActiveAlpha] - The alpha value of the border when activated.
* @param {number} [opts.duration=Theme.fast] - The duration of the animation when the switch gets activated in seconds.
* @param {number} [opts.durationActive=Theme.fast] - The duration of the animation when the switch gets deactivated in seconds.
* @param {boolean} [opts.disabled=false] - Is the switch disabled? When disabled, the switch has a lower alpha value
* and cannot be clicked (interactive is set to false).
* @param {boolean} [opts.active=false] - Is the button initially active?
* @param {actionCallback} [opts.action] - Executed when the switch was triggered in inactive state (by pointerup).
* @param {actionActiveCallback} [opts.actionActive] - Executed when the button was triggered in active state (by pointerup).
* @param {beforeActionCallback} [opts.beforeAction] - Executed before an action is triggered.
* @param {afterActionCallback} [opts.afterAction] - Executed after an action was triggered.
* @param {string|object} [opts.tooltip] - A string for the label of the tooltip or an object to configure the tooltip
* to display.
* @param {boolean} [opts.visible=true] - Is the switch initially visible (property visible)?
*/
constructor(opts = {}) {
super();
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
x: 0,
y: 0,
width: 44,
height: 28,
fill: theme.fill,
fillAlpha: theme.fillAlpha,
fillActive: theme.primaryColor,
fillActiveAlpha: theme.fillActiveAlpha,
stroke: theme.stroke,
strokeWidth: theme.strokeWidth,
strokeAlpha: theme.strokeAlpha,
strokeActive: theme.primaryColor,
strokeActiveWidth: theme.strokeActiveWidth,
strokeActiveAlpha: theme.strokeActiveAlpha,
controlFill: theme.stroke,
controlFillAlpha: theme.strokeAlpha,
controlFillActive: theme.stroke,
controlFillActiveAlpha: theme.strokeAlpha,
controlStroke: theme.stroke,
controlStrokeWidth: theme.strokeWidth * .8,
controlStrokeAlpha: theme.strokeAlpha,
controlStrokeActive: theme.stroke,
controlStrokeActiveWidth: theme.strokeActiveWidth * .8,
controlStrokeActiveAlpha: theme.strokeActiveAlpha,
duration: theme.fast,
durationActive: theme.fast,
disabled: false,
active: false,
action: null,
actionActive: null,
beforeAction: null,
afterAction: null,
tooltip: null,
visible: true
}, opts);
this.opts.controlRadius = this.opts.controlRadius || (this.opts.height / 2);
this.opts.controlRadiusActive = this.opts.controlRadiusActive || this.opts.controlRadius;
// Validation
//-----------------
if (this.opts.height > this.opts.width) {
this.opts.height = this.opts.width;
}
// Properties
//-----------------
this.id = this.opts.id;
this.radius = this.opts.height / 2;
this._active = null;
this._disabled = null;
this.switchObj = null;
this.control = null;
this.tooltip = null;
this.visible = this.opts.visible;
// animated
//-----------------
this.tempAnimated = {
fill: this.opts.fill,
fillAlpha: this.opts.fillAlpha,
stroke: this.opts.stroke,
strokeWidth: this.opts.strokeWidth,
strokeAlpha: this.opts.strokeAlpha,
controlFill: this.opts.controlFill,
controlFillAlpha: this.opts.controlFillAlpha,
controlStroke: this.opts.controlStroke,
controlStrokeWidth: this.opts.controlStrokeWidth,
controlStrokeAlpha: this.opts.controlStrokeAlpha,
controlRadius: this.opts.controlRadius
};
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Switch} A reference to the switch for chaining.
*/
setup() {
// Switch
//-----------------
let switchObj = new PIXI.Graphics();
this.switchObj = switchObj;
this.addChild(switchObj);
// Control
//-----------------
this.xInactive = this.opts.controlRadius;
this.xActive = this.opts.width - this.opts.controlRadiusActive;
let control = new PIXI.Graphics();
control.x = this.opts.active ? this.xActive : this.xInactive;
control.y = this.opts.height / 2;
this.control = control;
this.addChild(this.control);
// interaction
//-----------------
this.switchObj.on('pointerover', e => {
TweenLite.to(this.control, this.theme.fast, {alpha: .83});
});
this.switchObj.on('pointerout', e => {
TweenLite.to(this.control, this.theme.fast, {alpha: 1});
});
this.switchObj.on('pointerdown', e => {
TweenLite.to(this.control, this.theme.fast, {alpha: .7});
});
this.switchObj.on('pointerup', e => {
if (this.opts.beforeAction) {
this.opts.beforeAction.call(this, e, this);
}
this.active = !this.active;
if (this.active) {
if (this.opts.action) {
this.opts.action.call(this, e, this);
}
} else {
if (this.opts.actionActive) {
this.opts.actionActive.call(this, e, this);
}
}
TweenLite.to(this.control, this.theme.fast, {alpha: .83});
if (this.opts.afterAction) {
this.opts.afterAction.call(this, e, this);
}
});
// disabled
//-----------------
this.disabled = this.opts.disabled;
// active
//-----------------
this.active = this.opts.active;
// tooltip
//-----------------
if (this.opts.tooltip) {
if (typeof this.opts.tooltip === 'string') {
this.tooltip = new Tooltip({
object: this,
content: this.opts.tooltip
});
} else {
this.opts.tooltip.object = this;
this.tooltip = new Tooltip(this.opts.tooltip);
}
}
return this
}
/**
* Should be called to refresh the layout of the switch. Can be used after resizing.
*
* @return {Switch} A reference to the switch for chaining.
*/
layout() {
// set position
//-----------------
this.position.set(this.opts.x, this.opts.y);
// draw
//-----------------
this.draw();
return this
}
/**
* Draws the switch to the canvas.
*
* @private
* @return {Switch} A reference to the switch for chaining.
*/
draw() {
this.switchObj.clear();
if (this.active) {
this.switchObj.lineStyle(this.opts.strokeActiveWidth, this.opts.strokeActive, this.opts.strokeActiveAlpha);
this.switchObj.beginFill(this.opts.fillActive, this.opts.fillActiveAlpha);
} else {
this.switchObj.lineStyle(this.opts.strokeWidth, this.opts.stroke, this.opts.strokeAlpha);
this.switchObj.beginFill(this.opts.fill, this.opts.fillAlpha);
}
this.switchObj.moveTo(this.radius, 0);
this.switchObj.lineTo(this.opts.width - this.radius, 0);
this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius);
this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke.
this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius);
this.switchObj.lineTo(this.radius, this.opts.height);
this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius);
this.switchObj.arcTo(0, 0, this.radius, 0, this.radius);
this.switchObj.endFill();
// Draw control
this.control.clear();
if (this.active) {
this.control.lineStyle(this.opts.controlStrokeActiveWidth, this.opts.controlStrokeActive, this.opts.controlStrokeActiveAlpha);
this.control.beginFill(this.opts.controlFillActive, this.opts.controlFillActiveAlpha);
this.control.drawCircle(0, 0, this.opts.controlRadiusActive - 1);
} else {
this.control.lineStyle(this.opts.controlStrokeWidth, this.opts.controlStroke, this.opts.controlStrokeAlpha);
this.control.beginFill(this.opts.controlFill, this.opts.controlFillAlpha);
this.control.drawCircle(0, 0, this.opts.controlRadius - 1);
}
this.control.endFill();
return this
}
/**
* Draws the animation.
*
* @private
* @return {Switch} A reference to the switch for chaining.
*/
drawAnimated() {
this.switchObj.clear();
this.switchObj.lineStyle(this.tempAnimated.strokeWidth, this.tempAnimated.stroke, this.tempAnimated.strokeAlpha);
this.switchObj.beginFill(this.tempAnimated.fill, this.tempAnimated.fillAlpha);
this.switchObj.moveTo(this.radius, 0);
this.switchObj.lineTo(this.opts.width - this.radius, 0);
this.switchObj.arcTo(this.opts.width, 0, this.opts.width, this.radius, this.radius);
this.switchObj.lineTo(this.opts.width, this.radius + 1); // BUGFIX: If not specified, there is a small area without a stroke.
this.switchObj.arcTo(this.opts.width, this.opts.height, this.opts.width - this.radius, this.opts.height, this.radius);
this.switchObj.lineTo(this.radius, this.opts.height);
this.switchObj.arcTo(0, this.opts.height, 0, this.radius, this.radius);
this.switchObj.arcTo(0, 0, this.radius, 0, this.radius);
this.switchObj.endFill();
this.control.clear();
this.control.lineStyle(this.tempAnimated.controlStrokeWidth, this.tempAnimated.controlStroke, this.tempAnimated.controlStrokeAlpha);
this.control.beginFill(this.tempAnimated.controlFill, this.tempAnimated.controlFillAlpha);
this.control.drawCircle(0, 0, this.tempAnimated.controlRadius - 1);
this.control.endFill();
return this
}
/**
* Gets or sets the active state.
*
* @member {boolean}
*/
get active() {
return this._active
}
set active(value) {
this._active = value;
if (this._active) {
TweenLite.to(this.control, this.opts.duration, {x: this.xActive});
TweenLite.to(this.tempAnimated, this.opts.duration, {
colorProps: {
fill: this.opts.fillActive,
stroke: this.opts.strokeActive,
controlFill: this.opts.controlFillActive,
controlStroke: this.opts.controlStrokeActive,
format: 'number'
},
fillAlpha: this.opts.fillActiveAlpha,
strokeWidth: this.opts.strokeActiveWidth,
strokeAlpha: this.opts.strokeActiveAlpha,
controlFillAlpha: this.opts.controlFillActiveAlpha,
controlStrokeWidth: this.opts.controlStrokeActiveWidth,
controlStrokeAlpha: this.opts.controlStrokeActiveAlpha,
controlRadius: this.opts.controlRadiusActive,
onUpdate: () => this.drawAnimated(),
onComplete: () => this.draw()
});
} else {
TweenLite.to(this.control, this.opts.durationActive, {x: this.xInactive});
TweenLite.to(this.tempAnimated, this.opts.durationActive, {
colorProps: {
fill: this.opts.fill,
stroke: this.opts.stroke,
controlFill: this.opts.controlFill,
controlStroke: this.opts.controlStroke,
format: 'number'
},
fillAlpha: this.opts.fillAlpha,
strokeWidth: this.opts.strokeWidth,
strokeAlpha: this.opts.strokeAlpha,
controlFillAlpha: this.opts.controlFillAlpha,
controlStrokeWidth: this.opts.controlStrokeWidth,
controlStrokeAlpha: this.opts.controlStrokeAlpha,
controlRadius: this.opts.controlRadius,
onUpdate: () => this.drawAnimated(),
onComplete: () => this.draw()
});
}
}
/**
* Gets or sets the disabled state. When disabled, the switch cannot be clicked.
*
* @member {boolean}
*/
get disabled() {
return this._disabled
}
set disabled(value) {
this._disabled = value;
if (this._disabled) {
this.switchObj.interactive = false;
this.switchObj.buttonMode = false;
this.switchObj.alpha = .5;
this.control.alpha = .5;
} else {
this.switchObj.interactive = true;
this.switchObj.buttonMode = true;
this.switchObj.alpha = 1;
this.control.alpha = 1;
}
}
/**
* Shows the switch (sets his alpha values to 1).
*
* @return {Switch} A reference to the switch for chaining.
*/
show() {
this.opts.strokeAlpha = 1;
this.opts.strokeActiveAlpha = 1;
this.opts.fillAlpha = 1;
this.opts.fillActiveAlpha = 1;
this.opts.controlStrokeAlpha = 1;
this.opts.controlStrokeActiveAlpha = 1;
this.opts.controlFillAlpha = 1;
this.opts.controlFillActiveAlpha = 1;
this.layout();
return this
}
/**
* Hides the switch (sets his alpha values to 1).
*
* @return {Switch} A reference to the switch for chaining.
*/
hide() {
this.opts.strokeAlpha = 0;
this.opts.strokeActiveAlpha = 0;
this.opts.fillAlpha = 0;
this.opts.fillActiveAlpha = 0;
this.opts.controlStrokeAlpha = 0;
this.opts.controlStrokeActiveAlpha = 0;
this.opts.controlFillAlpha = 0;
this.opts.controlFillActiveAlpha = 0;
this.layout();
return this
}
}
/**
* Class that represents a PixiJS PopupMenu.
*
* @example
* // Create the button and the modal when clicked
* const button = new Button({
* label: 'Show PopupMenu',
* action: e => {
* const popupmenu = new PopupMenu({
* items: [
* {label: 'Save', action: () => alert('Saved')},
* {label: 'Edit', action: () => alert('Edited')},
* {label: 'Delete', action: () => alert('Deleted')}
* ]
* })
* app.scene.addChild(popupmenu)
* }
* })
*
* // Add the button to a DisplayObject
* app.scene.addChild(button)
*
* @class
* @extends Popup
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/popupmenu.html|DocTest}
*/
class PopupMenu$1 extends Popup {
/**
* Creates an instance of a PopupMenu.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the modal.
* @param {object[]} [opts.items=[]] - A list of the menu items. Each item must be of type object.
* If an object has a label property, a PIXI.Text object is created (using the textStyle property).
* If an object hasn't a label property, it must contain a content property which has to be a
* PIXI.DisplayObject.
* @param {number} [opts.margin=Theme.margin / 2] - The app where the modal belongs to.
* @param {object} [opts.textStyle=Theme.textStyle] - The color of the background.
* @param {boolean} [opts.closeOnPopup=true] - The opacity of the background.
*/
constructor(opts = {}) {
const theme = Theme.fromString(opts.theme);
opts = Object.assign({}, {
items: [],
margin: theme.margin / 2,
textStyle: theme.textStyle,
closeOnPopup: true
}, opts);
super(opts);
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {PopupMenu} A reference to the popupmenu for chaining.
*/
setup() {
// content
//-----------------
const content = new PIXI.Container();
let y = 0;
for (let item of this.opts.items) {
let object = null;
if (item.label) {
object = new PIXI.Text(item.label, item.textStyle || this.opts.textStyle);
} else {
object = item.content;
}
object.y = y;
if (item.action) {
if (item.disabled) {
object.alpha = .5;
} else {
object.interactive = true;
object.buttonMode = true;
}
object.on('pointerover', e => {
TweenLite.to(object, this.theme.fast, {alpha: .83, overwrite: 'none'});
});
object.on('pointerout', e => {
TweenLite.to(object, this.theme.fast, {alpha: 1, overwrite: 'none'});
});
object.on('pointerup', e => {
item.action.call(object, e, object);
if (this.opts.closeOnAction) {
this.hide();
}
});
}
content.addChild(object);
y += object.height + this.opts.margin;
}
this.opts.content = content;
super.setup();
}
}
/* global Quad */
/**
* Class that represents a PixiJS Volatile.
*
* @example
* const app = new PIXIApp({
* view: canvas,
* width: 900,
* height: 250
* }).setup().run()
*
* const button = new Button({
* label: 'Volatile!',
* action: () => {
* new Volatile({
* object: button,
* direction: 'right',
* destroyOnComplete: false
* })
* }
* })
*
* app.scene.addChild(button)
*
* @class
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/volatile.html|DocTest}
*/
class Volatile {
/**
* Creates an instance of a Volatile.
*
* @constructor
* @param {object} [opts] - An options object to specify to style and behaviour of the modal.
* @param {number} [opts.id=auto generated] - The id of the tooltip.
* @param {PIXI.DisplayObject|PIXI.DisplayObject[]} opts.object - The object where the volatile should be applied to.
* @param {string} [opts.direction=top] - The animation direction. Possible values: top, right, bottom, left.
* @param {function} [opts.onStart] - A function which is executed when the volatile animation starts.
* @param {function} [opts.onComplete] - A function which is executed when the volatile animation finishes.
* @param {number} [opts.distance=160] - The animation distance.
* @param {number} [opts.duration=1.5] - The duration of the animation in seconds.
* @param {object} [opts.ease=Quad.easeOut] - The easing of the animation, see {@link https://greensock.com/docs/Easing}
* @param {boolean} [opts.destroyOnComplete=true] - Should the object be destroyed after the volatile animation?
*/
constructor(opts = {}) {
const theme = Theme.fromString(opts.theme);
this.theme = theme;
this.opts = Object.assign({}, {
id: PIXI.utils.uid(),
object: null,
direction: 'top', // top, right, bottom, left
onStart: null,
onComplete: null,
distance: 160,
duration: 1.5,
ease: Quad.easeOut,
destroyOnComplete: true
}, opts);
this.id = this.opts.id;
if (!Array.isArray(this.opts.object)) {
this.opts.object = [this.opts.object];
}
this.objects = this.opts.object;
// setup
//-----------------
this.setup();
// layout
//-----------------
this.layout();
// run
//-----------------
this.run();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {Volatile} A reference to the volatile for chaining.
*/
setup() {
return this
}
/**
* Should be called to refresh the layout of the volatile. Can be used after resizing.
*
* @return {Volatile} A reference to the volatile for chaining.
*/
layout() {
return this
}
/**
* Starts the volatile animation.
*
* @private
* @return {Volatile} A reference to the volatile for chaining.
*/
run() {
for (let object of this.objects) {
let x = object.x;
let y = object.y;
switch (this.opts.direction) {
case 'top':
y -= this.opts.distance;
break
case 'right':
x += this.opts.distance;
break
case 'bottom':
y += this.opts.distance;
break
case 'left':
x -= this.opts.distance;
break
}
TweenLite.to(object, this.opts.duration, {
x,
y,
alpha: 0,
ease: this.opts.ease,
overwrite: 'all',
onStart: () => {
if (this.opts.onStart) {
this.opts.onStart.call(object, object);
}
},
onComplete: () => {
if (this.opts.onComplete) {
this.opts.onComplete.call(object, object);
}
if (this.opts.destroyOnComplete) {
object.destroy({children: true});
}
}
});
}
return this
}
}
/* globals */
/**
* Class that represents a PixiJS List.
*
* @example
* const elephant1 = PIXI.Sprite.fromImage('./assets/elephant-1.jpg')
* const elephant2 = PIXI.Sprite.fromImage('./assets/elephant-2.jpg')
*
* // Create the list
* const list = new List([elephant1, elephant2])
*
* app.scene.addChild(list)
*
* @class
* @extends PIXI.Container
* @see {@link http://pixijs.download/dev/docs/PIXI.Container.html|PixiJS Container}
* @see {@link https://www.iwm-tuebingen.de/iwmbrowser/lib/pixi/list.html|DocTest}
*/
class List extends PIXI.Container {
/**
* Creates an instance of a Flippable.
*
* @constructor
* @param {PIXI.DisplayObject[]} items - An array of PIXI.DisplayObjects.
* @param {object} [opts] - An options object which can contain the following properties.
* @param {number} [opts.width] - The width of the list. If the items are larger than this width, the overflow
* will be hidden.
* @param {number} [opts.height] - The height of the list. If the items are larger than this height, the overflow
* will be hidden.
* @param {number} [opts.padding=10] - The inner spacing (distance from one item to the previous/next item).
* @param {number} [opts.margin=10] - The outer spacing (distance from one item to the border).
* @param {string} [opts.orientation=vertical] - The orientation of the button group. Can be horizontal or vertical.
* @param {string} [opts.align=left] - The horizontal position of the items. Possible values are
* left, center and right.
* @param {string} [opts.verticalAlign=middle] - The vertical position of the items. Possible values are
* top, middle and bottom.
*/
constructor(items = [], opts = {}) {
super();
this.opts = Object.assign({}, {
padding: 10,
margin: 10,
orientation: 'vertical',
align: 'left',
verticalAlign: 'middle',
width: null,
height: null
}, opts);
this.__items = items;
this.__dragging = false;
// setup
//--------------------
this.setup();
}
/**
* Creates children and instantiates everything.
*
* @private
* @return {List} A reference to the list for chaining.
*/
setup() {
// inner container
//--------------------
const container = new PIXI.Container();
this.addChild(container);
this.container = container;
// mask
//--------------------
const mask = new PIXI.Graphics();
this.addChild(mask);
this.__mask = mask;
// add items
//--------------------
for(let item of this.__items) {
container.addChild(item);
}
// interaction
//--------------------
this.interactive = this.opts.width || this.opts.height;
this.on('pointerdown', this.onStart.bind(this));
this.on('pointermove', this.onMove.bind(this));
this.on('pointerup', this.onEnd.bind(this));
this.on('pointercancel', this.onEnd.bind(this));
this.on('pointerout', this.onEnd.bind(this));
this.on('pointerupoutside', this.onEnd.bind(this));
this.layout();
return this
}
/**
* Replaces the existing items and relayouts the list.
*
* @param {PIXI.DisplayObject[]} items - An array of PIXI.DisplayObjects.
* @return {List} A reference to the list for chaining.
*/
setItems(items) {
this.container.removeChildren();
this.__items = items;
for(let item of this.__items) {
this.container.addChild(item);
}
this.layout();
}
/**
* Should be called to refresh the layout of the list (the width or the height).
*
* @return {List} A reference to the list for chaining.
*/
layout() {
const margin = this.opts.margin;
let x = margin;
let y = margin;
for (let item of this.__items) {
item.x = x;
item.y = y;
if (this.opts.orientation === 'vertical') {
y += item.height + this.opts.padding;
} else {
x += item.width + this.opts.padding;
}
}
// vertical
//--------------------
if (this.opts.orientation === 'vertical') {
switch (this.opts.align) {
case 'center':
this.__items.forEach(it => it.x = margin + this.width / 2 - it.width / 2);
break
case 'right':
this.__items.forEach(it => it.x = margin + this.width - it.width);
break
default:
this.__items.forEach(it => it.x = margin);
break
}
if (this.opts.height) {
const mask = this.__mask;
mask.clear();
mask.beginFill(0x000);
mask.drawRect(0, 0, this.width + 2 * margin, this.opts.height);
this.mask = mask;
this.interactive = this.innerHeight > this.opts.height;
}
}
// horizontal
//--------------------
if (this.opts.orientation === 'horizontal') {
switch (this.opts.verticalAlign) {
case 'top':
this.__items.forEach(it => it.y = margin);
break
case 'bottom':
this.__items.forEach(it => it.y = margin + this.height - it.height);
break
default:
this.__items.forEach(it => it.y = margin + this.height / 2 - it.height / 2);
break
}
if (this.opts.width) {
const mask = this.__mask;
mask.clear();
mask.beginFill(0x000);
mask.drawRect(0, 0, this.opts.width, this.height + 2 * margin);
this.mask = mask;
this.interactive = this.innerWidth > this.opts.width;
}
}
return this
}
/**
*
*/
get innerWidth() {
let size = 0;
this.__items.forEach(it => size += it.width);
size += this.opts.padding * (this.__items.length - 1);
size += 2 * this.opts.margin;
return size
}
/**
*
*/
get innerHeight() {
let size = 0;
this.__items.forEach(it => size += it.height);
size += this.opts.padding * (this.__items.length - 1);
size += 2 * this.opts.margin;
return size
}
/**
* Resizes the list.
*
* @param {number} widthOrHeight - The new width (if orientation is horizontal) or height (if orientation is vertical) of the list.
*/
resize(widthOrHeight) {
if (this.opts.orientation === 'horizontal') {
this.opts.width = widthOrHeight;
} else {
this.opts.height = widthOrHeight;
}
this.layout();
}
/**
*
* @private
* @param {*} event
*/
onStart(event) {
this.__dragging = true;
this.capture(event);
this.__delta = {
x: this.container.position.x - event.data.global.x,
y: this.container.position.y - event.data.global.y
};
TweenLite.killTweensOf(this.container.position, {x: true, y: true});
ThrowPropsPlugin.track(this.container.position, 'x,y');
}
/**
*
* @private
* @param {*} event
*/
onMove(event) {
if (this.__dragging) {
this.capture(event);
if (this.opts.orientation === 'horizontal') {
this.container.position.x = event.data.global.x + this.__delta.x;
} else {
this.container.position.y = event.data.global.y + this.__delta.y;
}
}
}
/**
*
* @private
* @param {*} event
*/
onEnd(event) {
if (this.__dragging) {
this.__dragging = false;
this.capture(event);
const throwProps = {};
if (this.opts.orientation === 'horizontal') {
let min = this.opts.width - this.innerWidth;
min = min > 0 ? 0 : min;
throwProps.x = {
velocity: 'auto',
min,
max: 0
};
} else {
let min = this.opts.height - this.innerHeight;
min = min > 0 ? 0 : min;
throwProps.y = {
velocity: 'auto',
min,
max: 0
};
}
ThrowPropsPlugin.to(this.container.position, {
throwProps,
ease: Strong.easeOut,
onComplete: () => ThrowPropsPlugin.untrack(this.container.position)
}, .8, .4);
}
}
/**
* Captures an event to inform InteractionMapper about processed events.
*
* @param {event|PIXI.InteractionEvent} event - The PIXI event to capture.
*/
capture(event) {
Events$1.capturedBy(event.data.originalEvent, this);
}
}
/* Needed to ensure that rollup.js includes class definitions and the classes
are visible inside doctests.
*/
window.PIXIApp = PIXIApp;
window.BlurFilter = BlurFilter;
window.FlipEffect = FlipEffect;
window.Flippable = Flippable;
window.DeepZoomInfo = DeepZoomInfo;
window.DeepZoomImage = DeepZoomImage;
window.Popover = Popover;
window.ScatterContainer = ScatterContainer;
window.DisplayObjectScatter = DisplayObjectScatter;
window.Command = Command;
window.RecorderTools = RecorderTools;
window.Timeline = Timeline;
window.AppTest = AppTest;
window.Theme = Theme;
window.Button = Button;
window.ButtonGroup = ButtonGroup;
window.Slider = Slider;
window.Switch = Switch;
window.Popup = Popup;
window.PopupMenu = PopupMenu$1;
window.Modal = Modal;
window.Volatile = Volatile;
window.Message = Message;
window.Tooltip = Tooltip;
window.Badge = Badge;
window.Progress = Progress;
window.List = List;
window.LabeledGraphics = LabeledGraphics;
window.FontInfo = FontInfo;
}());
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLmpzIiwic291cmNlcyI6WyJ0aGVtZS5qcyIsInByb2dyZXNzLmpzIiwiYWJzdHJhY3Rwb3B1cC5qcyIsInRvb2x0aXAuanMiLCJiYWRnZS5qcyIsIi4uL2V2ZW50cy5qcyIsImJ1dHRvbi5qcyIsImJ1dHRvbmdyb3VwLmpzIiwicG9wdXAuanMiLCJtb2RhbC5qcyIsIm1lc3NhZ2UuanMiLCIuLi91dGlscy5qcyIsImFwcC5qcyIsImJsdXJmaWx0ZXIuanMiLCIuLi9pbnRlcmZhY2UuanMiLCIuLi9pbnRlcmFjdGlvbi5qcyIsIi4uL2NhcGFiaWxpdGllcy5qcyIsIi4uL3NjYXR0ZXIuanMiLCIuLi9mbGlwcGFibGUuanMiLCJkZWVwem9vbS90aWxlLmpzIiwiZGVlcHpvb20vbG9hZGVyLmpzIiwiZGVlcHpvb20vdGlsZXMuanMiLCJkZWVwem9vbS9pbWFnZS5qcyIsImZsaXBlZmZlY3QuanMiLCJmbGlwcGFibGUuanMiLCJwb3BvdmVyLmpzIiwic2NhdHRlci5qcyIsInRlc3QuanMiLCJsYWJlbGVkZ3JhcGhpY3MuanMiLCJ0aW1lbGluZS5qcyIsInNsaWRlci5qcyIsInN3aXRjaC5qcyIsInBvcHVwbWVudS5qcyIsInZvbGF0aWxlLmpzIiwibGlzdC5qcyIsImJ1bmRsZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBUaGVtZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSB0aGVtZVxuICogY29uc3QgeWVsbG93ID0gbmV3IFRoZW1lKHtcbiAqICAgICBmaWxsOiAweGZlY2QyZCxcbiAqICAgICBmaWxsQWN0aXZlOiAweGZlOTcyNyxcbiAqICAgICBzdHJva2VBY3RpdmU6IDB4ZmVjZDJkLFxuICogICAgIHN0cm9rZUFjdGl2ZVdpZHRoOiA0LFxuICogICAgIHRleHRTdHlsZToge1xuICogICAgICAgICBmaWxsOiAweDVlYzdmOFxuICogICAgIH0sXG4gKiAgICAgdGV4dFN0eWxlQWN0aXZlOiB7XG4gKiAgICAgICAgIGZpbGw6IDB4NTk1NGQzXG4gKiAgICAgfSxcbiAqICAgICB0ZXh0U3R5bGVMYXJnZToge1xuICogICAgICAgICBmb250U2l6ZTogMzZcbiAqICAgICB9XG4gKiB9KVxuICpcbiAqIC8vIENyZWF0ZSB0aGUgYXBwIGFuZCBhcHBseSB0aGUgbmV3IHRoZW1lIHRvIGl0XG4gKiBjb25zdCBhcHAgPSBuZXcgUElYSUFwcCh7XG4gKiAgICAgdmlldzogY2FudmFzLFxuICogICAgIHdpZHRoOiA0NTAsXG4gKiAgICAgaGVpZ2h0OiAxNTAsXG4gKiAgICAgdGhlbWU6IHllbGxvd1xuICogfSkuc2V0dXAoKS5ydW4oKVxuICpcbiAqIEBjbGFzc1xuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cuaXdtLXR1ZWJpbmdlbi5kZS9pd21icm93c2VyL2xpYi9waXhpL3RoZW1lLmh0bWx8RG9jVGVzdH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGhlbWUge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFRoZW1lLlxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IHRvIHNwZWNpZnkgdG8gc3R5bGUgYW5kIGJlaGF2aW91ciBvZiB0aGUgdGhlbWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLm1hcmdpbj0xMF0gLSBUaGUgb3V0ZXIgc3BhY2luZyAoZGlzdGFuY2UgdG8gb3RoZXIgb2JqZWN0cykgZnJvbSB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5wYWRkaW5nPTEwXSAtIFRoZSBpbm5lciBzcGFjaW5nIChkaXN0YW5jZSBmcm9tIGljb24gYW5kL29yIGxhYmVsKSB0byB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5yYWRpdXM9NF0gLSBUaGUgcmFkaXVzIHVzZWQgd2hlbiBkcmF3aW5nIGEgcm91bmRlZCByZWN0YW5nbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZhc3Q9MC4yNV0gLSBUaGUgZHVyYXRpb24gb2YgdGltZSB3aGVuIGl0IGhhcyB0byBiZSBmYXN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5ub3JtYWw9MC41XSAtIFRoZSBkdXJhdGlvbiBvZiB0aW1lIHdoZW4gaXQgaGFzIHRvIGJlIG5vcm1hbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc2xvdz0xXSAtIFRoZSBkdXJhdGlvbiBvZiB0aW1lIHdoZW4gaXQgaGFzIHRvIGJlIHNsb3cuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnByaW1hcnlDb2xvcj0weDVlYzdmOF0gLSBUaGUgcHJpbWFyeSBjb2xvciBvZiB0aGUgdGhlbWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNvbG9yMT0weDI4MjgyOF0gLSBUaGUgZmlyc3QgY29sb3Igb2YgdGhlIHRoZW1lLiBGb3IgZXhhbXBsZSB1c2VkIGZvciB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29sb3IyPTB4ZjZmNmY2XSAtIFRoZSBzZWNvbmQgY29sb3Igb2YgdGhlIHRoZW1lLiBGb3IgZXhhbXBsZSB1c2VkIGZvciB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsPWNvbG9yMV0gLSBUaGUgY29sb3Igb2YgdGhlIGJhY2tncm91bmQgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBbHBoYT0xXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFjdGl2ZT1jb2xvcjFdIC0gVGhlIGNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsQWN0aXZlQWxwaGE9MV0gLSBUaGUgYWxwaGEgdmFsdWUgb2YgdGhlIGJhY2tncm91bmQgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZT1jb2xvcjJdIC0gVGhlIGNvbG9yIG9mIHRoZSBib3JkZXIgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZVdpZHRoPTAuNl0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWxwaGE9MV0gLSBUaGUgYWxwaGEgdmFsdWUgb2YgdGhlIGJvcmRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlPWNvbG9yMl0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlV2lkdGg9MC42XSAtIFRoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGluIHBpeGVsIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmVBbHBoYT0xXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5pY29uQ29sb3I9Y29sb3IyXSAtIFRoZSBjb2xvciBvZiB0aGUgaWNvbiAoc2V0IGJ5IHRoZSB0aW50IHByb3BlcnR5KSBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaWNvbkNvbG9yQWN0aXZlPWNvbG9yUHJpbWFyeV0gLSBUaGUgY29sb3Igb2YgdGhlIGljb24gd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmJhY2tncm91bmQ9Y29sb3IxXSAtIFRoZSBjb2xvciBvZiBhIGJhY2tncm91bmQgZm9yIGEgY29tcG9uZW50IChlLmcuIGF0IHRoZSBNb2RhbCBjbGFzcykuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZT17fV0gLSBBIHRleHRzdHlsZSBvYmplY3QgZm9yIHRoZSBzdHlsaW5nIG9mIHRleHQuIFNlZSBQSVhJLlRleHRTdHlsZVxuICAgICAqICAgICBmb3IgcG9zc2libGUgb3B0aW9ucy4gRGVmYXVsdCBvYmplY3Q6XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLnRleHRTdHlsZS5mb250RmFtaWx5PVwiQXZlbmlyIE5leHRcIiwgXCJPcGVuIFNhbnNcIiwgXCJTZWdvZSBVSVwiLCAuLi5dIC0gVGhlIGZvbnQgZmFtaWx5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy50ZXh0U3R5bGUuZm9udFdlaWdodD00MDBdIC0gVGhlIGZvbnQgd2VpZ2h0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50ZXh0U3R5bGUuZm9udFNpemU9MTZdIC0gVGhlIGZvbnQgc2l6ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMudGV4dFN0eWxlLmZpbGw9Y29sb3IyXSAtIFRoZSBmaWxsIGNvbG9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50ZXh0U3R5bGUuc3Ryb2tlPWNvbG9yMV0gLSBUaGUgc3Ryb2tlIGNvbG9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50ZXh0U3R5bGUuc3Ryb2tlVGhpY2tuZXNzPTBdIC0gVGhlIHRoaWNrbmVzcyBvZiB0aGUgc3Ryb2tlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50ZXh0U3R5bGUubWl0ZXJMaW1pdD0xXSAtIFRoZSBtZXRlciBsaW1pdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudGV4dFN0eWxlLmxpbmVKb2luPXJvdW5kXSAtIFRoZSBsaW5lIGpvaW4uXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZUFjdGl2ZT10ZXh0U3R5bGUgKyB7ZmlsbDogcHJpbWFyeUNvbG9yfV0gLSBBIHRleHRzdHlsZSBvYmplY3Qgd2hpY2ggaXMgdXNlZFxuICAgICAqICAgICBmb3IgYWN0aXZlZCB0ZXh0LlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cy50ZXh0U3R5bGVTbWFsbD10ZXh0U3R5bGUgKyB7Zm9udFNpemU6IC09IDN9XSAtIEEgdGV4dHN0eWxlIG9iamVjdCB3aGljaCBpcyB1c2VkIGZvclxuICAgICAqICAgICBzbWFsbCB0ZXh0LlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cy50ZXh0U3R5bGVTbWFsbEFjdGl2ZT10ZXh0U3R5bGVTbWFsbCArIHtmaWxsOiBwcmltYXJ5Q29sb3J9XSAtIEEgdGV4dHN0eWxlIG9iamVjdCB3aGljaFxuICAgICAqICAgICBpcyB1c2VkIGZvciBzbWFsbCBhY3RpdmVkIHRleHQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZUxhcmdlPXRleHRTdHlsZSArIHtmb250U2l6ZTogKz0gM31dIC0gQSB0ZXh0c3R5bGUgb2JqZWN0IHdoaWNoIGlzIHVzZWQgZm9yXG4gICAgICogICAgIGxhcmdlIHRleHQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZUxhcmdlQWN0aXZlPXRleHRTdHlsZUxhcmdlICsge2ZpbGw6IHByaW1hcnlDb2xvcn1dIC0gQSB0ZXh0c3R5bGUgb2JqZWN0IHdoaWNoXG4gICAgICogICAgIGlzIHVzZWQgZm9yIGxhcmdlIGFjdGl2ZWQgdGV4dC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcblxuICAgICAgICBjb25zdCBjb2xvclByaW1hcnkgPSBvcHRzLnByaW1hcnlDb2xvciAhPSBudWxsID8gb3B0cy5wcmltYXJ5Q29sb3IgOiAweDVlYzdmOCAgICAgICAgICAgICAgIC8vIGJsdWVcbiAgICAgICAgY29uc3QgY29sb3IxID0gb3B0cy5jb2xvcjEgIT0gbnVsbCA/IG9wdHMuY29sb3IxIDogMHgyODI4MjggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBibGFja1xuICAgICAgICBjb25zdCBjb2xvcjIgPSBvcHRzLmNvbG9yMiAhPSBudWxsID8gb3B0cy5jb2xvcjIgOiAweGY2ZjZmNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoaXRlXG5cbiAgICAgICAgdGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgbWFyZ2luOiAxMixcbiAgICAgICAgICAgIHBhZGRpbmc6IDEyLFxuICAgICAgICAgICAgcmFkaXVzOiA0LFxuICAgICAgICAgICAgZmFzdDogLjI1LFxuICAgICAgICAgICAgbm9ybWFsOiAuNSxcbiAgICAgICAgICAgIHNsb3c6IDEsXG4gICAgICAgICAgICBwcmltYXJ5Q29sb3I6IGNvbG9yUHJpbWFyeSxcbiAgICAgICAgICAgIGNvbG9yMTogY29sb3IxLFxuICAgICAgICAgICAgY29sb3IyOiBjb2xvcjIsXG4gICAgICAgICAgICBmaWxsOiBjb2xvcjEsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IDEsXG4gICAgICAgICAgICBmaWxsQWN0aXZlOiBjb2xvcjEsXG4gICAgICAgICAgICBmaWxsQWN0aXZlQWxwaGE6IDEsXG4gICAgICAgICAgICBzdHJva2U6IGNvbG9yMixcbiAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAuNixcbiAgICAgICAgICAgIHN0cm9rZUFscGhhOiAxLFxuICAgICAgICAgICAgc3Ryb2tlQWN0aXZlOiBjb2xvcjIsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVXaWR0aDogLjYsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVBbHBoYTogMSxcbiAgICAgICAgICAgIGljb25Db2xvcjogY29sb3IyLFxuICAgICAgICAgICAgaWNvbkNvbG9yQWN0aXZlOiBjb2xvclByaW1hcnksXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBjb2xvcjFcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICAvLyBTZXQgdGV4dFN0eWxlIGFuZCB2YXJpYW50c1xuICAgICAgICB0aGlzLm9wdHMudGV4dFN0eWxlID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgZm9udEZhbWlseTogJ1wiQXZlbmlyIE5leHRcIiwgXCJPcGVuIFNhbnNcIiwgXCJTZWdvZSBVSVwiLCBcIlJvYm90b1wiLCBcIkhlbHZldGljYSBOZXVlXCIsIC1hcHBsZS1zeXN0ZW0sIHN5c3RlbS11aSwgQmxpbmtNYWNTeXN0ZW1Gb250LCBBcmlhbCwgc2Fucy1zZXJpZiAhZGVmYXVsdCcsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnNTAwJyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAxOCxcbiAgICAgICAgICAgIGZpbGw6IGNvbG9yMixcbiAgICAgICAgICAgIHN0cm9rZTogY29sb3IxLFxuICAgICAgICAgICAgc3Ryb2tlVGhpY2tuZXNzOiAwLFxuICAgICAgICAgICAgbWl0ZXJMaW1pdDogMSxcbiAgICAgICAgICAgIGxpbmVKb2luOiAncm91bmQnXG4gICAgICAgIH0sIHRoaXMub3B0cy50ZXh0U3R5bGUpXG4gICAgICAgIHRoaXMub3B0cy50ZXh0U3R5bGVTbWFsbCA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMub3B0cy50ZXh0U3R5bGUsIHtmb250U2l6ZTogdGhpcy5vcHRzLnRleHRTdHlsZS5mb250U2l6ZSAtIDN9LCB0aGlzLm9wdHMudGV4dFN0eWxlU21hbGwpXG4gICAgICAgIHRoaXMub3B0cy50ZXh0U3R5bGVMYXJnZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMub3B0cy50ZXh0U3R5bGUsIHtmb250U2l6ZTogdGhpcy5vcHRzLnRleHRTdHlsZS5mb250U2l6ZSArIDN9LCB0aGlzLm9wdHMudGV4dFN0eWxlTGFyZ2UpXG4gICAgICAgIHRoaXMub3B0cy50ZXh0U3R5bGVBY3RpdmUgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm9wdHMudGV4dFN0eWxlLCB7ZmlsbDogdGhpcy5vcHRzLnByaW1hcnlDb2xvcn0sIHRoaXMub3B0cy50ZXh0U3R5bGVBY3RpdmUpXG4gICAgICAgIHRoaXMub3B0cy50ZXh0U3R5bGVTbWFsbEFjdGl2ZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMub3B0cy50ZXh0U3R5bGVTbWFsbCwge2ZpbGw6IHRoaXMub3B0cy5wcmltYXJ5Q29sb3J9LCB0aGlzLm9wdHMudGV4dFN0eWxlU21hbGxBY3RpdmUpXG4gICAgICAgIHRoaXMub3B0cy50ZXh0U3R5bGVMYXJnZUFjdGl2ZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMub3B0cy50ZXh0U3R5bGVMYXJnZSwge2ZpbGw6IHRoaXMub3B0cy5wcmltYXJ5Q29sb3J9LCB0aGlzLm9wdHMudGV4dFN0eWxlTGFyZ2VBY3RpdmUpXG5cbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCB0aGlzLm9wdHMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmFjdG9yeSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aGVtZT1kYXJrIC0gVGhlIG5hbWUgb2YgdGhlIHRoZW1lIHRvIGxvYWQuXG4gICAgICogQHJldHVybiB7VGhlbWV9IFJldHVybnMgYSBuZXdseSBjcmVhdGVkIFRoZW1lIG9iamVjdC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbVN0cmluZyh0aGVtZSkge1xuXG4gICAgICAgIGlmICh0aGVtZSAmJiB0eXBlb2YgdGhlbWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhlbWVcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAodGhlbWUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2xpZ2h0JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRoZW1lTGlnaHQoKVxuICAgICAgICAgICAgY2FzZSAncmVkJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRoZW1lUmVkKClcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUaGVtZURhcmsoKVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBUaGVtZURhcmsuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSB0aGUgYXBwIHdpdGggYSBuZXcgZGFyayB0aGVtZVxuICogY29uc3QgYXBwID0gbmV3IFBJWElBcHAoe1xuICogICAgIHZpZXc6IGNhbnZhcyxcbiAqICAgICB3aWR0aDogNDUwLFxuICogICAgIGhlaWdodDogMTUwLFxuICogICAgIHRoZW1lOiBuZXcgVGhlbWVEYXJrKClcbiAqIH0pLnNldHVwKCkucnVuKClcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFRoZW1lXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvdGhlbWUuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgY2xhc3MgVGhlbWVEYXJrIGV4dGVuZHMgVGhlbWUge1xuXG59XG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFRoZW1lTGlnaHQuXG4gKiBUaGUgY29sb3IxIGlzIHNldCB0byAweGY2ZjZmNiwgY29sb3IyIHRvIDB4MjgyODI4LlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIGFwcCB3aXRoIGEgbmV3IGxpZ2h0IHRoZW1lXG4gKiBjb25zdCBhcHAgPSBuZXcgUElYSUFwcCh7XG4gKiAgICAgdmlldzogY2FudmFzLFxuICogICAgIHdpZHRoOiA0NTAsXG4gKiAgICAgaGVpZ2h0OiAxNTAsXG4gKiAgICAgdGhlbWU6IG5ldyBUaGVtZUxpZ2h0KClcbiAqIH0pLnNldHVwKCkucnVuKClcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFRoZW1lXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvdGhlbWUuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgY2xhc3MgVGhlbWVMaWdodCBleHRlbmRzIFRoZW1lIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBUaGVtZUxpZ2h0LlxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG5cbiAgICAgICAgc3VwZXIoe2NvbG9yMTogMHhmNmY2ZjYsIGNvbG9yMjogMHgyODI4Mjh9KVxuICAgIH1cbn1cblxuLyoqXG4gKiBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBQaXhpSlMgVGhlbWVSZWQuXG4gKiBUaGUgcHJpbWFyeUNvbG9yIGlzIHNldCB0byAweGQ5MmYzMS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBhcHAgd2l0aCBhIG5ldyByZWQgdGhlbWVcbiAqIGNvbnN0IGFwcCA9IG5ldyBQSVhJQXBwKHtcbiAqICAgICB2aWV3OiBjYW52YXMsXG4gKiAgICAgd2lkdGg6IDQ1MCxcbiAqICAgICBoZWlnaHQ6IDE1MCxcbiAqICAgICB0aGVtZTogbmV3IFRoZW1lUmVkKClcbiAqIH0pLnNldHVwKCkucnVuKClcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFRoZW1lXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvdGhlbWUuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgY2xhc3MgVGhlbWVSZWQgZXh0ZW5kcyBUaGVtZSB7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgVGhlbWVSZWQuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcblxuICAgICAgICBzdXBlcih7cHJpbWFyeUNvbG9yOiAweGQ5MmYzMX0pXG4gICAgfVxufVxuIiwiaW1wb3J0IFRoZW1lIGZyb20gJy4vdGhlbWUuanMnXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFByb2dyZXNzLlxuICogXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBwcm9ncmVzc1xuICogY29uc3QgcHJvZ3Jlc3MgPSBuZXcgUHJvZ3Jlc3Moe1xuICogICAgIGFwcDogYXBwXG4gKiB9KVxuICpcbiAqIC8vIEFkZCB0aGUgcHJvZ3Jlc3MgdG8gYSBEaXNwbGF5T2JqZWN0XG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQocHJvZ3Jlc3MpXG4gKlxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBQSVhJLkNvbnRhaW5lclxuICogQHNlZSB7QGxpbmsgaHR0cDovL3BpeGlqcy5kb3dubG9hZC9kZXYvZG9jcy9QSVhJLkNvbnRhaW5lci5odG1sfFBJWEkuQ29udGFpbmVyfVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cuaXdtLXR1ZWJpbmdlbi5kZS9pd21icm93c2VyL2xpYi9waXhpL3Byb2dyZXNzLmh0bWx8RG9jVGVzdH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvZ3Jlc3MgZXh0ZW5kcyBQSVhJLkNvbnRhaW5lciB7XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFByb2dyZXNzLlxuICAgICAqIFxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0c10gLSBBbiBvcHRpb25zIG9iamVjdCB0byBzcGVjaWZ5IHRvIHN0eWxlIGFuZCBiZWhhdmlvdXIgb2YgdGhlIHByb2dyZXNzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5pZD1hdXRvIGdlbmVyYXRlZF0gLSBUaGUgaWQgb2YgdGhlIHByb2dyZXNzLlxuICAgICAqIEBwYXJhbSB7UElYSUFwcH0gW29wdHMuYXBwPXdpbmRvdy5hcHBdIC0gVGhlIGFwcCB3aGVyZSB0aGUgcHJvZ3Jlc3MgYmVsb25ncyB0by5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMud2lkdGhdIC0gVGhlIHdpZHRoIG9mIHRoZSBwcm9ncmVzcyBiYXIuIFdoZW4gbm90IHNldCwgdGhlIHdpZHRoIGlzIHRoZSBzaXplIG9mIHRoZSBhcHBcbiAgICAgKiAgICAgbWludXMgMiAqIG9wdHMubWFyZ2luLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5oZWlnaHQ9Ml0gLSBUaGUgaGVpZ2h0IG9mIHRoZSBwcm9ncmVzcyBiYXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VGhlbWV9IFtvcHRzLnRoZW1lPWRhcmtdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3IgdGhpcyBwcm9ncmVzcy4gUG9zc2libGUgdmFsdWVzIGFyZSBkYXJrLCBsaWdodCwgcmVkXG4gICAgICogICAgIG9yIGEgVGhlbWUgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5tYXJnaW49MTAwXSAtIFRoZSBvdXRlciBzcGFjaW5nIHRvIHRoZSBlZGdlcyBvZiB0aGUgYXBwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5wYWRkaW5nPTBdIC0gVGhlIGlubmVyIHNwYWNpbmcgKGRpc3RhbmNlIGZyb20gaWNvbiBhbmQvb3IgbGFiZWwpIHRvIHRoZSBib3JkZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGw9VGhlbWUuZmlsbF0gLSBUaGUgY29sb3Igb2YgdGhlIHByb2dyZXNzIGJhY2tncm91bmQgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBbHBoYT1UaGVtZS5maWxsQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsQWN0aXZlPVRoZW1lLnByaW1hcnlDb2xvcl0gLSBUaGUgY29sb3Igb2YgdGhlIHByb2dyZXNzIGJhY2tncm91bmQgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBY3RpdmVBbHBoYT1UaGVtZS5maWxsQWN0aXZlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2U9VGhlbWUuc3Ryb2tlXSAtIFRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIGFzIGEgaGV4IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VXaWR0aD0wXSAtIFRoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGluIHBpeGVsLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBbHBoYT1UaGVtZS5zdHJva2VBbHBoYV0gLSBUaGUgYWxwaGEgdmFsdWUgb2YgdGhlIGJvcmRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlPVRoZW1lLnN0cm9rZUFjdGl2ZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlV2lkdGg9MF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlQWxwaGE9VGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5iYWNrZ3JvdW5kPWZhbHNlXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5iYWNrZ3JvdW5kRmlsbD1UaGVtZS5iYWNrZ3JvdW5kXSAtIEEgdGV4dHN0eWxlIG9iamVjdCBmb3IgdGhlIHN0eWxpbmcgb2YgdGhlIGxhYmVsLiBTZWUgUElYSS5UZXh0U3R5bGVcbiAgICAgKiAgICAgZm9yIHBvc3NpYmxlIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmJhY2tncm91bmRGaWxsQWxwaGE9MV0gLSBBIHRleHRzdHlsZSBvYmplY3QgZm9yIHRoZSBzdHlsaW5nIG9mIHRoZSBsYWJlbCB3aGVuIHRoZVxuICAgICAqICAgICBwcm9ncmVzcyBpcyBhY3RpdmF0ZWQuIFNlZSBQSVhJLlRleHRTdHlsZSBmb3IgcG9zc2libGUgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMucmFkaXVzPVRoZW1lLnJhZGl1c10gLSBUaGUgcmFkaXVzIG9mIHRoZSBmb3VyIGNvcm5lcnMgb2YgdGhlIHByb2dyZXNzICh3aGljaCBpcyBhIHJvdW5kZWQgcmVjdGFuZ2xlKS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRlc3Ryb3lPbkNvbXBsZXRlPXRydWVdIC0gU2hvdWxkIHRoZSBwcm9ncmVzcyBiYXIgZGVzdHJveSBpdHNlbGYgYWZ0ZXIgcmVhY2hpbmcgMTAwICU/XG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy52aXNpYmxlPXRydWVdIC0gSXMgdGhlIHByb2dyZXNzIGluaXRpYWxseSB2aXNpYmxlIChwcm9wZXJ0eSB2aXNpYmxlKT9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcblxuICAgICAgICBzdXBlcigpXG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcbiAgICAgICAgdGhpcy50aGVtZSA9IHRoZW1lXG5cbiAgICAgICAgdGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgaWQ6IFBJWEkudXRpbHMudWlkKCksXG4gICAgICAgICAgICBhcHA6IHdpbmRvdy5hcHAsXG4gICAgICAgICAgICB3aWR0aDogbnVsbCxcbiAgICAgICAgICAgIGhlaWdodDogMixcbiAgICAgICAgICAgIG1hcmdpbjogMTAwLFxuICAgICAgICAgICAgcGFkZGluZzogMCxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIGZpbGxBY3RpdmU6IHRoZW1lLnByaW1hcnlDb2xvcixcbiAgICAgICAgICAgIGZpbGxBY3RpdmVBbHBoYTogdGhlbWUuZmlsbEFjdGl2ZUFscGhhLFxuICAgICAgICAgICAgc3Ryb2tlOiB0aGVtZS5zdHJva2UsXG4gICAgICAgICAgICBzdHJva2VXaWR0aDogMCxcbiAgICAgICAgICAgIHN0cm9rZUFscGhhOiB0aGVtZS5zdHJva2VBbHBoYSxcbiAgICAgICAgICAgIHN0cm9rZUFjdGl2ZTogdGhlbWUuc3Ryb2tlQWN0aXZlLFxuICAgICAgICAgICAgc3Ryb2tlQWN0aXZlV2lkdGg6IDAsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVBbHBoYTogdGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGEsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBmYWxzZSxcbiAgICAgICAgICAgIGJhY2tncm91bmRGaWxsOiB0aGVtZS5iYWNrZ3JvdW5kLFxuICAgICAgICAgICAgYmFja2dyb3VuZEZpbGxBbHBoYTogMSxcbiAgICAgICAgICAgIHJhZGl1czogdGhlbWUucmFkaXVzLFxuICAgICAgICAgICAgZGVzdHJveU9uQ29tcGxldGU6IHRydWUsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub3B0cy5pZFxuXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZCA9IG51bGxcbiAgICAgICAgdGhpcy5iYXIgPSBudWxsXG4gICAgICAgIHRoaXMuYmFyQWN0aXZlID0gbnVsbFxuXG4gICAgICAgIHRoaXMuYWxwaGEgPSAwXG4gICAgICAgIFxuICAgICAgICB0aGlzLnZpc2libGUgPSB0aGlzLm9wdHMudmlzaWJsZVxuXG4gICAgICAgIHRoaXMuX3Byb2dyZXNzID0gMFxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG5cbiAgICAgICAgLy8gbGF5b3V0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1Byb2dyZXNzfSBBIHJlZmVyZW5jZSB0byB0aGUgcHJvZ3Jlc3MgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldHVwKCkge1xuXG4gICAgICAgIC8vIGludGVyYWN0aW9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5vbignYWRkZWQnLCBlID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2hvdygpXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gYmFja2dyb3VuZFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMuYmFja2dyb3VuZCkge1xuICAgICAgICAgICAgY29uc3QgYmFja2dyb3VuZCA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZCA9IGJhY2tncm91bmRcbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQoYmFja2dyb3VuZClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGJhclxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IGJhciA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgdGhpcy5iYXIgPSBiYXJcbiAgICAgICAgdGhpcy5hZGRDaGlsZChiYXIpXG5cbiAgICAgICAgY29uc3QgYmFyQWN0aXZlID0gbmV3IFBJWEkuR3JhcGhpY3MoKVxuICAgICAgICB0aGlzLmJhckFjdGl2ZSA9IGJhckFjdGl2ZVxuICAgICAgICB0aGlzLmJhci5hZGRDaGlsZChiYXJBY3RpdmUpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIHByb2dyZXNzLiBDYW4gYmUgdXNlZCBhZnRlciByZXNpemluZy5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtQcm9ncmVzc30gQSByZWZlcmVuY2UgdG8gdGhlIHByb2dyZXNzIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG5cbiAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLm9wdHMuYXBwLnNpemUud2lkdGhcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5vcHRzLmFwcC5zaXplLmhlaWdodFxuXG4gICAgICAgIC8vIGJhY2tncm91bmRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmJhY2tncm91bmQpIHtcbiAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZC5jbGVhcigpXG4gICAgICAgICAgICB0aGlzLmJhY2tncm91bmQuYmVnaW5GaWxsKHRoaXMub3B0cy5iYWNrZ3JvdW5kRmlsbCwgdGhpcy5vcHRzLmJhY2tncm91bmRGaWxsQWxwaGEpXG4gICAgICAgICAgICB0aGlzLmJhY2tncm91bmQuZHJhd1JlY3QoMCwgMCwgd2lkdGgsIGhlaWdodClcbiAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZC5lbmRGaWxsKClcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZHJhdygpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIGNhbnZhcy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1Byb2dyZXNzfSBBIHJlZmVyZW5jZSB0byB0aGUgcHJvZ3Jlc3MgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGRyYXcoKSB7XG5cbiAgICAgICAgdGhpcy5iYXIuY2xlYXIoKVxuICAgICAgICB0aGlzLmJhckFjdGl2ZS5jbGVhcigpXG5cbiAgICAgICAgdGhpcy5kcmF3QmFyKClcbiAgICAgICAgdGhpcy5kcmF3QmFyQWN0aXZlKClcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBEcmF3cyB0aGUgYmFyLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7UHJvZ3Jlc3N9IEEgcmVmZXJlbmNlIHRvIHRoZSBwcm9ncmVzcyBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgZHJhd0JhcigpIHtcblxuICAgICAgICBjb25zdCB3aWR0aCA9IHRoaXMub3B0cy5hcHAuc2l6ZS53aWR0aFxuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLm9wdHMuYXBwLnNpemUuaGVpZ2h0XG5cbiAgICAgICAgdGhpcy5yYWRpdXMgPSB0aGlzLm9wdHMucmFkaXVzXG4gICAgICAgIGlmICgodGhpcy5yYWRpdXMgKiAyKSA+IHRoaXMub3B0cy5oZWlnaHQpIHtcbiAgICAgICAgICAgIHRoaXMucmFkaXVzID0gdGhpcy5vcHRzLmhlaWdodCAvIDJcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdhbnRlZFdpZHRoID0gdGhpcy5vcHRzLndpZHRoIHx8ICh3aWR0aCAtICgyICogdGhpcy5vcHRzLm1hcmdpbikpXG4gICAgICAgIGNvbnN0IHdhbnRlZEhlaWdodCA9IHRoaXMub3B0cy5oZWlnaHRcblxuICAgICAgICB0aGlzLmJhci5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlLCB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEpXG4gICAgICAgIHRoaXMuYmFyLmJlZ2luRmlsbCh0aGlzLm9wdHMuZmlsbCwgdGhpcy5vcHRzLmZpbGxBbHBoYSlcbiAgICAgICAgaWYgKHRoaXMucmFkaXVzID4gMSkge1xuICAgICAgICAgICAgdGhpcy5iYXIuZHJhd1JvdW5kZWRSZWN0KDAsIDAsIHdhbnRlZFdpZHRoLCB3YW50ZWRIZWlnaHQsIHRoaXMucmFkaXVzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5iYXIuZHJhd1JlY3QoMCwgMCwgd2FudGVkV2lkdGgsIHdhbnRlZEhlaWdodClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJhci5lbmRGaWxsKClcbiAgICAgICAgXG4gICAgICAgIHRoaXMuYmFyLnggPSB3aWR0aCAvIDIgLSB0aGlzLmJhci53aWR0aCAvIDJcbiAgICAgICAgdGhpcy5iYXIueSA9IGhlaWdodCAvIDIgLSB0aGlzLmJhci5oZWlnaHQgLyAyXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIGFjdGl2ZSBiYXIuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtQcm9ncmVzc30gQSByZWZlcmVuY2UgdG8gdGhlIHByb2dyZXNzIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBkcmF3QmFyQWN0aXZlKCkge1xuXG4gICAgICAgIGNvbnN0IHdhbnRlZFdpZHRoID0gdGhpcy5iYXIud2lkdGggLSAoMiAqIHRoaXMub3B0cy5wYWRkaW5nKVxuICAgICAgICBjb25zdCB3YW50ZWRIZWlnaHQgPSB0aGlzLmJhci5oZWlnaHQgLSAoMiAqIHRoaXMub3B0cy5wYWRkaW5nKVxuICAgICAgICBcbiAgICAgICAgY29uc3QgYmFyQWN0aXZlV2lkdGggPSB3YW50ZWRXaWR0aCAqIHRoaXMuX3Byb2dyZXNzIC8gMTAwXG5cbiAgICAgICAgdGhpcy5iYXJBY3RpdmUubGluZVN0eWxlKHRoaXMub3B0cy5zdHJva2VBY3RpdmVXaWR0aCwgdGhpcy5vcHRzLnN0cm9rZUFjdGl2ZSwgdGhpcy5vcHRzLnN0cm9rZUFjdGl2ZUFscGhhKVxuICAgICAgICB0aGlzLmJhckFjdGl2ZS5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGxBY3RpdmUsIHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEpXG4gICAgICAgIGlmIChiYXJBY3RpdmVXaWR0aCA+IDApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJhZGl1cyA+IDEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJhckFjdGl2ZS5kcmF3Um91bmRlZFJlY3QoMCwgMCwgYmFyQWN0aXZlV2lkdGgsIHdhbnRlZEhlaWdodCwgdGhpcy5yYWRpdXMpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYmFyQWN0aXZlLmRyYXdSZWN0KDAsIDAsIGJhckFjdGl2ZVdpZHRoLCB3YW50ZWRIZWlnaHQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iYXJBY3RpdmUuZW5kRmlsbCgpXG5cbiAgICAgICAgdGhpcy5iYXJBY3RpdmUueCA9IHRoaXMub3B0cy5wYWRkaW5nXG4gICAgICAgIHRoaXMuYmFyQWN0aXZlLnkgPSB0aGlzLm9wdHMucGFkZGluZ1xuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBwcm9ncmVzcyAoc2V0cyBoaXMgYWxwaGEgdmFsdWVzIHRvIDEpLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge1Byb2dyZXNzfSBBIHJlZmVyZW5jZSB0byB0aGUgcHJvZ3Jlc3MgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNob3coKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogMX0pXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIHByb2dyZXNzIChzZXRzIGhpcyBhbHBoYSB2YWx1ZXMgdG8gMSkuXG4gICAgICogXG4gICAgICogQHJldHVybiB7UHJvZ3Jlc3N9IEEgcmVmZXJlbmNlIHRvIHRoZSBwcm9ncmVzcyBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgaGlkZSgpIHtcbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAwLCBvbkNvbXBsZXRlOiAoKSA9PiB0aGlzLnZpc2libGUgPSBmYWxzZX0pXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBwcm9ncmVzcy4gSGFzIHRvIGJlIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMTAwLlxuICAgICAqIFxuICAgICAqIEBtZW1iZXIge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9ncmVzc1xuICAgIH1cbiAgICBzZXQgcHJvZ3Jlc3ModmFsdWUpIHtcblxuICAgICAgICB2YWx1ZSA9IE1hdGgucm91bmQodmFsdWUpXG5cbiAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgdmFsdWUgPSAwXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUgPiAxMDApIHtcbiAgICAgICAgICAgIHZhbHVlID0gMTAwXG4gICAgICAgIH1cblxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcywgdGhpcy50aGVtZS5ub3JtYWwsIHtcbiAgICAgICAgICAgIF9wcm9ncmVzczogdmFsdWUsXG4gICAgICAgICAgICBvblVwZGF0ZTogKCkgPT4gdGhpcy5kcmF3KCksXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAxMDAgJiYgdGhpcy5vcHRzLmRlc3Ryb3lPbkNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLCB0aGlzLnRoZW1lLmZhc3QsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZTogKCkgPT4gdGhpcy5kZXN0cm95KHtjaGlsZHJlbjogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cbn1cbiIsImltcG9ydCBUaGVtZSBmcm9tICcuL3RoZW1lLmpzJ1xuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBBYnN0cmFjdFBvcHVwLlxuICogVGhlIGNsYXNzIGlzIHVzZWQgZm9yIHZhcmlvdXMgb3RoZXIgUG9wdXAtbGlrZSBjbGFzc2VzXG4gKiBsaWtlIFBvcHVwLCBNZXNzYWdlLCBUb29sdGlwLi4uXG4gKlxuICogQGNsYXNzXG4gKiBAYWJzdHJhY3RcbiAqIEBleHRlbmRzIFBJWEkuR3JhcGhpY3NcbiAqIEBzZWUge0BsaW5rIGh0dHA6Ly9waXhpanMuZG93bmxvYWQvZGV2L2RvY3MvUElYSS5HcmFwaGljcy5odG1sfFBJWEkuR3JhcGhpY3N9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFic3RyYWN0UG9wdXAgZXh0ZW5kcyBQSVhJLkdyYXBoaWNzIHtcbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGFuIEFic3RyYWN0UG9wdXAgKG9ubHkgZm9yIGludGVybmFsIHVzZSkuXG4gICAgICogXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IHRvIHNwZWNpZnkgdG8gc3R5bGUgYW5kIGJlaGF2aW91ciBvZiB0aGUgcG9wdXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmlkPWF1dG8gZ2VuZXJhdGVkXSAtIFRoZSBpZCBvZiB0aGUgcG9wdXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLng9MF0gLSBUaGUgeCBwb3NpdGlvbiBvZiB0aGUgcG9wdXAuIENhbiBiZSBhbHNvIHNldCBhZnRlciBjcmVhdGlvbiB3aXRoIHBvcHVwLnggPSAwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy55PTBdIC0gVGhlIHkgcG9zaXRpb24gb2YgdGhlIHBvcHVwLiBDYW4gYmUgYWxzbyBzZXQgYWZ0ZXIgY3JlYXRpb24gd2l0aCBwb3B1cC55ID0gMC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xUaGVtZX0gW29wdHMudGhlbWU9ZGFya10gLSBUaGUgdGhlbWUgdG8gdXNlIGZvciB0aGlzIHBvcHVwLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGRhcmssIGxpZ2h0LCByZWRcbiAgICAgKiAgICAgb3IgYSBUaGVtZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfFBJWEkuVGV4dH0gW29wdHMuaGVhZGVyXSAtIFRoZSBoZWFkaW5nIGluc2lkZSB0aGUgcG9wdXAgYXMgYSBzdHJpbmcsIGEgbnVtYmVyICh3aWxsIGJlXG4gICAgICogICAgIGNvbnZlcnRlZCB0byBhIHRleHQpIG9yIGFzIGEgUElYSS5UZXh0IG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ8UElYSS5EaXNwbGF5T2JqZWN0fSBbb3B0cy5jb250ZW50XSAtIEEgdGV4dCwgYSBudW1iZXIgKHdpbGwgYmUgY29udmVydGVkIHRvIGEgdGV4dCkgb3JcbiAgICAgKiAgICAgYW4gUElYSS5EaXNwbGF5T2JqZWN0IGFzIHRoZSBjb250ZW50IG9mIHRoZSBwb3B1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluV2lkdGg9MzIwXSAtIFRoZSBtaW5pbXVtIHdpZHRoIG9mIHRoZSBwb3B1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluSGVpZ2h0PTEzMF0gLSBUaGUgbWluaW11bSBoZWlnaHQgb2YgdGhlIHBvcHVwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5wYWRkaW5nPVRoZW1lLnBhZGRpbmddIC0gVGhlIGlubmVyIHNwYWNpbmcgKGRpc3RhbmNlIGZyb20gaGVhZGVyIGFuZCBjb250ZW50KSB0aGUgdGhlIGJvcmRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbD1UaGVtZS5maWxsXSAtIFRoZSBjb2xvciBvZiB0aGUgYnV0dG9uIGJhY2tncm91bmQgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBbHBoYT1UaGVtZS5maWxsQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2U9VGhlbWUuc3Ryb2tlXSAtIFRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIGFzIGEgaGV4IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VXaWR0aD1UaGVtZS5zdHJva2VXaWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWxwaGE9VGhlbWUuc3Ryb2tlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLmhlYWRlclN0eWxlPVRoZW1lLnRleHRTdHlsZUxhcmdlXSAtIEEgdGV4dHN0eWxlIG9iamVjdCBmb3IgdGhlIHN0eWxpbmcgb2YgdGhlIGhlYWRlci4gU2VlIFBJWEkuVGV4dFN0eWxlXG4gICAgICogICAgIGZvciBwb3NzaWJsZSBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cy50ZXh0U3R5bGU9VGhlbWUudGV4dFN0eWxlU21hbGxdIC0gQSB0ZXh0c3R5bGUgb2JqZWN0IGZvciB0aGUgc3R5bGluZyBvZiB0aGUgdGV4dC4gU2VlIFBJWEkuVGV4dFN0eWxlXG4gICAgICogICAgIGZvciBwb3NzaWJsZSBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5yYWRpdXM9VGhlbWUucmFkaXVzXSAtIFRoZSByYWRpdXMgb2YgdGhlIGZvdXIgY29ybmVycyBvZiB0aGUgcG9wdXAgKHdoaWNoIGlzIGEgcm91bmRlZCByZWN0YW5nbGUpLlxuICAgICAqIEBwYXJhbSB7aGlkZGVuQ2FsbGJhY2t9IFtvcHRzLm9uSGlkZGVuXSAtIEV4ZWN1dGVkIHdoZW4gdGhlIHBvcHVwIGdldHMgaGlkZGVuLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudmlzaWJsZT10cnVlXSAtIElzIHRoZSBwb3B1cCBpbml0aWFsbHkgdmlzaWJsZSAocHJvcGVydHkgdmlzaWJsZSk/XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm9yaWVudGF0aW9uXSAtIFdoZW4gc2V0IHRvIHBvcnRyYWl0LCB0aGUgcG9wdXAgY2Fubm90IGJlIGRpc3BsYXllZCBpbiBsYW5kc2NhcGUgbW9kZS4gV2hlbiBzZXRcbiAgICAgKiAgICAgdG8gbGFuZHNjYXBlLCB0aGUgcG9wdXAgY2Fubm90IGJlIGRpc3BsYXllZCBpbiBwb3J0cmFpdCBtb2RlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICB0aGlzLnRoZW1lID0gdGhlbWVcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBpZDogUElYSS51dGlscy51aWQoKSxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgaGVhZGVyOiBudWxsLCAgICAgICAgICAgICAgICAgICAgICAgLy8gbnVsbCBvciBudWxsXG4gICAgICAgICAgICBjb250ZW50OiBudWxsLCAgICAgICAgICAgICAgICAgICAgICAvLyBudWxsIG9yIFN0cmluZyBvciBQSVhJLkRpc3BsYXlPYmplY3RcbiAgICAgICAgICAgIG1pbldpZHRoOiAzMjAsXG4gICAgICAgICAgICBtaW5IZWlnaHQ6IDEzMCxcbiAgICAgICAgICAgIG1heFdpZHRoOiBudWxsLFxuICAgICAgICAgICAgcGFkZGluZzogdGhlbWUucGFkZGluZyxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIHN0cm9rZTogdGhlbWUuc3Ryb2tlLFxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoZW1lLnN0cm9rZVdpZHRoLFxuICAgICAgICAgICAgc3Ryb2tlQWxwaGE6IHRoZW1lLnN0cm9rZUFscGhhLFxuICAgICAgICAgICAgaGVhZGVyU3R5bGU6IHRoZW1lLnRleHRTdHlsZUxhcmdlLFxuICAgICAgICAgICAgdGV4dFN0eWxlOiB0aGVtZS50ZXh0U3R5bGVTbWFsbCxcbiAgICAgICAgICAgIHJhZGl1czogdGhlbWUucmFkaXVzLFxuICAgICAgICAgICAgb25IaWRkZW46IG51bGwsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgb3JpZW50YXRpb246IG51bGxcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICB0aGlzLmlkID0gdGhpcy5vcHRzLmlkXG5cbiAgICAgICAgdGhpcy5oZWFkZXJTdHlsZSA9IG5ldyBQSVhJLlRleHRTdHlsZSh0aGlzLm9wdHMuaGVhZGVyU3R5bGUpXG4gICAgICAgIHRoaXMudGV4dFN0eWxlID0gbmV3IFBJWEkuVGV4dFN0eWxlKHRoaXMub3B0cy50ZXh0U3R5bGUpXG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5tYXhXaWR0aCkge1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTdHlsZS53b3JkV3JhcCA9IHRydWVcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyU3R5bGUud29yZFdyYXBXaWR0aCA9IHRoaXMub3B0cy5tYXhXaWR0aCAtICgyICogdGhpcy5vcHRzLnBhZGRpbmcpXG5cbiAgICAgICAgICAgIHRoaXMudGV4dFN0eWxlLndvcmRXcmFwID0gdHJ1ZVxuICAgICAgICAgICAgdGhpcy50ZXh0U3R5bGUud29yZFdyYXBXaWR0aCA9IHRoaXMub3B0cy5tYXhXaWR0aCAtICgyICogdGhpcy5vcHRzLnBhZGRpbmcpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFscGhhID0gMFxuICAgICAgICB0aGlzLnZpc2libGUgPSB0aGlzLm9wdHMudmlzaWJsZVxuXG4gICAgICAgIHRoaXMuX2hlYWRlciA9IG51bGxcbiAgICAgICAgdGhpcy5fY29udGVudCA9IG51bGxcblxuICAgICAgICAvLyBwb3NpdGlvblxuICAgICAgICB0aGlzLnggPSB0aGlzLm9wdHMueFxuICAgICAgICB0aGlzLnkgPSB0aGlzLm9wdHMueVxuXG4gICAgICAgIC8vIHBhZGRpbmdcbiAgICAgICAgdGhpcy5pbm5lclBhZGRpbmcgPSB0aGlzLm9wdHMucGFkZGluZyAqIDEuNVxuICAgICAgICBcbiAgICAgICAgLy8gaW50ZXJhY3Rpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gdHJ1ZVxuICAgICAgICB0aGlzLm9uKCdhZGRlZCcsIGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5zaG93KClcbiAgICAgICAgfSlcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgZnJhbWV3b3JrIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge0Fic3RyYWN0UG9wdXB9IEEgcmVmZXJlbmNlIHRvIHRoZSBwb3B1cCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG5cbiAgICAgICAgLy8gcG9zaXRpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnN5ID0gdGhpcy5vcHRzLnBhZGRpbmdcblxuICAgICAgICAvLyBoZWFkZXJcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmhlYWRlciAhPSBudWxsKSB7XG5cbiAgICAgICAgICAgIGxldCBoZWFkZXIgPSBudWxsXG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuaGVhZGVyIGluc3RhbmNlb2YgUElYSS5UZXh0KSB7XG4gICAgICAgICAgICAgICAgaGVhZGVyID0gdGhpcy5vcHRzLmhlYWRlclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5vcHRzLmhlYWRlciA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBoZWFkZXIgPSAgbmV3IFBJWEkuVGV4dCh0aGlzLm9wdHMuaGVhZGVyLnRvU3RyaW5nKCksIHRoaXMuaGVhZGVyU3R5bGUpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGhlYWRlciA9ICBuZXcgUElYSS5UZXh0KHRoaXMub3B0cy5oZWFkZXIsIHRoaXMuaGVhZGVyU3R5bGUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGhlYWRlci54ID0gdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIGhlYWRlci55ID0gdGhpcy5zeVxuXG4gICAgICAgICAgICB0aGlzLmFkZENoaWxkKGhlYWRlcilcblxuICAgICAgICAgICAgdGhpcy5zeSArPSBoZWFkZXIuaGVpZ2h0XG5cbiAgICAgICAgICAgIHRoaXMuX2hlYWRlciA9IGhlYWRlclxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5oZWFkZXIgJiYgdGhpcy5vcHRzLmNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc3kgKz0gdGhpcy5pbm5lclBhZGRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvbnRlbnRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmNvbnRlbnQgIT0gbnVsbCkge1xuXG4gICAgICAgICAgICBsZXQgY29udGVudCA9IG51bGxcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdHMuY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBjb250ZW50ID0gbmV3IFBJWEkuVGV4dCh0aGlzLm9wdHMuY29udGVudCwgdGhpcy50ZXh0U3R5bGUpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm9wdHMuY29udGVudCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBjb250ZW50ID0gbmV3IFBJWEkuVGV4dCh0aGlzLm9wdHMuY29udGVudC50b1N0cmluZygpLCB0aGlzLnRleHRTdHlsZSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGVudCA9IHRoaXMub3B0cy5jb250ZW50XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRlbnQueCA9IHRoaXMub3B0cy5wYWRkaW5nXG4gICAgICAgICAgICBjb250ZW50LnkgPSB0aGlzLnN5XG5cbiAgICAgICAgICAgIHRoaXMuc3kgKz0gY29udGVudC5oZWlnaHRcblxuICAgICAgICAgICAgdGhpcy5hZGRDaGlsZChjb250ZW50KVxuXG4gICAgICAgICAgICB0aGlzLl9jb250ZW50ID0gY29udGVudFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIHBvcHVwLiBDYW4gYmUgdXNlZCBhZnRlciByZXNpemluZy5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtBYnN0cmFjdFBvcHVwfSBBIHJlZmVyZW5jZSB0byB0aGUgcG9wdXAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcbiAgICAgICAgXG4gICAgICAgIC8vIHdhbnRlZCB3aWR0aCAmIHdhbnRlZCBoZWlnaHRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBwYWRkaW5nID0gdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0SW5uZXJTaXplKClcbiAgICAgICAgY29uc3Qgd2lkdGggPSBzaXplLndpZHRoICsgKDIgKiBwYWRkaW5nKVxuICAgICAgICBjb25zdCBoZWlnaHQgPSBzaXplLmhlaWdodCArICgyICogcGFkZGluZylcblxuICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gTWF0aC5tYXgod2lkdGgsIHRoaXMub3B0cy5taW5XaWR0aClcbiAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSBNYXRoLm1heChoZWlnaHQsIHRoaXMub3B0cy5taW5IZWlnaHQpXG4gICAgICAgIFxuICAgICAgICBpZiAodGhpcy5vcHRzLm1heFdpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gTWF0aC5taW4odGhpcy53YW50ZWRXaWR0aCwgdGhpcy5vcHRzLm1heFdpZHRoKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5yYWRpdXMgKiAyID4gdGhpcy53YW50ZWRXaWR0aCkge1xuICAgICAgICAgICAgdGhpcy53YW50ZWRXaWR0aCA9IHRoaXMub3B0cy5yYWRpdXMgKiAyXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRzLnJhZGl1cyAqIDIgPiB0aGlzLndhbnRlZEhlaWdodCkge1xuICAgICAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSB0aGlzLm9wdHMucmFkaXVzICogMlxuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoICh0aGlzLm9wdHMub3JpZW50YXRpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ3BvcnRyYWl0JzpcbiAgICAgICAgICAgICAgICBpZiAodGhpcy53YW50ZWRXaWR0aCA+IHRoaXMud2FudGVkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FudGVkSGVpZ2h0ID0gdGhpcy53YW50ZWRXaWR0aFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSAnbGFuZHNjYXBlJzpcbiAgICAgICAgICAgICAgICBpZiAodGhpcy53YW50ZWRIZWlnaHQgPiB0aGlzLndhbnRlZFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FudGVkV2lkdGggPSB0aGlzLndhbnRlZEhlaWdodFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kcmF3KClcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBEcmF3cyB0aGUgY2FudmFzLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7QWJzdHJhY3RQb3B1cH0gQSByZWZlcmVuY2UgdG8gdGhlIHBvcHVwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBkcmF3KCkge1xuXG4gICAgICAgIGNvbnN0IHNxdWFyZSA9IE1hdGgucm91bmQodGhpcy53YW50ZWRXaWR0aCkgPT09IE1hdGgucm91bmQodGhpcy53YW50ZWRIZWlnaHQpXG4gICAgICAgIGNvbnN0IGRpYW1ldGVyID0gTWF0aC5yb3VuZCh0aGlzLm9wdHMucmFkaXVzICogMilcblxuICAgICAgICB0aGlzLmNsZWFyKClcbiAgICAgICAgdGhpcy5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlLCB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEpXG4gICAgICAgIHRoaXMuYmVnaW5GaWxsKHRoaXMub3B0cy5maWxsLCB0aGlzLm9wdHMuZmlsbEFscGhhKVxuICAgICAgICBpZiAoc3F1YXJlICYmIGRpYW1ldGVyID09PSB0aGlzLndhbnRlZFdpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLmRyYXdDaXJjbGUodGhpcy53YW50ZWRXaWR0aCAvIDIsIHRoaXMud2FudGVkSGVpZ2h0IC8gMiwgdGhpcy5vcHRzLnJhZGl1cylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZHJhd1JvdW5kZWRSZWN0KDAsIDAsIHRoaXMud2FudGVkV2lkdGgsIHRoaXMud2FudGVkSGVpZ2h0LCB0aGlzLm9wdHMucmFkaXVzKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZW5kRmlsbCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgc2l6ZSBvZiB0aGUgY2hpbGRyZW4gb2YgdGhlIEFic3RyYWN0UG9wdXAuXG4gICAgICogQ2Fubm90IHVzZSBnZXRCb3VuZHMoKSBiZWNhdXNlIGl0IGlzIG5vdCB1cGRhdGVkIHdoZW4gY2hpbGRyZW5cbiAgICAgKiBhcmUgcmVtb3ZlZC5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IEFuIEphdmFTY3JpcHQgb2JqZWN0IHdpZHRoIHRoZSBrZXlzIHdpZHRoIGFuZCBoZWlnaHQuXG4gICAgICovXG4gICAgZ2V0SW5uZXJTaXplKCkge1xuXG4gICAgICAgIGxldCB3aWR0aCA9IDBcbiAgICAgICAgbGV0IGhlaWdodCA9IDBcblxuICAgICAgICBpZiAodGhpcy5faGVhZGVyKSB7XG4gICAgICAgICAgICB3aWR0aCA9IHRoaXMuX2hlYWRlci53aWR0aFxuICAgICAgICAgICAgaGVpZ2h0ID0gdGhpcy5faGVhZGVyLmhlaWdodFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2hlYWRlciAmJiB0aGlzLl9jb250ZW50KSB7XG4gICAgICAgICAgICBoZWlnaHQgKz0gdGhpcy5pbm5lclBhZGRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICAgICAgICB3aWR0aCA9IE1hdGgubWF4KHdpZHRoLCB0aGlzLl9jb250ZW50LndpZHRoKVxuICAgICAgICAgICAgaGVpZ2h0ICs9IHRoaXMuX2NvbnRlbnQuaGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge3dpZHRoLCBoZWlnaHR9XG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBwb3B1cCAoc2V0cyBoaXMgYWxwaGEgdmFsdWVzIHRvIDEpLlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gLSBFeGVjdXRlZCB3aGVuIHNob3cgYW5pbWF0aW9uIHdhcyBjb21wbGV0ZWQuXG4gICAgICogQHJldHVybiB7QWJzdHJhY3RQb3B1cH0gQSByZWZlcmVuY2UgdG8gdGhlIHBvcHVwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzaG93KGNiKSB7XG5cbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIHRoaXMudGhlbWUuZmFzdCwge1xuICAgICAgICAgICAgYWxwaGE6IDEsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNiKSB7XG4gICAgICAgICAgICAgICAgICAgIGNiLmNhbGwodGhpcylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIHBvcHVwIChzZXRzIGhpcyBhbHBoYSB2YWx1ZXMgdG8gMCkuXG4gICAgICogXG4gICAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSAtIEV4ZWN1dGVkIHdoZW4gaGlkZSBhbmltYXRpb24gd2FzIGNvbXBsZXRlZC5cbiAgICAgKiBAcmV0dXJuIHtBYnN0cmFjdFBvcHVwfSBBIHJlZmVyZW5jZSB0byB0aGUgcG9wdXAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGhpZGUoY2IpIHtcblxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcywgdGhpcy50aGVtZS5mYXN0LCB7XG4gICAgICAgICAgICBhbHBoYTogMCxcbiAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpc2libGUgPSBmYWxzZVxuICAgICAgICAgICAgICAgIGlmIChjYikge1xuICAgICAgICAgICAgICAgICAgICBjYi5jYWxsKHRoaXMpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmICh0aGlzLm9wdHMub25IaWRkZW4pIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy5vbkhpZGRlbi5jYWxsKHRoaXMsIHRoaXMpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgZ2V0cyB0aGUgaGVhZGVyLiBUaGUgZ2V0dGVyIGFsd2F5cyByZXR1cm5zIGEgUElYSS5UZXh0IG9iamVjdC4gVGhlIHNldHRlciBjYW4gcmVjZWl2ZVxuICAgICAqIGEgc3RyaW5nLCBhIG51bWJlciBvciBhIFBJWEkuVGV4dCBvYmplY3QuXG4gICAgICogXG4gICAgICogQG1lbWJlciB7c3RyaW5nfG51bWJlcnxQSVhJLlRleHR9XG4gICAgICovXG4gICAgZ2V0IGhlYWRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYWRlclxuICAgIH1cbiAgICBzZXQgaGVhZGVyKHZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLl9oZWFkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2hlYWRlci5kZXN0cm95KClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdHMuaGVhZGVyID0gdmFsdWVcbiAgICAgICAgdGhpcy5zZXR1cCgpLmxheW91dCgpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgZ2V0cyB0aGUgY29udGVudC4gVGhlIGdldHRlciBhbHdheXMgcmV0dXJucyBhbiBQSVhJLkRpc3BsYXlPYmplY3QuIFRoZSBzZXR0ZXIgY2FuIHJlY2VpdmVcbiAgICAgKiBhIHN0cmluZywgYSBudW1iZXIgb3IgYSBQSVhJLkRpc3BsYXlPYmplY3QuXG4gICAgICogXG4gICAgICogQG1lbWJlciB7c3RyaW5nfG51bWJlcnxQSVhJLkRpc3BsYXlPYmplY3R9XG4gICAgICovXG4gICAgZ2V0IGNvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZW50XG4gICAgfVxuICAgIHNldCBjb250ZW50KHZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZW50LmRlc3Ryb3koKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub3B0cy5jb250ZW50ID0gdmFsdWVcbiAgICAgICAgdGhpcy5zZXR1cCgpLmxheW91dCgpXG4gICAgfVxufVxuIiwiaW1wb3J0IFRoZW1lIGZyb20gJy4vdGhlbWUuanMnXG5pbXBvcnQgQWJzdHJhY3RQb3B1cCBmcm9tICcuL2Fic3RyYWN0cG9wdXAuanMnXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFRvb2x0aXAuXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIGFwcFxuICogY29uc3QgYXBwID0gbmV3IFBJWElBcHAoe1xuICogICAgIHZpZXc6IGNhbnZhcyxcbiAqICAgICB3aWR0aDogOTAwLFxuICogICAgIGhlaWdodDogMjUwXG4gKiB9KS5zZXR1cCgpLnJ1bigpXG4gKiBcbiAqIC8vIEFkZCBhbiBEaXNwbGF5T2JqZWN0IHRvIHRoZSBhcHBcbiAqIGNvbnN0IGNpcmNsZSA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAqIGNpcmNsZS5iZWdpbkZpbGwoMHg1MjUxYTMpXG4gKiBjaXJjbGUuZHJhd0NpcmNsZSg1MCwgNTAsIDQwKVxuICogYXBwLnNjZW5lLmFkZENoaWxkKGNpcmNsZSlcbiAqIFxuICogY29uc3QgdG9vbHRpcCA9IG5ldyBUb29sdGlwKHtcbiAqICAgICBvYmplY3Q6IGNpcmNsZSxcbiAqICAgICBjb250YWluZXI6IGFwcC5zY2VuZSxcbiAqICAgICBjb250ZW50OiAnRGFzIEdlc2V0eiBpc3QgZGVyIEZyZXVuZCBkZXMgU2Nod2FjaGVuLidcbiAqIH0pXG4gKlxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBBYnN0cmFjdFBvcHVwXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvdG9vbHRpcC5odG1sfERvY1Rlc3R9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvb2x0aXAgZXh0ZW5kcyBBYnN0cmFjdFBvcHVwIHtcbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgVG9vbHRpcC5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSB0b29sdGlwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5taW5XaWR0aD0wXSAtIFRoZSBtaW5pbXVtIHdpZHRoIG9mIHRoZSB0b29sdGlwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5taW5IZWlnaHQ9MF0gLSBUaGUgbWluaW11bSBoZWlnaHQgb2YgdGhlIHRvb2x0aXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnBhZGRpbmc9VGhlbWUucGFkZGluZyAvIDJdIC0gVGhlIGlubmVyIHNwYWNpbmcgb2YgdGhlIHRvb2x0aXAuXG4gICAgICogQHBhcmFtIHtQSVhJLkRpc3BsYXlPYmplY3R9IG9wdHMub2JqZWN0IC0gVGhlIG9iamVjdCwgd2hlcmUgdGhlIHRvb2x0aXAgc2hvdWxkIGJlIGRpc3BsYXllZC5cbiAgICAgKiBAcGFyYW0ge1BJWEkuRGlzcGxheU9iamVjdH0gW29wdHMuY29udGFpbmVyPW9iamVjdF0gLSBUaGUgY29udGFpbmVyIHdoZXJlIHRoZSB0b29sdGlwIHNob3VsZCBiZSBhdHRhY2hlZCB0by5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMub2Zmc2V0TGVmdD04XSAtIFRoZSBob3Jpem9udGFsIHNoaWZ0IG9mIHRoZSB0b29sdGlwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5vZmZzZXRUb3A9LThdIC0gVGhlIHZlcnRpY2FsIHNoaWZ0IG9mIHRoZSB0b29sdGlwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5kZWxheT0wXSAtIEEgZGVsYXksIGFmdGVyIHdoaWNoIHRoZSB0b29sdGlwIHNob3VsZCBiZSBvcGVuZWQuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcbiAgICAgICAgXG4gICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBtaW5XaWR0aDogMCxcbiAgICAgICAgICAgIG1pbkhlaWdodDogMCxcbiAgICAgICAgICAgIHBhZGRpbmc6IHRoZW1lLnBhZGRpbmcgLyAyLFxuICAgICAgICAgICAgb2JqZWN0OiBudWxsLFxuICAgICAgICAgICAgY29udGFpbmVyOiBudWxsLFxuICAgICAgICAgICAgb2Zmc2V0TGVmdDogOCxcbiAgICAgICAgICAgIG9mZnNldFRvcDogLTgsXG4gICAgICAgICAgICBkZWxheTogMFxuICAgICAgICB9LCBvcHRzKVxuXG4gICAgICAgIG9wdHMuY29udGFpbmVyID0gb3B0cy5jb250YWluZXIgfHwgb3B0cy5vYmplY3RcblxuICAgICAgICBzdXBlcihvcHRzKVxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG5cbiAgICAgICAgLy8gbGF5b3V0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1Rvb2x0aXB9IEEgcmVmZXJlbmNlIHRvIHRoZSB0b29sdGlwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHtcblxuICAgICAgICBzdXBlci5zZXR1cCgpXG5cbiAgICAgICAgLy8gYmluZCBldmVudHMgdGhpc1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuaW50ZXJhY3RpdmUgPSB0cnVlXG5cbiAgICAgICAgbGV0IG1vdXNlb3ZlclRvb2x0aXAgPSBmYWxzZVxuICAgICAgICBcbiAgICAgICAgdGhpcy5vbignbW91c2VvdmVyJywgZSA9PiB7XG4gICAgICAgICAgICBtb3VzZW92ZXJUb29sdGlwID0gdHJ1ZVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMub24oJ21vdXNlb3V0JywgZSA9PiB7XG4gICAgICAgICAgICBtb3VzZW92ZXJUb29sdGlwID0gZmFsc2VcbiAgICAgICAgICAgIGlmICghbW91c2VvdmVyT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLmNvbnRhaW5lci5yZW1vdmVDaGlsZCh0aGlzKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIFxuICAgICAgICAvLyBiaW5kIGV2ZW50cyBvYmplY3RcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBvYmplY3QgPSB0aGlzLm9wdHMub2JqZWN0XG4gICAgICAgIG9iamVjdC5pbnRlcmFjdGl2ZSA9IHRydWVcblxuICAgICAgICBsZXQgbW91c2VvdmVyT2JqZWN0ID0gZmFsc2VcblxuICAgICAgICBvYmplY3Qub24oJ21vdXNlb3ZlcicsIGUgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbW91c2VvdmVyT2JqZWN0ID0gdHJ1ZVxuICAgICAgICAgICAgICAgIHRoaXMudmlzaWJsZSA9IHRydWVcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMuY29udGFpbmVyLmFkZENoaWxkKHRoaXMpXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihlKVxuICAgICAgICAgICAgfSwgdGhpcy5vcHRzLmRlbGF5ICogMTAwMClcbiAgICAgICAgfSlcblxuICAgICAgICBvYmplY3Qub24oJ21vdXNlbW92ZScsIGUgPT4ge1xuICAgICAgICAgICAgaWYgKG1vdXNlb3Zlck9iamVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24oZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBvYmplY3Qub24oJ21vdXNlb3V0JywgZSA9PiB7XG4gICAgICAgICAgICBtb3VzZW92ZXJPYmplY3QgPSBmYWxzZVxuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpXG4gICAgICAgICAgICBpZiAoIW1vdXNlb3ZlclRvb2x0aXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdHMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIGFuZCBzZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgdG9vbHRpcC5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1Rvb2x0aXB9IEEgcmVmZXJlbmNlIHRvIHRoZSB0b29sdGlwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbihlKSB7XG5cbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSBlLmRhdGEuZ2V0TG9jYWxQb3NpdGlvbih0aGlzLm9wdHMuY29udGFpbmVyKVxuXG4gICAgICAgIHRoaXMueCA9IHBvc2l0aW9uLnggKyB0aGlzLm9wdHMub2Zmc2V0TGVmdFxuICAgICAgICB0aGlzLnkgPSBwb3NpdGlvbi55ICsgdGhpcy5vcHRzLm9mZnNldFRvcCAtIHRoaXMuaGVpZ2h0XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG59XG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCBBYnN0cmFjdFBvcHVwIGZyb20gJy4vYWJzdHJhY3Rwb3B1cC5qcydcbmltcG9ydCBUb29sdGlwIGZyb20gJy4vdG9vbHRpcC5qcydcblxuLyoqXG4gKiBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBQaXhpSlMgQmFkZ2UuXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIGFwcFxuICogY29uc3QgYXBwID0gbmV3IFBJWElBcHAoe1xuICogICAgIHZpZXc6IGNhbnZhcyxcbiAqICAgICB3aWR0aDogOTAwLFxuICogICAgIGhlaWdodDogMjUwXG4gKiB9KS5zZXR1cCgpLnJ1bigpXG4gKiBcbiAqIC8vIEFkZCBhbiBEaXNwbGF5T2JqZWN0IHRvIHRoZSBhcHBcbiAqIGNvbnN0IGNpcmNsZSA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAqIGNpcmNsZS5iZWdpbkZpbGwoMHg1MjUxYTMpXG4gKiBjaXJjbGUuZHJhd0NpcmNsZSg1MCwgNTAsIDQwKVxuICogYXBwLnNjZW5lLmFkZENoaWxkKGNpcmNsZSlcbiAqIFxuICogY29uc3QgYmFkZ2UxID0gbmV3IEJhZGdlKHtcbiAqICAgICBvYmplY3Q6IGNpcmNsZSxcbiAqICAgICBjb250YWluZXI6IGFwcC5zY2VuZSxcbiAqICAgICBjb250ZW50OiAnRGFzIEdlc2V0eiBpc3QgZGVyIEZyZXVuZCBkZXMgU2Nod2FjaGVuLidcbiAqIH0pXG4gKlxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBBYnN0cmFjdFBvcHVwXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvYmFkZ2UuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYWRnZSBleHRlbmRzIEFic3RyYWN0UG9wdXAge1xuICAgIFxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBCYWRnZS5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBiYWRnZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluV2lkdGg9MF0gLSBUaGUgbWluaW11bSB3aWR0aCBvZiB0aGUgYmFkZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLm1pbkhlaWdodD0wXSAtIFRoZSBtaW5pbXVtIGhlaWdodCBvZiB0aGUgYmFkZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnBhZGRpbmc9VGhlbWUucGFkZGluZyAvIDJdIC0gVGhlIGlubmVyIHNwYWNpbmcgb2YgdGhlIGJhZGdlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gW29wdHMudG9vbHRpcF0gLSBBIHN0cmluZyBmb3IgdGhlIGxhYmVsIG9mIHRoZSB0b29sdGlwIG9yIGFuIG9iamVjdCB0byBjb25maWd1cmUgdGhlIHRvb2x0aXBcbiAgICAgKiAgICAgdG8gZGlzcGxheS5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICBcbiAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgIG1pbldpZHRoOiAwLFxuICAgICAgICAgICAgbWluSGVpZ2h0OiAwLFxuICAgICAgICAgICAgcGFkZGluZzogdGhlbWUucGFkZGluZyAvIDIsXG4gICAgICAgICAgICB0b29sdGlwOiBudWxsXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgc3VwZXIob3B0cylcblxuICAgICAgICB0aGlzLnRvb2x0aXAgPSBudWxsXG5cbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNldHVwKClcblxuICAgICAgICAvLyBsYXlvdXRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmxheW91dCgpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgY2hpbGRyZW4gYW5kIGluc3RhbnRpYXRlcyBldmVyeXRoaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKiBAcmV0dXJuIHtCYWRnZX0gQSByZWZlcmVuY2UgdG8gdGhlIGJhZGdlIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHtcblxuICAgICAgICBzdXBlci5zZXR1cCgpXG5cbiAgICAgICAgLy8gdG9vbHRpcFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMudG9vbHRpcCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdHMudG9vbHRpcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAgPSBuZXcgVG9vbHRpcCh7b2JqZWN0OiB0aGlzLCBjb250ZW50OiB0aGlzLm9wdHMudG9vbHRpcH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0cy50b29sdGlwID0gT2JqZWN0LmFzc2lnbih7fSwge29iamVjdDogdGhpc30sIHRoaXMub3B0cy50b29sdGlwKVxuICAgICAgICAgICAgICAgIHRoaXMudG9vbHRpcCA9IG5ldyBUb29sdGlwKHRoaXMub3B0cy50b29sdGlwKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIGJhZGdlLiBDYW4gYmUgdXNlZCBhZnRlciByZXNpemluZy5cbiAgICAgKiBcbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKiBAcmV0dXJuIHtCYWRnZX0gQSByZWZlcmVuY2UgdG8gdGhlIGJhZGdlIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG5cbiAgICAgICAgc3VwZXIubGF5b3V0KClcblxuICAgICAgICB0aGlzLmNvbnRlbnQueCA9IHRoaXMud2lkdGggLyAyIC0gdGhpcy5jb250ZW50LndpZHRoIC8gMiAtIHRoaXMub3B0cy5zdHJva2VXaWR0aCAvIDJcbiAgICAgICAgdGhpcy5jb250ZW50LnkgPSB0aGlzLmhlaWdodCAvIDIgLSB0aGlzLmNvbnRlbnQuaGVpZ2h0IC8gMiAtIHRoaXMub3B0cy5zdHJva2VXaWR0aCAvIDJcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cbiIsIlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRzIHtcblxuICAgIHN0YXRpYyBzdG9wKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICB9XG5cbiAgICBzdGF0aWMgZXh0cmFjdFBvaW50KGV2ZW50KSB7XG4gICAgICAgIHN3aXRjaCAoZXZlbnQuY29uc3RydWN0b3IubmFtZSkge1xuICAgICAgICAgICAgY2FzZSAnVG91Y2hFdmVudCc6XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudC50YXJnZXRUb3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ID0gZXZlbnQudGFyZ2V0VG91Y2hlc1tpXVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB4OiB0LmNsaWVudFgsIHk6IHQuY2xpZW50WSB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiB7IHg6IGV2ZW50LmNsaWVudFgsIHk6IGV2ZW50LmNsaWVudFkgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIGlzQ2FwdHVyZWQoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50Ll9fY2FwdHVyZWRCeSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHN0YXRpYyBjYXB0dXJlZEJ5KGV2ZW50LCBvYmopIHtcbiAgICAgICAgZXZlbnQuX19jYXB0dXJlZEJ5ID0gb2JqXG4gICAgfVxuXG4gICAgc3RhdGljIGlzTW91c2VEb3duKGV2ZW50KSB7XG4gICAgICAgIC8vIEF0dGVtcHRzIHRvIGNsb25lIHRoZSB3aGljaCBhdHRyaWJ1dGUgb2YgZXZlbnRzIGZhaWxlZCBpbiBXZWJLaXQuIE1heVxuICAgICAgICAvLyBiZSB0aGlzIGlzIGEgYnVnIG9yIGEgc2VjdXJpdHkgZmVhdHVyZS4gV29ya2Fyb3VuZDogd2UgaW50cm9kdWNlXG4gICAgICAgIC8vIGEgbW91c2VEb3duU3Vic3RpdHV0ZSBhdHRyaWJ1dGUgdGhhdCBjYW4gYmUgYXNzaWduZWQgdG8gY2xvbmVkXG4gICAgICAgIC8vIGV2ZW50cyBhZnRlciBpbnN0YW50aWF0aW9uLlxuICAgICAgICBpZiAoUmVmbGVjdC5oYXMoZXZlbnQsICdtb3VzZURvd25TdWJzdGl0dXRlJykpXG4gICAgICAgICAgICByZXR1cm4gZXZlbnQubW91c2VEb3duU3Vic3RpdHV0ZVxuICAgICAgICByZXR1cm4gZXZlbnQuYnV0dG9ucyB8fCBldmVudC53aGljaFxuICAgIH1cblxuICAgIHN0YXRpYyBpc1NpbXVsYXRlZEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBSZWZsZWN0LmhhcyhldmVudCwgJ21vdXNlRG93blN1YnN0aXR1dGUnKVxuICAgIH1cblxuICAgIHN0YXRpYyBpc01vdXNlUmlnaHRDbGljayhldmVudCkge1xuICAgICAgICByZXR1cm4gZXZlbnQuYnV0dG9ucyB8fCBldmVudC53aGljaFxuICAgIH1cblxuICAgIHN0YXRpYyBleHRyYWN0VG91Y2hlcyh0YXJnZXRzKSB7XG4gICAgICAgIGxldCB0b3VjaGVzID0gW11cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgdCA9IHRhcmdldHNbaV1cbiAgICAgICAgICAgIHRvdWNoZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGFyZ2V0U2VsZWN0b3I6IHRoaXMuc2VsZWN0b3IodC50YXJnZXQpLFxuICAgICAgICAgICAgICAgIGlkZW50aWZpZXI6IHQuaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICBzY3JlZW5YOiB0LnNjcmVlblgsXG4gICAgICAgICAgICAgICAgc2NyZWVuWTogdC5zY3JlZW5ZLFxuICAgICAgICAgICAgICAgIGNsaWVudFg6IHQuY2xpZW50WCxcbiAgICAgICAgICAgICAgICBjbGllbnRZOiB0LmNsaWVudFksXG4gICAgICAgICAgICAgICAgcGFnZVg6IHQucGFnZVgsXG4gICAgICAgICAgICAgICAgcGFnZVk6IHQucGFnZVlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvdWNoZXNcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlVG91Y2hMaXN0KHRhcmdldHMpIHtcbiAgICAgICAgbGV0IHRvdWNoZXMgPSBbXVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB0ID0gdGFyZ2V0c1tpXVxuICAgICAgICAgICAgbGV0IHRvdWNoVGFyZ2V0ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0LnBhZ2VYLCB0LnBhZ2VZKVxuICAgICAgICAgICAgbGV0IHRvdWNoID0gbmV3IFRvdWNoKHVuZGVmaW5lZCwgdG91Y2hUYXJnZXQsIHQuaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICB0LnBhZ2VYLCB0LnBhZ2VZLCB0LnNjcmVlblgsIHQuc2NyZWVuWSlcbiAgICAgICAgICAgIHRvdWNoZXMucHVzaCh0b3VjaClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFRvdWNoTGlzdCguLi50b3VjaGVzKVxuICAgIH1cblxuICAgIHN0YXRpYyBleHRyYWN0RXZlbnQodGltZXN0YW1wLCBldmVudCkge1xuICAgICAgICBsZXQgdGFyZ2V0U2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yKGV2ZW50LnRhcmdldClcbiAgICAgICAgbGV0IGluZm9zID0ge1xuICAgICAgICAgICAgdHlwZTogZXZlbnQudHlwZSxcbiAgICAgICAgICAgIHRpbWU6IHRpbWVzdGFtcCxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiBldmVudC5jb25zdHJ1Y3RvcixcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICB0YXJnZXRTZWxlY3RvcjogdGFyZ2V0U2VsZWN0b3IsXG4gICAgICAgICAgICAgICAgdmlldzogZXZlbnQudmlldyxcbiAgICAgICAgICAgICAgICBtb3VzZURvd25TdWJzdGl0dXRlOiBldmVudC5idXR0b25zIHx8IGV2ZW50LndoaWNoLCAvLyB3aGljaCBjYW5ub3QgYmUgY2xvbmVkIGRpcmVjdGx5XG4gICAgICAgICAgICAgICAgYnViYmxlczogZXZlbnQuYnViYmxlcyxcbiAgICAgICAgICAgICAgICBjYW5jZWxhYmxlOiBldmVudC5jYW5jZWxhYmxlLFxuICAgICAgICAgICAgICAgIHNjcmVlblg6IGV2ZW50LnNjcmVlblgsXG4gICAgICAgICAgICAgICAgc2NyZWVuWTogZXZlbnQuc2NyZWVuWSxcbiAgICAgICAgICAgICAgICBjbGllbnRYOiBldmVudC5jbGllbnRYLFxuICAgICAgICAgICAgICAgIGNsaWVudFk6IGV2ZW50LmNsaWVudFksXG4gICAgICAgICAgICAgICAgbGF5ZXJYOiBldmVudC5sYXllclgsXG4gICAgICAgICAgICAgICAgbGF5ZXJZOiBldmVudC5sYXllclksXG4gICAgICAgICAgICAgICAgcGFnZVg6IGV2ZW50LnBhZ2VYLFxuICAgICAgICAgICAgICAgIHBhZ2VZOiBldmVudC5wYWdlWSxcbiAgICAgICAgICAgICAgICBjdHJsS2V5OiBldmVudC5jdHJsS2V5LFxuICAgICAgICAgICAgICAgIGFsdEtleTogZXZlbnQuYWx0S2V5LFxuICAgICAgICAgICAgICAgIHNoaWZ0S2V5OiBldmVudC5zaGlmdEtleSxcbiAgICAgICAgICAgICAgICBtZXRhS2V5OiBldmVudC5tZXRhS2V5XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LnR5cGUuc3RhcnRzV2l0aCgndG91Y2gnKSkge1xuICAgICAgICAgICAgLy8gT24gU2FmYXJpLVdlYktpdCB0aGUgVG91Y2hFdmVudCBoYXMgbGF5ZXJYLCBsYXllclkgY29vcmRpbmF0ZXNcbiAgICAgICAgICAgIGxldCBkYXRhID0gaW5mb3MuZGF0YVxuICAgICAgICAgICAgZGF0YS50YXJnZXRUb3VjaGVzID0gdGhpcy5leHRyYWN0VG91Y2hlcyhldmVudC50YXJnZXRUb3VjaGVzKVxuICAgICAgICAgICAgZGF0YS5jaGFuZ2VkVG91Y2hlcyA9IHRoaXMuZXh0cmFjdFRvdWNoZXMoZXZlbnQuY2hhbmdlZFRvdWNoZXMpXG4gICAgICAgICAgICBkYXRhLnRvdWNoZXMgPSB0aGlzLmV4dHJhY3RUb3VjaGVzKGV2ZW50LnRvdWNoZXMpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LnR5cGUuc3RhcnRzV2l0aCgncG9pbnRlcicpKSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IGluZm9zLmRhdGFcbiAgICAgICAgICAgIGRhdGEucG9pbnRlcklkID0gZXZlbnQucG9pbnRlcklkXG4gICAgICAgICAgICBkYXRhLnBvaW50ZXJUeXBlID0gZXZlbnQucG9pbnRlclR5cGVcbiAgICAgICAgfVxuICAgICAgICBpZiAoRXZlbnRzLmRlYnVnKSB7XG4gICAgICAgICAgICBFdmVudHMuZXh0cmFjdGVkLnB1c2godGhpcy50b0xpbmUoZXZlbnQpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmZvc1xuICAgIH1cblxuICAgIHN0YXRpYyBjbG9uZUV2ZW50KHR5cGUsIGNvbnN0cnVjdG9yLCBkYXRhKSB7XG4gICAgICAgIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3RvdWNoJykpIHtcbiAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZmluZCB0YXJnZXQgZnJvbSBsYXllclgsIGxheWVyWVxuICAgICAgICAgICAgLy92YXIgdGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihkYXRhLnRhcmdldFNlbGVjdG9yKVxuICAgICAgICAgICAgLy8gZWxlbWVudEZyb21Qb2ludChkYXRhLmxheWVyWCwgZGF0YS5sYXllclkpXG4gICAgICAgICAgICAvL2RhdGEudGFyZ2V0ID0gdGFyZ2V0XG4gICAgICAgICAgICBkYXRhLnRhcmdldFRvdWNoZXMgPSB0aGlzLmNyZWF0ZVRvdWNoTGlzdChkYXRhLnRhcmdldFRvdWNoZXMpXG4gICAgICAgICAgICBkYXRhLmNoYW5nZWRUb3VjaGVzID0gdGhpcy5jcmVhdGVUb3VjaExpc3QoZGF0YS5jaGFuZ2VkVG91Y2hlcylcbiAgICAgICAgICAgIGRhdGEudG91Y2hlcyA9IHRoaXMuY3JlYXRlVG91Y2hMaXN0KGRhdGEudG91Y2hlcylcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBuZWVkIHRvIGZpbmQgdGFyZ2V0IGZyb20gcGFnZVgsIHBhZ2VZIHdoaWNoIGFyZSBvbmx5XG4gICAgICAgIC8vIGF2YWlsYWJsZSBhZnRlciBjb25zdHJ1Y3Rpb24uIFRoZXkgc2VlbSB0byBnZXR0ZXIgaXRlbXMuXG5cbiAgICAgICAgbGV0IGNsb25lID0gUmVmbGVjdC5jb25zdHJ1Y3QoY29uc3RydWN0b3IsIFt0eXBlLCBkYXRhXSlcbiAgICAgICAgY2xvbmUubW91c2VEb3duU3Vic3RpdHV0ZSA9IGRhdGEubW91c2VEb3duU3Vic3RpdHV0ZVxuICAgICAgICByZXR1cm4gY2xvbmVcbiAgICB9XG5cbiAgICBzdGF0aWMgc2ltdWxhdGVFdmVudCh0eXBlLCBjb25zdHJ1Y3RvciwgZGF0YSkge1xuICAgICAgICBkYXRhLnRhcmdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZGF0YS50YXJnZXRTZWxlY3RvcilcbiAgICAgICAgbGV0IGNsb25lID0gdGhpcy5jbG9uZUV2ZW50KHR5cGUsIGNvbnN0cnVjdG9yLCBkYXRhKVxuICAgICAgICBpZiAoZGF0YS50YXJnZXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgZGF0YS50YXJnZXQuZGlzcGF0Y2hFdmVudChjbG9uZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAoRXZlbnRzLmRlYnVnKSB7XG4gICAgICAgICAgICBFdmVudHMuc2ltdWxhdGVkLnB1c2godGhpcy50b0xpbmUoY2xvbmUpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIHRvTGluZShldmVudCkge1xuICAgICAgICByZXR1cm4gYCR7ZXZlbnQudHlwZX0gIyR7ZXZlbnQudGFyZ2V0LmlkfSAke2V2ZW50LmNsaWVudFh9ICR7ZXZlbnQuY2xpZW50WX1gXG4gICAgICAgIGxldCByZXN1bHQgPSBldmVudC50eXBlXG4gICAgICAgIGxldCBzZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IoZXZlbnQudGFyZ2V0KVxuICAgICAgICByZXN1bHQgKz0gJyBzZWxlY3RvcjogJyArIHNlbGVjdG9yXG4gICAgICAgIGlmIChldmVudC50YXJnZXQgIT0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikpXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnQ2Fubm90IHJlc29sdmUnLCBzZWxlY3RvcilcbiAgICAgICAgbGV0IGtleXMgPSBbJ2xheWVyWCcsICdsYXllclknLCAncGFnZVgnLCAncGFnZVknLCAnY2xpZW50WCcsICdjbGllbnRZJ11cbiAgICAgICAgZm9yIChsZXQga2V5IG9mIGtleXMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9ICcgJyArIGtleSArICc6JyArIGV2ZW50W2tleV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0ludmFsaWQga2V5OiAnICsga2V5KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBzdGF0aWMgY29tcGFyZUV4dHJhY3RlZFdpdGhTaW11bGF0ZWQoKSB7XG4gICAgICAgIHZhciBkaWZmcyA9IDBcbiAgICAgICAgaWYgKHRoaXMuZXh0cmFjdGVkLmxlbmd0aCAhPSB0aGlzLnNpbXVsYXRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdVbmVxdWFsIGxlbmd0aCBvZiBleHRyYWN0ZWQgWycgKyB0aGlzLmV4dHJhY3RlZC5sZW5ndGggK1xuICAgICAgICAgICAgICAgICddIGFuZCBzaW11bGF0ZWQgZXZlbnRzIFsnICsgdGhpcy5zaW11bGF0ZWQubGVuZ3RoICsgJ10uJylcbiAgICAgICAgICAgIGRpZmZzICs9IDFcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5leHRyYWN0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0ZWRbaV1cbiAgICAgICAgICAgICAgICB2YXIgc2ltdWxhdGVkID0gdGhpcy5zaW11bGF0ZWRbaV1cbiAgICAgICAgICAgICAgICBpZiAoZXh0cmFjdGVkICE9IHNpbXVsYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnRXZlbnRzIGRpZmZlcjonICsgZXh0cmFjdGVkICsgJ3wnICsgc2ltdWxhdGVkKVxuICAgICAgICAgICAgICAgICAgICBkaWZmcyArPSAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIHNlbGVjdG9yKGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIE9wdGltYWxTZWxlY3Quc2VsZWN0KGNvbnRleHQpXG4gICAgfVxuXG4gICAgc3RhdGljIHJlc2V0KCkge1xuICAgICAgICB0aGlzLmV4dHJhY3RlZCA9IFtdXG4gICAgICAgIHRoaXMuc2ltdWxhdGVkID0gW11cbiAgICB9XG5cbiAgICBzdGF0aWMgcmVzZXRTaW11bGF0ZWQoKSB7XG4gICAgICAgIHRoaXMuc2ltdWxhdGVkID0gW11cbiAgICB9XG5cbiAgICBzdGF0aWMgc2hvd0V4dHJhY3RlZEV2ZW50cyhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wb3B1cCA9PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICAgICAgICBFbGVtZW50cy5zZXRTdHlsZShlbGVtZW50LCB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgd2lkdGg6ICc0ODBweCcsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnNjQwcHgnLFxuICAgICAgICAgICAgICAgIG92ZXJmbG93OiAnYXV0bycsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAnbGlnaHRncmF5J1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWxlbWVudClcbiAgICAgICAgICAgIHRoaXMucG9wdXAgPSBlbGVtZW50XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wb3B1cC5pbm5lckhUTUwgPSAnJ1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIHRoaXMuZXh0cmFjdGVkKSB7XG4gICAgICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgICAgIGRpdi5pbm5lckhUTUwgPSBsaW5lXG4gICAgICAgICAgICB0aGlzLnBvcHVwLmFwcGVuZENoaWxkKGRpdilcbiAgICAgICAgfVxuICAgICAgICBsZXQgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgZGl2LmlubmVySFRNTCA9ICctLS0tLS0tLS0tLS0gU2ltdWxhdGVkIC0tLS0tLS0tLS0tJ1xuICAgICAgICB0aGlzLnBvcHVwLmFwcGVuZENoaWxkKGRpdilcbiAgICAgICAgZm9yIChsZXQgbGluZSBvZiB0aGlzLnNpbXVsYXRlZCkge1xuICAgICAgICAgICAgbGV0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gbGluZVxuICAgICAgICAgICAgdGhpcy5wb3B1cC5hcHBlbmRDaGlsZChkaXYpXG4gICAgICAgIH1cbiAgICAgICAgRWxlbWVudHMuc2V0U3R5bGUodGhpcy5wb3B1cCxcbiAgICAgICAgICAgIHsgbGVmdDogZXZlbnQuY2xpZW50WCArICdweCcsIHRvcDogZXZlbnQuY2xpZW50WSArICdweCcgfSlcbiAgICB9XG59XG5cbkV2ZW50cy5wb3B1cCA9IG51bGxcbkV2ZW50cy5kZWJ1ZyA9IHRydWVcbkV2ZW50cy5leHRyYWN0ZWQgPSBbXVxuRXZlbnRzLnNpbXVsYXRlZCA9IFtdXG5FdmVudHMuc2ltdWxhdGlvblJ1bm5pbmcgPSBmYWxzZVxuXG5leHBvcnQgY2xhc3MgRXZlbnRSZWNvcmRlciB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5yZWNvcmRpbmcgPSBbXVxuICAgICAgICB0aGlzLnJlY29yZGVkID0gW11cbiAgICAgICAgdGhpcy5zdGVwID0gMFxuICAgIH1cblxuICAgIHJlY29yZChldmVudCkge1xuICAgICAgICBsZXQgbGVuZ3RoID0gdGhpcy5yZWNvcmRpbmcubGVuZ3RoXG4gICAgICAgIGlmIChsZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSBldmVudC50aW1lU3RhbXBcbiAgICAgICAgICAgIEV2ZW50cy5yZXNldCgpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbGFzdCA9IHRoaXMucmVjb3JkaW5nW2xlbmd0aCAtIDFdXG4gICAgICAgICAgICBpZiAoZXZlbnQudGltZVN0YW1wIDwgbGFzdC50aW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3dhcm5pbmc6IHdyb25nIHRlbXBvcmFsIG9yZGVyJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgdCA9IGV2ZW50LnRpbWVTdGFtcCAtIHRoaXMuc3RhcnRUaW1lXG4gICAgICAgIHRoaXMucmVjb3JkaW5nLnB1c2goRXZlbnRzLmV4dHJhY3RFdmVudCh0LCBldmVudCkpXG4gICAgfVxuXG4gICAgc3RvcFJlY29yZGluZygpIHtcbiAgICAgICAgdGhpcy5yZWNvcmRlZCA9IHRoaXMucmVjb3JkaW5nXG4gICAgICAgIHRoaXMucmVjb3JkaW5nID0gW11cbiAgICAgICAgY29uc29sZS5sb2coJ1JlY29yZGVkICcgKyB0aGlzLnJlY29yZGVkLmxlbmd0aCArICcgZXZlbnRzJylcbiAgICB9XG5cbiAgICBzdGFydFJlcGxheSh3aGlsZUNvbmRpdGlvbiA9IG51bGwsIG9uQ29tcGxldGUgPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RlcCA9IDBcbiAgICAgICAgRXZlbnRzLnJlc2V0U2ltdWxhdGVkKClcbiAgICAgICAgY29uc29sZS5sb2coJ1N0YXJ0IHJlcGxheScpXG4gICAgICAgIEV2ZW50cy5zaW11bGF0aW9uUnVubmluZyA9IHRydWVcbiAgICAgICAgdGhpcy5yZXBsYXkod2hpbGVDb25kaXRpb24sIG9uQ29tcGxldGUpXG4gICAgfVxuXG4gICAgcmVwbGF5KHdoaWxlQ29uZGl0aW9uID0gbnVsbCwgb25Db21wbGV0ZSA9IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RlcCA8IHRoaXMucmVjb3JkZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICBsZXQgeyB0eXBlLCB0aW1lLCBjb25zdHJ1Y3RvciwgZGF0YSB9ID0gdGhpcy5yZWNvcmRlZFt0aGlzLnN0ZXBdXG4gICAgICAgICAgICBFdmVudHMuc2ltdWxhdGVFdmVudCh0eXBlLCBjb25zdHJ1Y3RvciwgZGF0YSlcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgdGhpcy5zdGVwICs9IDFcbiAgICAgICAgICAgIGxldCBkdCA9IDBcbiAgICAgICAgICAgIGlmICh0aGlzLnN0ZXAgPCB0aGlzLnJlY29yZGVkLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHZhciBuZXh0ID0gdGhpcy5yZWNvcmRlZFt0aGlzLnN0ZXBdXG4gICAgICAgICAgICAgICAgZHQgPSBuZXh0LnRpbWUgLSB0aW1lXG4gICAgICAgICAgICAgICAgaWYgKGR0IDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnd2FybmluZzogd3JvbmcgdGVtcG9yYWwgb3JkZXInKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh3aGlsZUNvbmRpdGlvbiA9PSBudWxsIHx8IHdoaWxlQ29uZGl0aW9uKCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgZGVsdGEgPSBNYXRoLnJvdW5kKGR0KVxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZXBsYXkod2hpbGVDb25kaXRpb24sIG9uQ29tcGxldGUpLCBkZWx0YSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdQbGF5ZWQgJyArIHRoaXMuc3RlcCArICcgZXZlbnRzJyArIG9uQ29tcGxldGUpXG4gICAgICAgICAgICBFdmVudHMuc2ltdWxhdGlvblJ1bm5pbmcgPSBmYWxzZVxuICAgICAgICAgICAgaWYgKG9uQ29tcGxldGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG9uQ29tcGxldGUoKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9FdmVudHMuY29tcGFyZUV4dHJhY3RlZFdpdGhTaW11bGF0ZWQoKVxuICAgICAgICB9XG4gICAgfVxufVxuXG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCBUb29sdGlwIGZyb20gJy4vdG9vbHRpcC5qcydcbmltcG9ydCBCYWRnZSBmcm9tICcuL2JhZGdlLmpzJ1xuaW1wb3J0IEV2ZW50cyBmcm9tICcuLi9ldmVudHMuanMnXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBidXR0b24gYWN0aW9uLlxuICpcbiAqIEBjYWxsYmFjayBhY3Rpb25DYWxsYmFja1xuICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7QnV0dG9ufSBidXR0b24gLSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBidXR0b24pLlxuICovXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBidXR0b24gYmVmb3JlQWN0aW9uLlxuICpcbiAqIEBjYWxsYmFjayBiZWZvcmVBY3Rpb25DYWxsYmFja1xuICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7QnV0dG9ufSBidXR0b24gLSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBidXR0b24pLlxuICovXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBidXR0b24gYWZ0ZXJBY3Rpb24uXG4gKlxuICogQGNhbGxiYWNrIGFmdGVyQWN0aW9uQ2FsbGJhY2tcbiAqIEBwYXJhbSB7b2JqZWN0fSBldmVudCAtIFRoZSBldmVudCBvYmplY3QuXG4gKiBAcGFyYW0ge0J1dHRvbn0gYnV0dG9uIC0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiAoYWxzbyB0aGlzIHJlZmVycyB0byB0aGUgYnV0dG9uKS5cbiAqL1xuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBCdXR0b24uXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSB0aGUgYnV0dG9uXG4gKiBjb25zdCBidXR0b24gPSBuZXcgQnV0dG9uKHtcbiAqICAgICBsYWJlbDogJ015IEJ1dHRvbicsXG4gKiAgICAgYWN0aW9uOiAoKSA9PiBjb25zb2xlLmxvZygnQnV0dG9uIHdhcyBjbGlja2VkJylcbiAqIH0pXG4gKlxuICogLy8gQWRkIHRoZSBidXR0b24gdG8gYSBEaXNwbGF5T2JqZWN0XG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQoYnV0dG9uKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5Db250YWluZXJcbiAqIEBzZWUge0BsaW5rIGh0dHA6Ly9waXhpanMuZG93bmxvYWQvZGV2L2RvY3MvUElYSS5Db250YWluZXIuaHRtbHxQSVhJLkNvbnRhaW5lcn1cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS9idXR0b24uaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdXR0b24gZXh0ZW5kcyBQSVhJLkNvbnRhaW5lciB7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgQnV0dG9uLlxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IHRvIHNwZWNpZnkgdG8gc3R5bGUgYW5kIGJlaGF2aW91ciBvZiB0aGUgYnV0dG9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5pZD1hdXRvIGdlbmVyYXRlZF0gLSBUaGUgaWQgb2YgdGhlIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubGFiZWxdIC0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLng9MF0gLSBUaGUgeCBwb3NpdGlvbiBvZiB0aGUgYnV0dG9uLiBDYW4gYmUgYWxzbyBzZXQgYWZ0ZXIgY3JlYXRpb24gd2l0aCBidXR0b24ueCA9IDAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnk9MF0gLSBUaGUgeSBwb3NpdGlvbiBvZiB0aGUgYnV0dG9uLiBDYW4gYmUgYWxzbyBzZXQgYWZ0ZXIgY3JlYXRpb24gd2l0aCBidXR0b24ueSA9IDAuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8VGhlbWV9IFtvcHRzLnRoZW1lPWRhcmtdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3IgdGhpcyBidXR0b24uIFBvc3NpYmxlIHZhbHVlcyBhcmUgZGFyaywgbGlnaHQsIHJlZFxuICAgICAqICAgICBvciBhIFRoZW1lIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluV2lkdGg9NDRdIC0gVGhlIG1pbmltdW0gd2lkdGggb2YgdGhlIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluSGVpZ2h0PTQ0XSAtIFRoZSBtaW5pbXVtIGhlaWdodCBvZiB0aGUgYnV0dG9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5wYWRkaW5nPVRoZW1lLnBhZGRpbmddIC0gVGhlIGlubmVyIHNwYWNpbmcgKGRpc3RhbmNlIGZyb20gaWNvbiBhbmQvb3IgbGFiZWwpIHRvIHRoZSBib3JkZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8UElYSS5EaXNwbGF5T2JqZWN0fSBbb3B0cy5pY29uXSAtIFRoZSBpY29uIG9mIHRoZSBidXR0b24uIENhbiBiZSBhIHByZWRlZmluZWQgb25lLCBhbiBVUkwgb3IgYW4gUElYSS5EaXNwbGF5T2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFBJWEkuRGlzcGxheU9iamVjdH0gW29wdHMuaWNvbkFjdGl2ZT1pY29uXSAtIFRoZSBpY29uIG9mIHRoZSBidXR0b24gd2hlbiBhY3RpdmF0ZWQuIENhbiBiZSBhIHByZWRlZmluZWQgb25lLCBhbiBVUkwgb3IgYW4gUElYSS5EaXNwbGF5T2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5pY29uUG9zaXRpb249bGVmdF0gLSBUaGUgcG9zaXRpb24gb2YgdGhlIGljb24gaW4gcmVsYXRpb24gdG8gdGhlIGxhYmVsLiBDYW4gYmUgbGVmdCBvciByaWdodC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaWNvbkNvbG9yPVRoZW1lLmljb25Db2xvcl0gLSBUaGUgY29sb3Igb2YgdGhlIGljb24gKHNldCBieSB0aGUgdGludCBwcm9wZXJ0eSkgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmljb25Db2xvckFjdGl2ZT1UaGVtZS5pY29uQ29sb3JBY3RpdmVdIC0gVGhlIGNvbG9yIG9mIHRoZSBpY29uIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsPVRoZW1lLmZpbGxdIC0gVGhlIGNvbG9yIG9mIHRoZSBidXR0b24gYmFja2dyb3VuZCBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFscGhhPVRoZW1lLmZpbGxBbHBoYV0gLSBUaGUgYWxwaGEgdmFsdWUgb2YgdGhlIGJhY2tncm91bmQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBY3RpdmU9VGhlbWUuZmlsbEFjdGl2ZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJ1dHRvbiBiYWNrZ3JvdW5kIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsQWN0aXZlQWxwaGE9VGhlbWUuZmlsbEFjdGl2ZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlPVRoZW1lLnN0cm9rZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlV2lkdGg9VGhlbWUuc3Ryb2tlV2lkdGhdIC0gVGhlIHdpZHRoIG9mIHRoZSBib3JkZXIgaW4gcGl4ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmU9VGhlbWUuc3Ryb2tlQWN0aXZlXSAtIFRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmVXaWR0aD1UaGVtZS5zdHJva2VBY3RpdmVXaWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlQWxwaGE9VGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZT1UaGVtZS50ZXh0U3R5bGVdIC0gQSB0ZXh0c3R5bGUgb2JqZWN0IGZvciB0aGUgc3R5bGluZyBvZiB0aGUgbGFiZWwuIFNlZSBQSVhJLlRleHRTdHlsZVxuICAgICAqICAgICBmb3IgcG9zc2libGUgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMudGV4dFN0eWxlQWN0aXZlPVRoZW1lLnRleHRTdHlsZUFjdGl2ZV0gLSBBIHRleHRzdHlsZSBvYmplY3QgZm9yIHRoZSBzdHlsaW5nIG9mIHRoZSBsYWJlbCB3aGVuIHRoZVxuICAgICAqICAgICBidXR0b24gaXMgYWN0aXZhdGVkLiBTZWUgUElYSS5UZXh0U3R5bGUgZm9yIHBvc3NpYmxlIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLnN0eWxlPWRlZmF1bHRdIC0gQSBzaG9ydGN1dCBmb3Igc3R5bGluZyBvcHRpb25zLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGRlZmF1bHQsIGxpbmsuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnJhZGl1cz1UaGVtZS5yYWRpdXNdIC0gVGhlIHJhZGl1cyBvZiB0aGUgZm91ciBjb3JuZXJzIG9mIHRoZSBidXR0b24gKHdoaWNoIGlzIGEgcm91bmRlZCByZWN0YW5nbGUpLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZGlzYWJsZWQ9ZmFsc2VdIC0gSXMgdGhlIGJ1dHRvbiBkaXNhYmxlZD8gV2hlbiBkaXNhYmxlZCwgdGhlIGJ1dHRvbiBoYXMgYSBsb3dlciBhbHBoYSB2YWx1ZVxuICAgICAqICAgICBhbmQgY2Fubm90IGJlIGNsaWNrZWQgKGludGVyYWN0aXZlIGlzIHNldCB0byBmYWxzZSkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5hY3RpdmU9ZmFsc2VdIC0gSXMgdGhlIGJ1dHRvbiBpbml0aWFsbHkgYWN0aXZlP1xuICAgICAqIEBwYXJhbSB7YWN0aW9uQ2FsbGJhY2t9IFtvcHRzLmFjdGlvbl0gLSBFeGVjdXRlZCB3aGVuIHRoZSBidXR0b24gd2FzIHRyaWdnZXJlZCAoYnkgcG9pbnRlcnVwKS5cbiAgICAgKiBAcGFyYW0ge2JlZm9yZUFjdGlvbkNhbGxiYWNrfSBbb3B0cy5iZWZvcmVBY3Rpb25dIC0gRXhlY3V0ZWQgYmVmb3JlIHRoZSBtYWluIGFjdGlvbiBpcyB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHthZnRlckFjdGlvbkNhbGxiYWNrfSBbb3B0cy5hZnRlckFjdGlvbl0gLSBFeGVjdXRlZCBhZnRlciB0aGUgbWFpbiBhY3Rpb24gd2FzIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudHlwZT1kZWZhdWx0XSAtIFRoZSB0eXBlIG9mIHRoZSBidXR0b24uIENhbiBiZSBkZWZhdWx0IG9yIGNoZWNrYm94LiBXaGVuIHRoZSB0eXBlIGlzXG4gICAgICogICAgIGNoZWNrYm94LCB0aGUgYWN0aXZlIHN0YXRlIGlzIHRvZ2dsZWQgYXV0b21hdGljYWxseS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuYWxpZ249Y2VudGVyXSAtIFRoZSBob3Jpem9udGFsIHBvc2l0aW9uIG9mIHRoZSBsYWJlbCBhbmQgdGhlIGljb24uIFBvc3NpYmxlIHZhbHVlcyBhcmVcbiAgICAgKiAgICAgbGVmdCwgY2VudGVyIGFuZCByaWdodC4gT25seSBhZmZlY3RzIHRoZSBzdHlsZSB3aGVuIHRoZSBtaW5XaWR0aCBpcyBiaWdnZXIgdGhhbiB0aGUgd2lkdGggb2YgdGhlIGljb24gYW5kIGxhYmVsLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy52ZXJ0aWNhbEFsaWduPW1pZGRsZV0gLSBUaGUgdmVydGljYWwgcG9zaXRpb24gb2YgdGhlIGxhYmVsIGFuZCB0aGUgaWNvbi4gUG9zc2libGUgdmFsdWVzIGFyZVxuICAgICAqICAgICB0b3AsIG1pZGRsZSBhbmQgYnV0dG9uLiBPbmx5IGFmZmVjdHMgdGhlIHN0eWxlIHdoZW4gdGhlIG1pbkhlaWdodCBpcyBiaWdnZXIgdGhhbiB0aGUgaGVpZ2h0IG9mIHRoZSBpY29uIGFuZCBsYWJlbC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IFtvcHRzLnRvb2x0aXBdIC0gQSBzdHJpbmcgZm9yIHRoZSBsYWJlbCBvZiB0aGUgdG9vbHRpcCBvciBhbiBvYmplY3QgdG8gY29uZmlndXJlIHRoZSB0b29sdGlwXG4gICAgICogICAgIHRvIGRpc3BsYXkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8b2JqZWN0fSBbb3B0cy5iYWRnZV0gLSBBIHN0cmluZyBmb3IgdGhlIGxhYmVsIG9mIHRoZSBiYWRnZSBvciBhbiBvYmplY3QgdG8gY29uZmlndXJlIHRoZSBiYWRnZSB0byBkaXNwbGF5LlxuICAgICAqICAgICBJZiB0aGUgcGFyYW1ldGVyIGlzIGFuIG9iamVjdCwgYWxsIGJhZGdlIG9wdGlvbnMgY2FuIGJlIHNldCBwbHVzIHRoZSBmb2xsb3dpbmc6XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJhZGdlLmFsaWduPXJpZ2h0XSAtIFRoZSBob3Jpem9udGFsIGFsaWdubWVudCBvZiB0aGUgYmFkZ2UuIFBvc3NpYmxlIHZhbHVlczogbGVmdCwgY2VudGVyLCByaWdodFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5iYWRnZS52ZXJ0aWNhbEFsaWduPXRvcF0gLSBUaGUgdmVydGljYWwgYWxpZ25tZW50IG9mIHRoZSBiYWRnZS4gUG9zc2libGUgdmFsdWVzOiB0b3AsIG1pZGRsZSwgYm90dG9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmJhZGdlLm9mZnNldExlZnQ9MF0gLSBUaGUgaG9yaXpvbnRhbCBzaGlmdCBvZiB0aGUgYmFkZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmJhZGdlLm9mZnNldFRvcD0wXSAtIFRoZSB2ZXJ0aWNhbCBzaGlmdCBvZiB0aGUgYmFkZ2UuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy52aXNpYmxlPXRydWVdIC0gSXMgdGhlIGJ1dHRvbiBpbml0aWFsbHkgdmlzaWJsZSAocHJvcGVydHkgdmlzaWJsZSk/XG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG5cbiAgICAgICAgc3VwZXIoKVxuXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICB0aGlzLnRoZW1lID0gdGhlbWVcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBpZDogUElYSS51dGlscy51aWQoKSxcbiAgICAgICAgICAgIGxhYmVsOiBudWxsLFxuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICBtaW5XaWR0aDogNDQsXG4gICAgICAgICAgICBtaW5IZWlnaHQ6IDQ0LFxuICAgICAgICAgICAgcGFkZGluZzogdGhlbWUucGFkZGluZyxcbiAgICAgICAgICAgIGljb246IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGljb25BY3RpdmU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGljb25Qb3NpdGlvbjogJ2xlZnQnLFxuICAgICAgICAgICAgaWNvbkNvbG9yOiB0aGVtZS5pY29uQ29sb3IsXG4gICAgICAgICAgICBpY29uQ29sb3JBY3RpdmU6IHRoZW1lLmljb25Db2xvckFjdGl2ZSxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIGZpbGxBY3RpdmU6IHRoZW1lLmZpbGxBY3RpdmUsXG4gICAgICAgICAgICBmaWxsQWN0aXZlQWxwaGE6IHRoZW1lLmZpbGxBY3RpdmVBbHBoYSxcbiAgICAgICAgICAgIHN0cm9rZTogdGhlbWUuc3Ryb2tlLFxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoZW1lLnN0cm9rZVdpZHRoLFxuICAgICAgICAgICAgc3Ryb2tlQWxwaGE6IHRoZW1lLnN0cm9rZUFscGhhLFxuICAgICAgICAgICAgc3Ryb2tlQWN0aXZlOiB0aGVtZS5zdHJva2VBY3RpdmUsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVXaWR0aDogdGhlbWUuc3Ryb2tlQWN0aXZlV2lkdGgsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVBbHBoYTogdGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGEsXG4gICAgICAgICAgICB0ZXh0U3R5bGU6IHRoZW1lLnRleHRTdHlsZSxcbiAgICAgICAgICAgIHRleHRTdHlsZUFjdGl2ZTogdGhlbWUudGV4dFN0eWxlQWN0aXZlLFxuICAgICAgICAgICAgc3R5bGU6ICdkZWZhdWx0JyxcbiAgICAgICAgICAgIHJhZGl1czogdGhlbWUucmFkaXVzLFxuICAgICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgICAgIGFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIGJlZm9yZUFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIGFmdGVyQWN0aW9uOiBudWxsLFxuICAgICAgICAgICAgdHlwZTogJ2RlZmF1bHQnLFxuICAgICAgICAgICAgYWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgICAgICB0b29sdGlwOiBudWxsLFxuICAgICAgICAgICAgYmFkZ2U6IG51bGwsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub3B0cy5pZFxuXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLmljb24gPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB0aGlzLm9wdHMuaWNvbkFjdGl2ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy5pY29uID0gdGhpcy5vcHRzLmljb25BY3RpdmVcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5vcHRzLmljb24gIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB0aGlzLm9wdHMuaWNvbkFjdGl2ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy5pY29uQWN0aXZlID0gdGhpcy5vcHRzLmljb25cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdHMuc3R5bGUgPT09ICdsaW5rJykge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLm9wdHMsIHtzdHJva2VBbHBoYTogMCwgc3Ryb2tlQWN0aXZlQWxwaGE6IDAsIGZpbGxBbHBoYTogMCwgZmlsbEFjdGl2ZUFscGhhOiAwfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IG51bGxcbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSBudWxsXG5cbiAgICAgICAgdGhpcy5pY29uSW5hY3RpdmUgPSBudWxsXG4gICAgICAgIHRoaXMuaWNvbkFjdGl2ZSA9IG51bGxcbiAgICAgICAgdGhpcy50ZXh0ID0gbnVsbFxuXG4gICAgICAgIHRoaXMuYnV0dG9uID0gbnVsbFxuICAgICAgICB0aGlzLmNvbnRlbnQgPSBudWxsXG5cbiAgICAgICAgdGhpcy50b29sdGlwID0gbnVsbFxuICAgICAgICB0aGlzLmJhZGdlID0gbnVsbFxuXG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHRoaXMub3B0cy52aXNpYmxlXG5cbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNldHVwKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXB0dXJlcyBhbiBldmVudCB0byBpbmZvcm0gSW50ZXJhY3Rpb25NYXBwZXIgYWJvdXQgcHJvY2Vzc2VkIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7ZXZlbnR8UElYSS5JbnRlcmFjdGlvbkV2ZW50fSBldmVudCAtIFRoZSBQSVhJIGV2ZW50IHRvIGNhcHR1cmUuXG4gICAgICovXG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICBFdmVudHMuY2FwdHVyZWRCeShldmVudC5kYXRhLm9yaWdpbmFsRXZlbnQsIHRoaXMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBjaGlsZHJlbiBhbmQgaW5zdGFudGlhdGVzIGV2ZXJ5dGhpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge0J1dHRvbn0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG5cbiAgICAgICAgLy8gQnV0dG9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgbGV0IGJ1dHRvbiA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgdGhpcy5idXR0b24gPSBidXR0b25cbiAgICAgICAgdGhpcy5hZGRDaGlsZChidXR0b24pXG5cbiAgICAgICAgLy8gQ29udGVudFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGxldCBjb250ZW50ID0gbmV3IFBJWEkuQ29udGFpbmVyKClcbiAgICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudFxuICAgICAgICB0aGlzLmFkZENoaWxkKGNvbnRlbnQpXG5cbiAgICAgICAgLy8gVGV4dFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMubGFiZWwpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dCA9IG5ldyBQSVhJLlRleHQodGhpcy5vcHRzLmxhYmVsLCB0aGlzLm9wdHMudGV4dFN0eWxlKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWNvblxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMuaWNvbikge1xuICAgICAgICAgICAgdGhpcy5pY29uSW5hY3RpdmUgPSB0aGlzLmxvYWRJY29uKHRoaXMub3B0cy5pY29uLCB0aGlzLm9wdHMuaWNvbkNvbG9yKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5pY29uQWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLmljb25BY3RpdmUgPSB0aGlzLmxvYWRJY29uKHRoaXMub3B0cy5pY29uQWN0aXZlLCB0aGlzLm9wdHMuaWNvbkNvbG9yQWN0aXZlKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaW50ZXJhY3Rpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmJ1dHRvbi5vbigncG9pbnRlcm92ZXInLCBlID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FwdHVyZShlKVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKFt0aGlzLmJ1dHRvbiwgdGhpcy5jb250ZW50XSwgdGhpcy50aGVtZS5mYXN0LCB7YWxwaGE6IC44Mywgb3ZlcndyaXRlOiAnbm9uZSd9KVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuYnV0dG9uLm9uKCdwb2ludGVybW92ZScsIGUgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYXB0dXJlKGUpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5idXR0b24ub24oJ3BvaW50ZXJvdXQnLCBlID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FwdHVyZShlKVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKFt0aGlzLmJ1dHRvbiwgdGhpcy5jb250ZW50XSwgdGhpcy50aGVtZS5mYXN0LCB7YWxwaGE6IDEsIG92ZXJ3cml0ZTogJ25vbmUnfSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmJ1dHRvbi5vbigncG9pbnRlcmRvd24nLCBlID0+IHtcbiAgICAgICAgICAgIC8vdGhpcy5jYXB0dXJlKGUpXG4gICAgICAgICAgICBUd2VlbkxpdGUudG8oW3RoaXMuYnV0dG9uLCB0aGlzLmNvbnRlbnRdLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogLjcsIG92ZXJ3cml0ZTogJ25vbmUnfSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmJ1dHRvbi5vbigncG9pbnRlcnVwJywgZSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhcHR1cmUoZSlcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuYmVmb3JlQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRzLmJlZm9yZUFjdGlvbi5jYWxsKHRoaXMsIGUsIHRoaXMpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRzLmFjdGlvbi5jYWxsKHRoaXMsIGUsIHRoaXMpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byhbdGhpcy5idXR0b24sIHRoaXMuY29udGVudF0sIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAuODMsIG92ZXJ3cml0ZTogJ25vbmUnfSlcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy50eXBlID09PSAnY2hlY2tib3gnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmUgPSAhdGhpcy5hY3RpdmVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5hZnRlckFjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0cy5hZnRlckFjdGlvbi5jYWxsKHRoaXMsIGUsIHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gZGlzYWJsZWRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmRpc2FibGVkID0gdGhpcy5vcHRzLmRpc2FibGVkXG5cbiAgICAgICAgLy8gYWN0aXZlXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5hY3RpdmUgPSB0aGlzLm9wdHMuYWN0aXZlICAgICAgLy8gY2FsbHMgLmxheW91dCgpXG5cbiAgICAgICAgLy8gdG9vbHRpcFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMudG9vbHRpcCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdHMudG9vbHRpcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAgPSBuZXcgVG9vbHRpcCh7b2JqZWN0OiB0aGlzLCBjb250ZW50OiB0aGlzLm9wdHMudG9vbHRpcH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0cy50b29sdGlwID0gT2JqZWN0LmFzc2lnbih7fSwge29iamVjdDogdGhpc30sIHRoaXMub3B0cy50b29sdGlwKVxuICAgICAgICAgICAgICAgIHRoaXMudG9vbHRpcCA9IG5ldyBUb29sdGlwKHRoaXMub3B0cy50b29sdGlwKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmFkZ2VcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmJhZGdlKSB7XG4gICAgICAgICAgICBsZXQgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgICAgICBhbGlnbjogJ3JpZ2h0JyxcbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAndG9wJyxcbiAgICAgICAgICAgICAgICBvZmZzZXRMZWZ0OiAwLFxuICAgICAgICAgICAgICAgIG9mZnNldFRvcDogMFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLmJhZGdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKG9wdHMsIHtjb250ZW50OiB0aGlzLm9wdHMuYmFkZ2V9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvcHRzID0gT2JqZWN0LmFzc2lnbihvcHRzLCB0aGlzLm9wdHMuYmFkZ2UpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGJhZGdlID0gbmV3IEJhZGdlKG9wdHMpXG5cbiAgICAgICAgICAgIHN3aXRjaCAob3B0cy5hbGlnbikge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgICAgICAgICAgICBiYWRnZS54ID0gdGhpcy54IC0gYmFkZ2Uud2lkdGggLyAyICsgb3B0cy5vZmZzZXRMZWZ0XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSAnY2VudGVyJzpcbiAgICAgICAgICAgICAgICAgICAgYmFkZ2UueCA9IHRoaXMueCArIHRoaXMud2lkdGggLyAyIC0gYmFkZ2Uud2lkdGggLyAyICsgb3B0cy5vZmZzZXRMZWZ0XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAgICAgICAgICBiYWRnZS54ID0gdGhpcy54ICsgdGhpcy53aWR0aCAtIGJhZGdlLndpZHRoIC8gMiArIG9wdHMub2Zmc2V0TGVmdFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzd2l0Y2ggKG9wdHMudmVydGljYWxBbGlnbikge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICAgICAgICAgIGJhZGdlLnkgPSB0aGlzLnkgLSBiYWRnZS5oZWlnaHQgLyAyICsgb3B0cy5vZmZzZXRUb3BcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlICdtaWRkbGUnOlxuICAgICAgICAgICAgICAgICAgICBiYWRnZS55ID0gdGhpcy55ICsgdGhpcy5oZWlnaHQgLyAyIC0gYmFkZ2UuaGVpZ2h0IC8gMiArIG9wdHMub2Zmc2V0VG9wXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICAgICAgICAgICAgYmFkZ2UueSA9IHRoaXMueSArIHRoaXMuaGVpZ2h0IC0gYmFkZ2UuaGVpZ2h0IC8gMiArIG9wdHMub2Zmc2V0VG9wXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQoYmFkZ2UpXG5cbiAgICAgICAgICAgIHRoaXMuYmFkZ2UgPSBiYWRnZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gc2V0IHBvc2l0aW9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5wb3NpdGlvbi5zZXQodGhpcy5vcHRzLngsIHRoaXMub3B0cy55KVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIGJ1dHRvbi4gQ2FuIGJlIHVzZWQgYWZ0ZXIgcmVzaXppbmcuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtCdXR0b259IEEgcmVmZXJlbmNlIHRvIHRoZSBidXR0b24gZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcblxuICAgICAgICAvLyBDbGVhciBjb250ZW50XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5yZW1vdmVDaGlsZCh0aGlzLmNvbnRlbnQpXG4gICAgICAgIHRoaXMuY29udGVudCA9IG5ldyBQSVhJLkNvbnRhaW5lcigpXG4gICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5jb250ZW50KVxuXG4gICAgICAgIC8vIFNldCB0aGUgaWNvblxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGxldCBpY29uID0gbnVsbFxuXG4gICAgICAgIGlmICghdGhpcy5hY3RpdmUgJiYgdGhpcy5pY29uSW5hY3RpdmUpIHtcbiAgICAgICAgICAgIGljb24gPSB0aGlzLmljb25JbmFjdGl2ZVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYWN0aXZlICYmIHRoaXMuaWNvbkFjdGl2ZSkge1xuICAgICAgICAgICAgaWNvbiA9IHRoaXMuaWNvbkFjdGl2ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHRoZSB0ZXh0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMudGV4dCkge1xuICAgICAgICAgICAgdGhpcy50ZXh0LnBvc2l0aW9uLnNldCgwLCAwKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2lkdGggYW5kIEhlaWdodFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGxldCB3aWR0aCA9IDBcbiAgICAgICAgaWYgKGljb24gJiYgdGhpcy50ZXh0KSB7XG4gICAgICAgICAgICB3aWR0aCA9IGljb24ud2lkdGggKyB0aGlzLnRleHQud2lkdGggKyAzICogdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgfSBlbHNlIGlmIChpY29uKSB7XG4gICAgICAgICAgICB3aWR0aCA9IGljb24ud2lkdGggKyAyICogdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRleHQpIHtcbiAgICAgICAgICAgIHdpZHRoID0gdGhpcy50ZXh0LndpZHRoICsgMiAqIHRoaXMub3B0cy5wYWRkaW5nXG4gICAgICAgIH1cblxuICAgICAgICBpZiAod2lkdGggPCB0aGlzLm9wdHMubWluV2lkdGgpIHtcbiAgICAgICAgICAgIHdpZHRoID0gdGhpcy5vcHRzLm1pbldpZHRoXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaGVpZ2h0ID0gMFxuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgaGVpZ2h0ID0gaWNvbi5oZWlnaHQgKyAyICogdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRleHQpIHtcbiAgICAgICAgICAgIGhlaWdodCA9IHRoaXMudGV4dC5oZWlnaHQgKyAyICogdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoZWlnaHQgPCB0aGlzLm9wdHMubWluSGVpZ2h0KSB7XG4gICAgICAgICAgICBoZWlnaHQgPSB0aGlzLm9wdHMubWluSGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl93aWR0aCA9IHdpZHRoXG4gICAgICAgIHRoaXMuX2hlaWdodCA9IGhlaWdodFxuXG4gICAgICAgIC8vIFBvc2l0aW9uIGljb24gYW5kIHRleHRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAoaWNvbiAmJiB0aGlzLnRleHQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuaWNvblBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICAgICAgICAgICAgaWNvbi54ID0gdGhpcy50ZXh0LndpZHRoICsgdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0LnggPSBpY29uLndpZHRoICsgdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY29udGVudC5hZGRDaGlsZChpY29uLCB0aGlzLnRleHQpXG4gICAgICAgIH0gZWxzZSBpZiAoaWNvbikge1xuICAgICAgICAgICAgdGhpcy5jb250ZW50LmFkZENoaWxkKGljb24pXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRlbnQuYWRkQ2hpbGQodGhpcy50ZXh0KVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sYXlvdXRJbm5lckNvbnRlbnQoKVxuICAgICAgICB0aGlzLmxheW91dENvbnRlbnQoKVxuXG4gICAgICAgIHRoaXMuaWNvbiA9IGljb25cblxuICAgICAgICAvLyBkcmF3XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5kcmF3KClcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHBvc2l0aW9ucyBvZiB0aGUgY29udGVudCBjaGlsZHJlbiAoaWNvbiBhbmQvb3IgdGV4dCkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge0J1dHRvbn0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgbGF5b3V0SW5uZXJDb250ZW50KCkge1xuXG4gICAgICAgIGZvciAobGV0IGNoaWxkIG9mIHRoaXMuY29udGVudC5jaGlsZHJlbikge1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLm9wdHMudmVydGljYWxBbGlnbikge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnkgPSAwXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlkZGxlJzpcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQueSA9IHRoaXMuY29udGVudC5oZWlnaHQgLyAyIC0gY2hpbGQuaGVpZ2h0IC8gMlxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnkgPSB0aGlzLmNvbnRlbnQuaGVpZ2h0IC0gY2hpbGQuaGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHBvc2l0aW9uIG9mIHRoZSBjb250ZW50LlxuICAgICAqIFVzZXMgdGhlIG9wdGlvbiBrZXlzIFwiYWxpZ25cIiBhbmQgXCJ2ZXJ0aWNhbEFsaWduXCIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge0J1dHRvbn0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgbGF5b3V0Q29udGVudCgpIHtcblxuICAgICAgICBzd2l0Y2ggKHRoaXMub3B0cy5hbGlnbikge1xuICAgICAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50LnggPSB0aGlzLm9wdHMucGFkZGluZ1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC54ID0gKCh0aGlzLl93aWR0aCAtIHRoaXMuY29udGVudC53aWR0aCkgLyAyKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50LnggPSB0aGlzLl93aWR0aCAtIHRoaXMub3B0cy5wYWRkaW5nIC0gdGhpcy5jb250ZW50LndpZHRoXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAodGhpcy5vcHRzLnZlcnRpY2FsQWxpZ24pIHtcbiAgICAgICAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50LnkgPSB0aGlzLm9wdHMucGFkZGluZ1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdtaWRkbGUnOlxuICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC55ID0gKHRoaXMuX2hlaWdodCAtIHRoaXMuY29udGVudC5oZWlnaHQpIC8gMlxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC55ID0gdGhpcy5faGVpZ2h0IC0gdGhpcy5vcHRzLnBhZGRpbmcgLSB0aGlzLmNvbnRlbnQuaGVpZ2h0XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIGNhbnZhcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7QnV0dG9ufSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBkcmF3KCkge1xuXG4gICAgICAgIHRoaXMuYnV0dG9uLmNsZWFyKClcbiAgICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZUFjdGl2ZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlLCB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlQWxwaGEpXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGxBY3RpdmUsIHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlLCB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEpXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGwsIHRoaXMub3B0cy5maWxsQWxwaGEpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idXR0b24uZHJhd1JvdW5kZWRSZWN0KDAsIDAsIHRoaXMuX3dpZHRoLCB0aGlzLl9oZWlnaHQsIHRoaXMub3B0cy5yYWRpdXMpXG4gICAgICAgIHRoaXMuYnV0dG9uLmVuZEZpbGwoKVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBhY3RpdmUgc3RhdGUuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBhY3RpdmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVcbiAgICB9XG4gICAgc2V0IGFjdGl2ZSh2YWx1ZSkge1xuXG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IHZhbHVlXG5cbiAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMudGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dC5zdHlsZSA9IHRoaXMub3B0cy50ZXh0U3R5bGVBY3RpdmVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQuc3R5bGUgPSB0aGlzLm9wdHMudGV4dFN0eWxlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxheW91dCgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBkaXNhYmxlZCBzdGF0ZS4gV2hlbiBkaXNhYmxlZCwgdGhlIGJ1dHRvbiBjYW5ub3QgYmUgY2xpY2tlZC5cbiAgICAgKlxuICAgICAqIEBtZW1iZXIge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IGRpc2FibGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWRcbiAgICB9XG4gICAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG5cbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSB2YWx1ZVxuXG4gICAgICAgIGlmICh0aGlzLl9kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5idXR0b24uaW50ZXJhY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5idXR0b24uYnV0dG9uTW9kZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5hbHBoYSA9IC41XG4gICAgICAgICAgICBpZiAodGhpcy5pY29uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pY29uLmFscGhhID0gLjVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHQuYWxwaGEgPSAuNVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5idXR0b24uaW50ZXJhY3RpdmUgPSB0cnVlXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbi5idXR0b25Nb2RlID0gdHJ1ZVxuICAgICAgICAgICAgdGhpcy5idXR0b24uYWxwaGEgPSAxXG4gICAgICAgICAgICBpZiAodGhpcy5pY29uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pY29uLmFscGhhID0gMVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMudGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dC5hbHBoYSA9IDFcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBidXR0b24gKHNldHMgaGlzIGFscGhhIHZhbHVlcyB0byAxKS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbn0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2hvdygpIHtcblxuICAgICAgICB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5zdHJva2VBY3RpdmVBbHBoYSA9IDFcbiAgICAgICAgdGhpcy5vcHRzLmZpbGxBbHBoYSA9IDFcbiAgICAgICAgdGhpcy5vcHRzLmZpbGxBY3RpdmVBbHBoYSA9IDFcblxuICAgICAgICB0aGlzLmxheW91dCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlcyB0aGUgYnV0dG9uIChzZXRzIGhpcyBhbHBoYSB2YWx1ZXMgdG8gMCkuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtCdXR0b259IEEgcmVmZXJlbmNlIHRvIHRoZSBidXR0b24gZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGhpZGUoKSB7XG5cbiAgICAgICAgdGhpcy5vcHRzLnN0cm9rZUFscGhhID0gMFxuICAgICAgICB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlQWxwaGEgPSAwXG4gICAgICAgIHRoaXMub3B0cy5maWxsQWxwaGEgPSAwXG4gICAgICAgIHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEgPSAwXG5cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgYW4gaWNvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xQSVhJLkRpc3BsYXlPYmplY3R9IGljb24gLSBUaGUgaWNvbiB0byBsb2FkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjb2xvciAtIFRoZSBjb2xvciBvZiB0aGUgaWNvbiAoaWYgbm90IGFuIFBJWEkuRGlzcGxheU9iamVjdCkuXG4gICAgICogQHJldHVybiB7UElYSS5EaXNwbGF5T2JqZWN0fSBSZXR1cm4gdGhlIGljb24gYXMgYW4gUElYSS5EaXNwbGF5T2JqZWN0LlxuICAgICAqL1xuICAgIGxvYWRJY29uKGljb24sIGNvbG9yKSB7XG5cbiAgICAgICAgbGV0IGRpc3BsYXlPYmplY3QgPSBudWxsXG5cbiAgICAgICAgaWYgKGljb24gaW5zdGFuY2VvZiBQSVhJLkRpc3BsYXlPYmplY3QpIHtcbiAgICAgICAgICAgIGRpc3BsYXlPYmplY3QgPSBpY29uXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgc2l6ZSA9IDE3XG4gICAgICAgICAgICBpZiAodGhpcy50ZXh0KSB7XG4gICAgICAgICAgICAgICAgc2l6ZSA9IHRoaXMudGV4dC5oZWlnaHRcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRzLm1pbkhlaWdodCkge1xuICAgICAgICAgICAgICAgIHNpemUgPSB0aGlzLm9wdHMubWluSGVpZ2h0IC0gKDIgKiB0aGlzLm9wdHMucGFkZGluZylcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdXJsID0gQnV0dG9uLmljb25Jc1VybChpY29uKSA/IGljb24gOiBgLi4vLi4vYXNzZXRzL2ljb25zL3BuZy9mbGF0LyR7aWNvbn0ucG5nYFxuICAgICAgICAgICAgY29uc3QgaWNvblRleHR1cmUgPSBQSVhJLlRleHR1cmUuZnJvbUltYWdlKHVybCwgdHJ1ZSlcblxuICAgICAgICAgICAgY29uc3Qgc3ByaXRlID0gbmV3IFBJWEkuU3ByaXRlKGljb25UZXh0dXJlKVxuICAgICAgICAgICAgc3ByaXRlLnRpbnQgPSBjb2xvclxuICAgICAgICAgICAgc3ByaXRlLndpZHRoID0gc2l6ZVxuICAgICAgICAgICAgc3ByaXRlLmhlaWdodCA9IHNpemVcblxuICAgICAgICAgICAgZGlzcGxheU9iamVjdCA9IHNwcml0ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRpc3BsYXlPYmplY3RcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiBhbiBpY29uIHN0cmluZyBpcyBhbiB1cmwuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVGhlIHVybCB0byB0ZXN0LlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIHVybCBpcyBhbiB1cmwgdG8gYW4gaW1hZ2UuXG4gICAgICovXG4gICAgc3RhdGljIGljb25Jc1VybCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIC9cXC4ocG5nfHN2Z3xnaWZ8anBnfGpwZWd8dGlmfHRpZmYpJC9pLnRlc3QodXJsKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgb3Igc2V0cyB0aGUgY29sb3Igb2YgdGhlIGN1cnJlbnQgaWNvbiAobm8gbWF0dGVyIGhvdyB0aGUgc3RhdHVzIGlzKS4gQ2hhbmdpbmcgdGhlIGNvbG9yLCBjaGFuZ2VzXG4gICAgICogdGhlIHRpbnQgcHJvcGVydHkgb2YgdGhlIGljb24gc3ByaXRlLlxuICAgICAqXG4gICAgICogQG1lbWJlciB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBpY29uQ29sb3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmljb24gPyB0aGlzLmljb24udGludCA6IG51bGxcbiAgICB9XG4gICAgc2V0IGljb25Db2xvcih2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5pY29uKSB7XG4gICAgICAgICAgICB0aGlzLmljb24udGludCA9IHZhbHVlXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCBCdXR0b24gZnJvbSAnLi9idXR0b24uanMnXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIEJ1dHRvbkdyb3VwLlxuICogXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBidXR0b24gZ3JvdXBcbiAqIGNvbnN0IGJ1dHRvbkdyb3VwID0gbmV3IEJ1dHRvbkdyb3VwKHtcbiAqICAgICBidXR0b25zOiBbXG4gKiAgICAgICAgIHtsYWJlbDogJ0J1dHRvbiAxJywgYWN0aW9uOiBldmVudCA9PiBjb25zb2xlLmxvZyhldmVudCl9LFxuICogICAgICAgICB7bGFiZWw6ICdCdXR0b24gMicsIGFjdGlvbjogZXZlbnQgPT4gY29uc29sZS5sb2coZXZlbnQpfSxcbiAqICAgICAgICAge2xhYmVsOiAnQnV0dG9uIDMnLCBhY3Rpb246IGV2ZW50ID0+IGNvbnNvbGUubG9nKGV2ZW50KX1cbiAqICAgICBdLFxuICogICAgIG1pbldpZHRoOiAxMDBcbiAqIH0pXG4gKlxuICogLy8gQWRkIHRoZSBidXR0b24gZ3JvdXAgdG8gYSBEaXNwbGF5T2JqZWN0XG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQoYnV0dG9uR3JvdXApXG4gKlxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBQSVhJLkdyYXBoaWNzXG4gKiBAc2VlIHtAbGluayBodHRwOi8vcGl4aWpzLmRvd25sb2FkL2Rldi9kb2NzL1BJWEkuR3JhcGhpY3MuaHRtbHxQSVhJLkdyYXBoaWNzfVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cuaXdtLXR1ZWJpbmdlbi5kZS9pd21icm93c2VyL2xpYi9waXhpL2J1dHRvbmdyb3VwLmh0bWx8RG9jVGVzdH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnV0dG9uR3JvdXAgZXh0ZW5kcyBQSVhJLkdyYXBoaWNzIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBCdXR0b25Hcm91cC5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBidXR0b24gZ3JvdXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmlkPWF1dG8gZ2VuZXJhdGVkXSAtIFRoZSBpZCBvZiB0aGUgYnV0dG9uIGdyb3VwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy54PTBdIC0gVGhlIHggcG9zaXRpb24gb2YgdGhlIGJ1dHRvbiBncm91cC4gQ2FuIGJlIGFsc28gc2V0IGFmdGVyIGNyZWF0aW9uIHdpdGggYnV0dG9uR3JvdXAueCA9IDAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnk9MF0gLSBUaGUgeSBwb3NpdGlvbiBvZiB0aGUgYnV0dG9uIGdyb3VwLiBDYW4gYmUgYWxzbyBzZXQgYWZ0ZXIgY3JlYXRpb24gd2l0aCBidXR0b25Hcm91cC55ID0gMC5cbiAgICAgKiBAcGFyYW0ge29iamVjdFtdfSBbb3B0cy5idXR0b25zPVtdXSAtIEFuIGFycmF5IG9mIHRoZSBidXR0b25zIG9mIHRoZSBidXR0b24gZ3JvdXAuIE9uZSBpdGVtIG9mIHRoZSBhcnJheSAob25lIG9iamVjdClcbiAgICAgKiAgICAgY2FuIGhhdmUgZXhhY3RseSB0aGUgc2FtZSBwcm9wZXJ0aWVzIGFzIGFuIEJ1dHRvbiBvYmplY3Qgd2hlbiBpbnN0YW50aWF0aW5nIGEgQnV0dG9uLiBJZiBhIHByb3BlcnR5IG9mIHRoZSBidXR0b24gZ3JvdXBcbiAgICAgKiAgICAgY29uZmxpY3RzIHdpdGggYSBwcm9wZXJ0eSBvZiBhIGJ1dHRvbiBvYmplY3QsIHRoZSB2YWx1ZSBmcm9tIHRoZSBidXR0b24gb2JqZWN0IHdpbGwgYmUgdXNlZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xUaGVtZT19IFtvcHRzLnRoZW1lPWRhcmtdIC0gVGhlIHRoZW1lIHRvIHVzZSBmb3IgdGhpcyBidXR0b24gZ3JvdXAuIFBvc3NpYmxlIHZhbHVlcyBhcmUgZGFyaywgbGlnaHQsIHJlZFxuICAgICAqICAgICBvciBhIFRoZW1lIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluV2lkdGg9NDRdIC0gQnV0dG9uOiBUaGUgbWluaW11bSB3aWR0aCBvZiBvbmUgYnV0dG9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5taW5IZWlnaHQ9NDRdIC0gQnV0dG9uOiBUaGUgbWluaW11bSBoZWlnaHQgb2Ygb25lIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMucGFkZGluZz1UaGVtZS5wYWRkaW5nXSAtIEJ1dHRvbjogVGhlIGlubmVyIHNwYWNpbmcgKGRpc3RhbmNlIGZyb20gaWNvbiBhbmQvb3IgbGFiZWwpIHRoZSB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5tYXJnaW49VGhlbWUubWFyZ2luXSAtIFRoZSBvdXRlciBzcGFjaW5nIChkaXN0YW5jZSBmcm9tIG9uZSBidXR0b24gdG8gdGhlIHByZXZpb3VzL25leHQgYnV0dG9uKS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuaWNvblBvc2l0aW9uPWxlZnRdIC0gQnV0dG9uOiBUaGUgcG9zaXRpb24gb2YgdGhlIGljb24gaW4gcmVsYXRpb24gdG8gdGhlIGxhYmVsLiBDYW4gYmUgbGVmdCBvciByaWdodC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaWNvbkNvbG9yPVRoZW1lLmljb25Db2xvcl0gLSBCdXR0b246IFRoZSBjb2xvciBvZiB0aGUgaWNvbiAoc2V0IGJ5IHRoZSB0aW50IHByb3BlcnR5KSBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaWNvbkNvbG9yQWN0aXZlPVRoZW1lLmljb25Db2xvckFjdGl2ZV0gLSBCdXR0b246IFRoZSBjb2xvciBvZiB0aGUgaWNvbiB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbD1UaGVtZS5maWxsXSAtIEJ1dHRvbjogVGhlIGNvbG9yIG9mIHRoZSBidXR0b24gYmFja2dyb3VuZCBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFscGhhPVRoZW1lLmZpbGxBbHBoYV0gLSBCdXR0b246IFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFjdGl2ZT1UaGVtZS5maWxsQWN0aXZlXSAtIEJ1dHRvbjogVGhlIGNvbG9yIG9mIHRoZSBidXR0b24gYmFja2dyb3VuZCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFjdGl2ZUFscGhhPVRoZW1lLmZpbGxBY3RpdmVBbHBoYV0gLSBCdXR0b246IFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlPVRoZW1lLnN0cm9rZV0gLSBCdXR0b246IFRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIGFzIGEgaGV4IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VXaWR0aD1UaGVtZS5zdHJva2VXaWR0aF0gLSBCdXR0b246IFRoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGluIHBpeGVsLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBbHBoYT1UaGVtZS5zdHJva2VBbHBoYV0gLSBCdXR0b246IFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmU9VGhlbWUuc3Ryb2tlQWN0aXZlXSAtIEJ1dHRvbjogVGhlIGNvbG9yIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZUFjdGl2ZVdpZHRoPVRoZW1lLnN0cm9rZUFjdGl2ZVdpZHRoXSAtIEJ1dHRvbjogVGhlIHdpZHRoIG9mIHRoZSBib3JkZXIgaW4gcGl4ZWwgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZUFjdGl2ZUFscGhhPVRoZW1lLnN0cm9rZUFjdGl2ZUFscGhhXSAtIEJ1dHRvbjogVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnRleHRTdHlsZT1UaGVtZS50ZXh0U3R5bGVdIC0gQnV0dG9uOiBBIHRleHRzdHlsZSBvYmplY3QgZm9yIHRoZSBzdHlsaW5nIG9mIHRoZSBsYWJlbC4gU2VlIFBJWEkuVGV4dFN0eWxlXG4gICAgICogICAgIGZvciBwb3NzaWJsZSBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50ZXh0U3R5bGVBY3RpdmU9VGhlbWUudGV4dFN0eWxlQWN0aXZlXSAtIEJ1dHRvbjogQSB0ZXh0c3R5bGUgb2JqZWN0IGZvciB0aGUgc3R5bGluZyBvZiB0aGUgbGFiZWwgd2hlbiB0aGVcbiAgICAgKiAgICAgYnV0dG9uIGlzIGFjdGl2YXRlZC4gU2VlIFBJWEkuVGV4dFN0eWxlIGZvciBwb3NzaWJsZSBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5zdHlsZT1kZWZhdWx0XSAtIEEgc2hvcnRjdXQgZm9yIHN0eWxpbmcgb3B0aW9ucy4gUG9zc2libGUgdmFsdWVzIGFyZSBkZWZhdWx0LCBsaW5rLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5yYWRpdXM9VGhlbWUucmFkaXVzXSAtIEJ1dHRvbjogVGhlIHJhZGl1cyBvZiB0aGUgZm91ciBjb3JuZXJzIG9mIHRoZSBidXR0b24gKHdoaWNoIGlzIGEgcm91bmRlZCByZWN0YW5nbGUpLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZGlzYWJsZWQ9ZmFsc2VdIC0gSXMgdGhlIGJ1dHRvbiBncm91cCBkaXNhYmxlZD8gV2hlbiBkaXNhYmxlZCwgdGhlIGJ1dHRvbiBncm91cCBoYXMgYSBsb3dlciBhbHBoYSB2YWx1ZVxuICAgICAqICAgICBhbmQgY2Fubm90IGJlIGNsaWNrZWQgKGludGVyYWN0aXZlIG9mIGV2ZXJ5IGJ1dHRvbiBpcyBzZXQgdG8gZmFsc2UpLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy50eXBlPWRlZmF1bHRdIC0gVGhlIHR5cGUgb2YgdGhlIGJ1dHRvbiBncm91cC4gQ2FuIGJlIGRlZmF1bHQsIGNoZWNrYm94IG9yIHJhZGlvLiBXaGVuIHRoZSB0eXBlIGlzXG4gICAgICogICAgIGNoZWNrYm94LCB0aGUgYWN0aXZlIHN0YXRlIGlzIHRvZ2dsZWQgZm9yIGVhY2ggYnV0dG9uIGF1dG9tYXRpY2FsbHkuIFdoZW4gdGhlIHR5cGUgaXMgcmFkaW8sIG9ubHkgb25lIGJ1dHRvbiBjYW5cbiAgICAgKiAgICAgYmUgYWN0aXZhdGVkIGF0IHRoZSBzYW1lIHRpbWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm9yaWVudGF0aW9uPWhvcml6b250YWxdIC0gVGhlIG9yaWVudGF0aW9uIG9mIHRoZSBidXR0b24gZ3JvdXAuIENhbiBiZSBob3Jpem9udGFsIG9yIHZlcnRpY2FsLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5hbGlnbj1jZW50ZXJdIC0gQnV0dG9uOiBUaGUgaG9yaXpvbnRhbCBwb3NpdGlvbiBvZiB0aGUgbGFiZWwgYW5kIHRoZSBpY29uLiBQb3NzaWJsZSB2YWx1ZXMgYXJlXG4gICAgICogICAgIGxlZnQsIGNlbnRlciBhbmQgcmlnaHQuIE9ubHkgYWZmZWN0cyB0aGUgc3R5bGUgd2hlbiB0aGUgbWluV2lkdGggaXMgYmlnZ2VyIHRoYW4gdGhlIHdpZHRoIG9mIHRoZSBpY29uIGFuZCBsYWJlbC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudmVydGljYWxBbGlnbj1taWRkbGVdIC0gQnV0dG9uOiBUaGUgdmVydGljYWwgcG9zaXRpb24gb2YgdGhlIGxhYmVsIGFuZCB0aGUgaWNvbi4gUG9zc2libGUgdmFsdWVzIGFyZVxuICAgICAqICAgICB0b3AsIG1pZGRsZSBhbmQgYm90dG9tLiBPbmx5IGFmZmVjdHMgdGhlIHN0eWxlIHdoZW4gdGhlIG1pbkhlaWdodCBpcyBiaWdnZXIgdGhhbiB0aGUgaGVpZ2h0IG9mIHRoZSBpY29uIGFuZCBsYWJlbC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnZpc2libGU9dHJ1ZV0gLSBJcyB0aGUgYnV0dG9uIGdyb3VwIGluaXRpYWxseSB2aXNpYmxlIChwcm9wZXJ0eSB2aXNpYmxlKT9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcblxuICAgICAgICBzdXBlcigpXG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcbiAgICAgICAgdGhpcy50aGVtZSA9IHRoZW1lXG5cbiAgICAgICAgdGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgaWQ6IFBJWEkudXRpbHMudWlkKCksXG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtdLFxuICAgICAgICAgICAgbWluV2lkdGg6IDQ0LFxuICAgICAgICAgICAgbWluSGVpZ2h0OiA0NCxcbiAgICAgICAgICAgIHBhZGRpbmc6IHRoZW1lLnBhZGRpbmcsXG4gICAgICAgICAgICBtYXJnaW46IHRoZW1lLm1hcmdpbixcbiAgICAgICAgICAgIGljb25Qb3NpdGlvbjogJ2xlZnQnLCAgICAgICAgICAgICAvLyBsZWZ0LCByaWdodFxuICAgICAgICAgICAgaWNvbkNvbG9yOiB0aGVtZS5pY29uQ29sb3IsXG4gICAgICAgICAgICBpY29uQ29sb3JBY3RpdmU6IHRoZW1lLmljb25Db2xvckFjdGl2ZSxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIGZpbGxBY3RpdmU6IHRoZW1lLmZpbGxBY3RpdmUsXG4gICAgICAgICAgICBmaWxsQWN0aXZlQWxwaGE6IHRoZW1lLmZpbGxBY3RpdmVBbHBoYSxcbiAgICAgICAgICAgIHN0cm9rZTogdGhlbWUuc3Ryb2tlLFxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoZW1lLnN0cm9rZVdpZHRoLFxuICAgICAgICAgICAgc3Ryb2tlQWxwaGE6IHRoZW1lLnN0cm9rZUFscGhhLFxuICAgICAgICAgICAgc3Ryb2tlQWN0aXZlOiB0aGVtZS5zdHJva2VBY3RpdmUsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVXaWR0aDogdGhlbWUuc3Ryb2tlQWN0aXZlV2lkdGgsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmVBbHBoYTogdGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGEsXG4gICAgICAgICAgICB0ZXh0U3R5bGU6IHRoZW1lLnRleHRTdHlsZSxcbiAgICAgICAgICAgIHRleHRTdHlsZUFjdGl2ZTogdGhlbWUudGV4dFN0eWxlQWN0aXZlLFxuICAgICAgICAgICAgc3R5bGU6ICdkZWZhdWx0JyxcbiAgICAgICAgICAgIHJhZGl1czogdGhlbWUucmFkaXVzLFxuICAgICAgICAgICAgZGlzYWJsZWQ6IG51bGwsXG4gICAgICAgICAgICB0eXBlOiAnZGVmYXVsdCcsICAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQsIGNoZWNrYm94LCByYWRpb1xuICAgICAgICAgICAgb3JpZW50YXRpb246ICdob3Jpem9udGFsJyxcbiAgICAgICAgICAgIGFsaWduOiAnY2VudGVyJywgICAgICAgICAgICAgICAgICAgLy8gbGVmdCwgY2VudGVyLCByaWdodFxuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsICAgICAgICAgICAvLyB0b3AsIG1pZGRsZSwgYm90dG9tXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5idXR0b25zID0gW11cblxuICAgICAgICB0aGlzLl9kaXNhYmxlZCA9IG51bGxcbiAgICAgICAgXG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHRoaXMub3B0cy52aXNpYmxlXG5cbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNldHVwKClcblxuICAgICAgICAvLyBsYXlvdXRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmxheW91dCgpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgY2hpbGRyZW4gYW5kIGluc3RhbnRpYXRlcyBldmVyeXRoaW5nLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7QnV0dG9uR3JvdXB9IEEgcmVmZXJlbmNlIHRvIHRoZSBidXR0b24gZ3JvdXAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldHVwKCkge1xuXG4gICAgICAgIC8vIEJ1dHRvbnNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBsZXQgcG9zaXRpb24gPSAwXG5cbiAgICAgICAgZm9yIChsZXQgaXQgb2YgdGhpcy5vcHRzLmJ1dHRvbnMpIHtcblxuICAgICAgICAgICAgZGVsZXRlIGl0LnhcbiAgICAgICAgICAgIGRlbGV0ZSBpdC55XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICAgICAgICAgIGl0LnggPSBwb3NpdGlvblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdC55ID0gcG9zaXRpb25cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXQudGhlbWUgPSBpdC50aGVtZSB8fCB0aGlzLm9wdHMudGhlbWVcbiAgICAgICAgICAgIGl0Lm1pbldpZHRoID0gaXQubWluV2lkdGggfHwgdGhpcy5vcHRzLm1pbldpZHRoXG4gICAgICAgICAgICBpdC5taW5IZWlnaHQgPSBpdC5taW5IZWlnaHQgfHwgdGhpcy5vcHRzLm1pbkhlaWdodFxuICAgICAgICAgICAgaXQucGFkZGluZyA9IGl0LnBhZGRpbmcgfHwgdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIGl0Lmljb25Qb3NpdGlvbiA9IGl0Lmljb25Qb3NpdGlvbiB8fCB0aGlzLm9wdHMuaWNvblBvc2l0aW9uXG4gICAgICAgICAgICBpdC5pY29uQ29sb3IgPSBpdC5pY29uQ29sb3IgfHwgdGhpcy5vcHRzLmljb25Db2xvclxuICAgICAgICAgICAgaXQuaWNvbkNvbG9yQWN0aXZlID0gaXQuaWNvbkNvbG9yQWN0aXZlIHx8IHRoaXMub3B0cy5pY29uQ29sb3JBY3RpdmVcbiAgICAgICAgICAgIGl0LmZpbGwgPSBpdC5maWxsIHx8IHRoaXMub3B0cy5maWxsXG4gICAgICAgICAgICBpdC5maWxsQWxwaGEgPSBpdC5maWxsQWxwaGEgfHwgdGhpcy5vcHRzLmZpbGxBbHBoYVxuICAgICAgICAgICAgaXQuZmlsbEFjdGl2ZSA9IGl0LmZpbGxBY3RpdmUgfHwgdGhpcy5vcHRzLmZpbGxBY3RpdmVcbiAgICAgICAgICAgIGl0LmZpbGxBY3RpdmVBbHBoYSA9IGl0LmZpbGxBY3RpdmVBbHBoYSB8fCB0aGlzLm9wdHMuZmlsbEFjdGl2ZUFscGhhXG4gICAgICAgICAgICBpdC5zdHJva2UgPSBpdC5zdHJva2UgfHwgdGhpcy5vcHRzLnN0cm9rZVxuICAgICAgICAgICAgaXQuc3Ryb2tlV2lkdGggPSBpdC5zdHJva2VXaWR0aCAhPSBudWxsID8gaXQuc3Ryb2tlV2lkdGggOiB0aGlzLm9wdHMuc3Ryb2tlV2lkdGhcbiAgICAgICAgICAgIGl0LnN0cm9rZUFscGhhID0gaXQuc3Ryb2tlQWxwaGEgIT0gbnVsbCA/IGl0LnN0cm9rZUFscGhhIDogdGhpcy5vcHRzLnN0cm9rZUFscGhhXG4gICAgICAgICAgICBpdC5zdHJva2VBY3RpdmUgPSBpdC5zdHJva2VBY3RpdmUgfHwgdGhpcy5vcHRzLnN0cm9rZUFjdGl2ZVxuICAgICAgICAgICAgaXQuc3Ryb2tlQWN0aXZlV2lkdGggPSBpdC5zdHJva2VBY3RpdmVXaWR0aCAhPSBudWxsID8gaXQuc3Ryb2tlQWN0aXZlV2lkdGggOiB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlV2lkdGhcbiAgICAgICAgICAgIGl0LnN0cm9rZUFjdGl2ZUFscGhhID0gaXQuc3Ryb2tlQWN0aXZlQWxwaGEgIT0gbnVsbCA/IGl0LnN0cm9rZUFjdGl2ZUFscGhhIDogdGhpcy5vcHRzLnN0cm9rZUFjdGl2ZUFscGhhXG4gICAgICAgICAgICBpdC50ZXh0U3R5bGUgPSBpdC50ZXh0U3R5bGUgfHwgdGhpcy5vcHRzLnRleHRTdHlsZVxuICAgICAgICAgICAgaXQudGV4dFN0eWxlQWN0aXZlID0gaXQudGV4dFN0eWxlQWN0aXZlIHx8IHRoaXMub3B0cy50ZXh0U3R5bGVBY3RpdmVcbiAgICAgICAgICAgIGl0LnN0eWxlID0gaXQuc3R5bGUgfHwgdGhpcy5vcHRzLnN0eWxlXG4gICAgICAgICAgICBpdC5yYWRpdXMgPSBpdC5yYWRpdXMgIT0gbnVsbCA/IGl0LnJhZGl1cyA6IHRoaXMub3B0cy5yYWRpdXNcbiAgICAgICAgICAgIGlmICghaXQudHlwZSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5vcHRzLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnY2hlY2tib3gnOlxuICAgICAgICAgICAgICAgICAgICAgICAgaXQudHlwZSA9IHRoaXMub3B0cy50eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgaXQudHlwZSA9ICdkZWZhdWx0J1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvL2l0LnR5cGUgPSBpdC50eXBlIHx8IHRoaXMub3B0cy50eXBlIHx8ICdkZWZhdWx0J1xuICAgICAgICAgICAgaXQuYWxpZ24gPSBpdC5hbGlnbiB8fCB0aGlzLm9wdHMuYWxpZ25cbiAgICAgICAgICAgIGl0LnZlcnRpY2FsQWxpZ24gPSBpdC52ZXJ0aWNhbEFsaWduIHx8IHRoaXMub3B0cy52ZXJ0aWNhbEFsaWduXG4gICAgICAgICAgICBpdC5hZnRlckFjdGlvbiA9IChldmVudCwgYnV0dG9uKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy50eXBlID09PSAncmFkaW8nICYmIGJ1dHRvbi5vcHRzLnR5cGUgPT09ICdkZWZhdWx0Jykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1dHRvbnMuZm9yRWFjaChpdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXQub3B0cy50eXBlID09PSAnZGVmYXVsdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdC5hY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChidXR0b24ub3B0cy50eXBlID09PSAnZGVmYXVsdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5hY3RpdmUgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpdC50b29sdGlwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpdC50b29sdGlwID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBpdC50b29sdGlwID0ge2NvbnRlbnQ6IGl0LnRvb2x0aXAsIGNvbnRhaW5lcjogdGhpc31cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpdC50b29sdGlwID0gT2JqZWN0LmFzc2lnbih7fSwge2NvbnRhaW5lcjogdGhpc30sIGl0LnRvb2x0aXApXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbihpdClcblxuICAgICAgICAgICAgdGhpcy5hZGRDaGlsZChidXR0b24pXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbnMucHVzaChidXR0b24pXG5cbiAgICAgICAgICAgIHBvc2l0aW9uICs9ICh0aGlzLm9wdHMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/IGJ1dHRvbi53aWR0aCA6IGJ1dHRvbi5oZWlnaHQpICsgdGhpcy5vcHRzLm1hcmdpblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgICAgY29uc3QgbWF4V2lkdGggPSB0aGlzLmdldE1heEJ1dHRvbldpZHRoKClcblxuICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goaXQgPT4ge1xuICAgICAgICAgICAgICAgIGl0Lm9wdHMubWluV2lkdGggPSBtYXhXaWR0aFxuICAgICAgICAgICAgICAgIGl0LmxheW91dCgpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGlzYWJsZWRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmRpc2FibGVkICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzYWJsZWQgPSB0aGlzLm9wdHMuZGlzYWJsZWRcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNob3VsZCBiZSBjYWxsZWQgdG8gcmVmcmVzaCB0aGUgbGF5b3V0IG9mIHRoZSBidXR0b24gZ3JvdXAuIENhbiBiZSB1c2VkIGFmdGVyIHJlc2l6aW5nLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge0J1dHRvbkdyb3VwfSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIGdyb3VwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG4gICAgICAgIFxuICAgICAgICAvLyBzZXQgcG9zaXRpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnBvc2l0aW9uLnNldCh0aGlzLm9wdHMueCwgdGhpcy5vcHRzLnkpXG5cbiAgICAgICAgLy8gZHJhd1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuZHJhdygpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIGNhbnZhcy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge0J1dHRvbkdyb3VwfSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIGdyb3VwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBkcmF3KCkge1xuXG4gICAgICAgIGlmICh0aGlzLm9wdHMubWFyZ2luID09PSAwKSB7XG5cbiAgICAgICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKGl0ID0+IGl0LmhpZGUoKSlcblxuICAgICAgICAgICAgdGhpcy5jbGVhcigpXG4gICAgICAgICAgICB0aGlzLmxpbmVTdHlsZSh0aGlzLm9wdHMuc3Ryb2tlV2lkdGgsIHRoaXMub3B0cy5zdHJva2UsIHRoaXMub3B0cy5zdHJva2VBbHBoYSlcbiAgICAgICAgICAgIHRoaXMuYmVnaW5GaWxsKHRoaXMub3B0cy5maWxsLCB0aGlzLm9wdHMuZmlsbEFscGhhKVxuICAgICAgICAgICAgdGhpcy5kcmF3Um91bmRlZFJlY3QoMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQsIHRoaXMub3B0cy5yYWRpdXMpXG5cbiAgICAgICAgICAgIC8vIERyYXcgYm9yZGVyc1xuICAgICAgICAgICAgdGhpcy5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlLCB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEgLyAyKVxuXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbnMuZm9yRWFjaCgoaXQsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb3ZlVG8oaXQueCwgaXQueSlcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGluZVRvKGl0LngsIGl0LmhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGluZVRvKGl0LndpZHRoLCBpdC55KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMuZW5kRmlsbCgpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBHZXRzIG9yIHNldHMgdGhlIGRpc2FibGVkIHN0YXRlLiBXaGVuIGRpc2FibGVkLCBubyBidXR0b24gb2YgdGhlIGJ1dHRvbiBncm91cCBjYW4gYmUgY2xpY2tlZC5cbiAgICAgKiBcbiAgICAgKiBAbWVtYmVyIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBkaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkXG4gICAgfVxuXG4gICAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG5cbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSB2YWx1ZVxuXG4gICAgICAgIHRoaXMuYnV0dG9ucy5mb3JFYWNoKGl0ID0+IGl0LmRpc2FibGVkID0gdmFsdWUpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNlYXJjaGVzIGFsbCBidXR0b25zIG9mIHRoZSBidXR0b24gZ3JvdXAgYW5kIHJldHVybnMgdGhlIG1heGltdW0gd2lkdGggb2Ygb25lIGJ1dHRvbi5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1heGltdW0gd2l0aCBvZiBhIGJ1dHRvbiBvZiB0aGUgYnV0dG9uIGdyb3VwLlxuICAgICAqL1xuICAgIGdldE1heEJ1dHRvbldpZHRoKCkge1xuXG4gICAgICAgIGxldCB3aWR0aHMgPSB0aGlzLmJ1dHRvbnMubWFwKGl0ID0+IGl0LndpZHRoKVxuXG4gICAgICAgIHJldHVybiBNYXRoLm1heCguLi53aWR0aHMpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBidXR0b24gZ3JvdXAgKHNldHMgaGlzIGFscGhhIHZhbHVlIHRvIDEpLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge0J1dHRvbkdyb3VwfSBBIHJlZmVyZW5jZSB0byB0aGUgYnV0dG9uIGdyb3VwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzaG93KCkge1xuXG4gICAgICAgIHRoaXMuYWxwaGEgPSAxXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlcyB0aGUgYnV0dG9uIGdyb3VwIChzZXRzIGhpcyBhbHBoYSB2YWx1ZSB0byAwKS5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtCdXR0b25Hcm91cH0gQSByZWZlcmVuY2UgdG8gdGhlIGJ1dHRvbiBncm91cCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgaGlkZSgpIHtcblxuICAgICAgICB0aGlzLmFscGhhID0gMFxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxufVxuIiwiaW1wb3J0IEFic3RyYWN0UG9wdXAgZnJvbSAnLi9hYnN0cmFjdHBvcHVwLmpzJ1xuaW1wb3J0IEJ1dHRvbiBmcm9tICcuL2J1dHRvbi5qcydcbmltcG9ydCBCdXR0b25Hcm91cCBmcm9tICcuL2J1dHRvbmdyb3VwLmpzJ1xuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBJbnRlcmFjdGl2ZVBvcHVwLlxuICogVGhlIGNsYXNzIGlzIHVzZWQgZm9yIHZhcmlvdXMgb3RoZXIgUG9wdXAtbGlrZSBjbGFzc2VzXG4gKiBsaWtlIFBvcHVwLCBNZXNzYWdlLi4uXG4gKlxuICogQGNsYXNzXG4gKiBAYWJzdHJhY3RcbiAqIEBleHRlbmRzIEFic3RyYWN0UG9wdXBcbiAqL1xuZXhwb3J0IGNsYXNzIEludGVyYWN0aXZlUG9wdXAgZXh0ZW5kcyBBYnN0cmFjdFBvcHVwIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYW4gSW50ZXJhY3RpdmVQb3B1cCAob25seSBmb3IgaW50ZXJuYWwgdXNlKS5cbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0c10gLSBBbiBvcHRpb25zIG9iamVjdCB0byBzcGVjaWZ5IHRvIHN0eWxlIGFuZCBiZWhhdmlvdXIgb2YgdGhlIHBvcHVwLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuY2xvc2VPblBvcHVwPWZhbHNlXSAtIFNob3VsZCB0aGUgcG9wdXAgYmUgY2xvc2VkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIHRoZSBwb3B1cD9cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmNsb3NlQnV0dG9uPXRydWVdIC0gU2hvdWxkIGEgY2xvc2UgYnV0dG9uIGJlIGRpc3BsYXllZCBvbiB0aGUgdXBwZXIgcmlnaHQgY29ybmVyP1xuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cy5idXR0b25dIC0gQSBCdXR0b24gb2JqZWN0IHRvIGJlIGRpc3BsYXkgb24gdGhlIGxvd2VyIHJpZ2h0IGNvcm5lci5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHMuYnV0dG9uR3JvdXBdIC0gQSBCdXR0b25Hcm91cCBvYmplY3QgdG8gYmUgZGlzcGxheWVkIG9uIHRoZSBsb3dlciByaWdodCBjb3JuZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG5cbiAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgIGNsb3NlT25Qb3B1cDogZmFsc2UsXG4gICAgICAgICAgICBjbG9zZUJ1dHRvbjogdHJ1ZSxcbiAgICAgICAgICAgIGJ1dHRvbjogbnVsbCxcbiAgICAgICAgICAgIGJ1dHRvbkdyb3VwOiBudWxsXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgc3VwZXIob3B0cylcblxuICAgICAgICB0aGlzLl9jbG9zZUJ1dHRvbiA9IG51bGxcbiAgICAgICAgdGhpcy5fYnV0dG9ucyA9IG51bGxcblxuICAgICAgICAvLyBwYWRkaW5nXG4gICAgICAgIHRoaXMuc21hbGxQYWRkaW5nID0gdGhpcy5vcHRzLnBhZGRpbmcgLyAyXG5cbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNldHVwKClcblxuICAgICAgICAvLyBsYXlvdXRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmxheW91dCgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgZnJhbWV3b3JrIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7QWJzdHJhY3RQb3B1cH0gQSByZWZlcmVuY2UgdG8gdGhlIHBvcHVwIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHtcblxuICAgICAgICBzdXBlci5zZXR1cCgpXG5cbiAgICAgICAgLy8gaW50ZXJhY3Rpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLm9uKCdwb2ludGVydXAnLCBlID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuY2xvc2VPblBvcHVwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIC8vIGNsb3NlQnV0dG9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMub3B0cy5jbG9zZUJ1dHRvbikge1xuICAgICAgICAgICAgbGV0IGNsb3NlQnV0dG9uID0gUElYSS5TcHJpdGUuZnJvbUltYWdlKCcuLi8uLi9hc3NldHMvaWNvbnMvcG5nL2ZsYXQvY2xvc2UucG5nJywgdHJ1ZSlcbiAgICAgICAgICAgIGNsb3NlQnV0dG9uLndpZHRoID0gdGhpcy5oZWFkZXJTdHlsZS5mb250U2l6ZVxuICAgICAgICAgICAgY2xvc2VCdXR0b24uaGVpZ2h0ID0gY2xvc2VCdXR0b24ud2lkdGhcbiAgICAgICAgICAgIGNsb3NlQnV0dG9uLnRpbnQgPSB0aGlzLnRoZW1lLmNvbG9yMlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBuZWVkZWQsIGJlY2F1c2UgdGhlIGNsb3NlQnV0dG9uIGJlbG9uZ3MgdG8gdGhlIGNvbnRlbnQuIFRoZSBwb3B1cCBtdXN0IHJlc2l6ZSB3aXRoIHRoZSBjbG9zZUJ1dHRvbi5cbiAgICAgICAgICAgIGlmICh0aGlzLl9oZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBjbG9zZUJ1dHRvbi54ID0gdGhpcy5faGVhZGVyLndpZHRoICsgdGhpcy5pbm5lclBhZGRpbmdcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgICAgICAgICAgIGNsb3NlQnV0dG9uLnggPSB0aGlzLl9jb250ZW50LndpZHRoICsgdGhpcy5pbm5lclBhZGRpbmdcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2xvc2VCdXR0b24uaW50ZXJhY3RpdmUgPSB0cnVlXG4gICAgICAgICAgICBjbG9zZUJ1dHRvbi5idXR0b25Nb2RlID0gdHJ1ZVxuICAgICAgICAgICAgY2xvc2VCdXR0b24ub24oJ3BvaW50ZXJkb3duJywgZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlQnV0dG9uID0gY2xvc2VCdXR0b25cbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQoY2xvc2VCdXR0b24pXG5cbiAgICAgICAgICAgIC8vIG1heFdpZHRoIGlzIHNldCBhbmQgYSBjbG9zZUJ1dHRvbiBzaG91bGQgYmUgZGlzcGxheWVkXG4gICAgICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLm1heFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgd29yZFdyYXBXaWR0aCA9IHRoaXMub3B0cy5tYXhXaWR0aCAtICgyICogdGhpcy5vcHRzLnBhZGRpbmcpIC0gdGhpcy5zbWFsbFBhZGRpbmcgLSB0aGlzLl9jbG9zZUJ1dHRvbi53aWR0aFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9oZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWFkZXJTdHlsZS53b3JkV3JhcFdpZHRoID0gd29yZFdyYXBXaWR0aFxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRleHRTdHlsZS53b3JkV3JhcFdpZHRoID0gd29yZFdyYXBXaWR0aFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGJ1dHRvbnNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmJ1dHRvbiB8fCB0aGlzLm9wdHMuYnV0dG9uR3JvdXApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuYnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYnV0dG9ucyA9IG5ldyBCdXR0b24oT2JqZWN0LmFzc2lnbih7dGV4dFN0eWxlOiB0aGlzLnRoZW1lLnRleHRTdHlsZVNtYWxsfSwgdGhpcy5vcHRzLmJ1dHRvbikpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2J1dHRvbnMgPSBuZXcgQnV0dG9uR3JvdXAoT2JqZWN0LmFzc2lnbih7dGV4dFN0eWxlOiB0aGlzLnRoZW1lLnRleHRTdHlsZVNtYWxsfSwgdGhpcy5vcHRzLmJ1dHRvbkdyb3VwKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5fYnV0dG9ucylcblxuICAgICAgICAgICAgdGhpcy5fYnV0dG9ucy55ID0gdGhpcy5pbm5lclBhZGRpbmcgKyB0aGlzLnN5XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3VsZCBiZSBjYWxsZWQgdG8gcmVmcmVzaCB0aGUgbGF5b3V0IG9mIHRoZSBwb3B1cC4gQ2FuIGJlIHVzZWQgYWZ0ZXIgcmVzaXppbmcuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtBYnN0cmFjdFBvcHVwfSBBIHJlZmVyZW5jZSB0byB0aGUgcG9wdXAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcblxuICAgICAgICBzdXBlci5sYXlvdXQoKVxuICAgICAgICBcbiAgICAgICAgLy8gY2xvc2VCdXR0b25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLmNsb3NlQnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9jbG9zZUJ1dHRvbi54ID0gdGhpcy53YW50ZWRXaWR0aCAtIHRoaXMuc21hbGxQYWRkaW5nIC0gdGhpcy5fY2xvc2VCdXR0b24ud2lkdGhcbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlQnV0dG9uLnkgPSB0aGlzLnNtYWxsUGFkZGluZ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYnV0dG9uc1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLl9idXR0b25zKSB7XG4gICAgICAgICAgICB0aGlzLl9idXR0b25zLnggPSB0aGlzLndhbnRlZFdpZHRoIC0gdGhpcy5vcHRzLnBhZGRpbmcgLSB0aGlzLl9idXR0b25zLndpZHRoXG4gICAgICAgICAgICB0aGlzLl9idXR0b25zLnkgPSB0aGlzLndhbnRlZEhlaWdodCAtIHRoaXMub3B0cy5wYWRkaW5nIC0gdGhpcy5fYnV0dG9ucy5oZWlnaHRcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgc2l6ZSBvZiB0aGUgY2hpbGRyZW4gb2YgdGhlIEFic3RyYWN0UG9wdXAuXG4gICAgICogQ2Fubm90IHVzZSBnZXRCb3VuZHMoKSBiZWNhdXNlIGl0IGlzIG5vdCB1cGRhdGVkIHdoZW4gY2hpbGRyZW5cbiAgICAgKiBhcmUgcmVtb3ZlZC5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBvdmVycmlkZVxuICAgICAqIEByZXR1cm5zIHtvYmplY3R9IEFuIEphdmFTY3JpcHQgb2JqZWN0IHdpZHRoIHRoZSBrZXlzIHdpZHRoIGFuZCBoZWlnaHQuXG4gICAgICovXG4gICAgZ2V0SW5uZXJTaXplKCkge1xuXG4gICAgICAgIGxldCBzaXplID0gc3VwZXIuZ2V0SW5uZXJTaXplKClcblxuICAgICAgICBpZiAodGhpcy5fY2xvc2VCdXR0b24pIHtcbiAgICAgICAgICAgIHNpemUud2lkdGggKz0gdGhpcy5zbWFsbFBhZGRpbmcgKyB0aGlzLl9jbG9zZUJ1dHRvbi53aWR0aFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2J1dHRvbnMpIHtcbiAgICAgICAgICAgIHNpemUud2lkdGggPSBNYXRoLm1heChzaXplLndpZHRoLCB0aGlzLl9idXR0b25zLnggKyB0aGlzLl9idXR0b25zLndpZHRoKVxuICAgICAgICAgICAgc2l6ZS5oZWlnaHQgKz0gdGhpcy5pbm5lclBhZGRpbmcgKyB0aGlzLl9idXR0b25zLmhlaWdodFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNpemVcbiAgICB9XG59XG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFBvcHVwLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIHBvcHVwXG4gKiBjb25zdCBwb3B1cCA9IG5ldyBQb3B1cCh7XG4gKiAgICAgaGVhZGVyOiAnR29ldGhlJyxcbiAqICAgICBjb250ZW50OiAnTWFuIGthbm4gZGllIEVyZmFocnVuZyBuaWNodCBmcsO8aCBnZW51ZyBtYWNoZW4sIHdpZSBlbnRiZWhybGljaCBtYW4gaW4gZGVyIFdlbHQgaXN0LidcbiAqIH0pXG4gKlxuICogLy8gQWRkIHRoZSBwb3B1cCB0byBhIERpc3BsYXlPYmplY3RcbiAqIGFwcC5zY2VuZS5hZGRDaGlsZChwb3B1cClcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIEludGVyYWN0aXZlUG9wdXBcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS9wb3B1cC5odG1sfERvY1Rlc3R9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvcHVwIGV4dGVuZHMgSW50ZXJhY3RpdmVQb3B1cCB7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgUG9wdXAuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBwb3B1cC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmNsb3NlQnV0dG9uPWZhbHNlXSAtIFNob3VsZCBhIGNsb3NlIGJ1dHRvbiBiZSBkaXNwbGF5ZWQgb24gdGhlIHVwcGVyIHJpZ2h0IGNvcm5lcj9cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWluV2lkdGg9MF0gLSBUaGUgbWluaW11bSB3aWR0aCBvZiB0aGUgcG9wdXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLm1pbkhlaWdodD0wXSAtIFRoZSBtaW5pbXVtIGhlaWdodCBvZiB0aGUgcG9wdXAuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG5cbiAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgIGNsb3NlQnV0dG9uOiBmYWxzZSxcbiAgICAgICAgICAgIG1pbldpZHRoOiAwLFxuICAgICAgICAgICAgbWluSGVpZ2h0OiAwXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgc3VwZXIob3B0cylcbiAgICB9XG59XG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCB7SW50ZXJhY3RpdmVQb3B1cH0gZnJvbSAnLi9wb3B1cC5qcydcblxuLyoqXG4gKiBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBQaXhpSlMgTW9kYWwuXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIGJ1dHRvbiBhbmQgdGhlIG1vZGFsIHdoZW4gY2xpY2tlZFxuICogY29uc3QgYnV0dG9uID0gbmV3IEJ1dHRvbih7XG4gKiAgICAgbGFiZWw6ICdTaG93IE1vZGFsJyxcbiAqICAgICBhY3Rpb246IGUgPT4ge1xuICogICAgICAgICBjb25zdCBtb2RhbCA9IG5ldyBNb2RhbCh7XG4gKiAgICAgICAgICAgICBhcHA6IGFwcCxcbiAqICAgICAgICAgICAgIGhlYWRlcjogJ1RoaXMgaXMgdGhlIGhlYWRlcicsXG4gKiAgICAgICAgICAgICBjb250ZW50OiAnVGhpcyBpcyB0aGUgdGV4dC4nXG4gKiAgICAgICAgIH0pXG4gKiAgICAgICAgIGFwcC5zY2VuZS5hZGRDaGlsZChtb2RhbClcbiAqICAgICB9XG4gKiB9KVxuICpcbiAqIC8vIEFkZCB0aGUgYnV0dG9uIHRvIGEgRGlzcGxheU9iamVjdFxuICogYXBwLnNjZW5lLmFkZENoaWxkKGJ1dHRvbilcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFBJWEkuQ29udGFpbmVyXG4gKiBAZXh0ZW5kcyBJbnRlcmFjdGl2ZVBvcHVwXG4gKiBAc2VlIHtAbGluayBodHRwOi8vcGl4aWpzLmRvd25sb2FkL2Rldi9kb2NzL1BJWEkuQ29udGFpbmVyLmh0bWx8UElYSS5Db250YWluZXJ9XG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvbW9kYWwuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RhbCBleHRlbmRzIFBJWEkuQ29udGFpbmVyIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBNb2RhbC5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBtb2RhbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaWQ9YXV0byBnZW5lcmF0ZWRdIC0gVGhlIGlkIG9mIHRoZSBtb2RhbC5cbiAgICAgKiBAcGFyYW0ge1BJWElBcHB9IFtvcHRzLmFwcD13aW5kb3cuYXBwXSAtIFRoZSBhcHAgd2hlcmUgdGhlIG1vZGFsIGJlbG9uZ3MgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmJhY2tncm91bmRGaWxsPVRoZW1lLmJhY2tncm91bmRdIC0gVGhlIGNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5iYWNrZ3JvdW5kRmlsbEFscGhhPTAuNl0gLSBUaGUgb3BhY2l0eSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmNsb3NlT25CYWNrZ3JvdW5kPXRydWVdIC0gU2hvdWxkIHRoZSBtb2RhbCBiZSBjbG9zZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgdGhlXG4gICAgICogICAgIGJhY2tncm91bmQ/XG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy52aXNpYmxlPXRydWVdIC0gSXMgdGhlIG1vZGFsIGluaXRpYWxseSB2aXNpYmxlIChwcm9wZXJ0eSB2aXNpYmxlKT9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcblxuICAgICAgICBzdXBlcigpXG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcbiAgICAgICAgdGhpcy50aGVtZSA9IHRoZW1lXG5cbiAgICAgICAgdGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgaWQ6IFBJWEkudXRpbHMudWlkKCksXG4gICAgICAgICAgICBhcHA6IHdpbmRvdy5hcHAsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kRmlsbDogdGhlbWUuYmFja2dyb3VuZCxcbiAgICAgICAgICAgIGJhY2tncm91bmRGaWxsQWxwaGE6IC42LFxuICAgICAgICAgICAgY2xvc2VPbkJhY2tncm91bmQ6IHRydWUsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub3B0cy5pZFxuXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZCA9IG51bGxcbiAgICAgICAgdGhpcy5wb3B1cCA9IG51bGxcblxuICAgICAgICB0aGlzLmFscGhhID0gMFxuICAgICAgICB0aGlzLnZpc2libGUgPSB0aGlzLm9wdHMudmlzaWJsZVxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG5cbiAgICAgICAgLy8gbGF5b3V0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge01vZGFsfSBBIHJlZmVyZW5jZSB0byB0aGUgbW9kYWwgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldHVwKCkge1xuXG4gICAgICAgIC8vIGludGVyYWN0aW9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgdGhpcy5vbignYWRkZWQnLCBlID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpc2libGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3coKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIC8vIGJhY2tncm91bmRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBsZXQgYmFja2dyb3VuZCA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kID0gYmFja2dyb3VuZFxuICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMuYmFja2dyb3VuZClcblxuICAgICAgICBpZiAodGhpcy5vcHRzLmNsb3NlT25CYWNrZ3JvdW5kKSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLmludGVyYWN0aXZlID0gdHJ1ZVxuICAgICAgICAgICAgYmFja2dyb3VuZC5vbigncG9pbnRlcnVwJywgZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb3B1cFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IHBvcHVwT3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMub3B0cywge1xuICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIG9uSGlkZGVuOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgbGV0IHBvcHVwID0gbmV3IEludGVyYWN0aXZlUG9wdXAocG9wdXBPcHRzKVxuICAgICAgICB0aGlzLnBvcHVwID0gcG9wdXBcbiAgICAgICAgdGhpcy5hZGRDaGlsZChwb3B1cClcbiAgICAgICAgcG9wdXAuc2hvdygpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIG1vZGFsLiBDYW4gYmUgdXNlZCBhZnRlciByZXNpemluZy5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtNb2RhbH0gQSByZWZlcmVuY2UgdG8gdGhlIG1vZGFsIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG5cbiAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLm9wdHMuYXBwLnNpemUud2lkdGhcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5vcHRzLmFwcC5zaXplLmhlaWdodFxuXG4gICAgICAgIC8vIGJhY2tncm91bmRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmJhY2tncm91bmQuY2xlYXIoKVxuICAgICAgICB0aGlzLmJhY2tncm91bmQuYmVnaW5GaWxsKHRoaXMub3B0cy5iYWNrZ3JvdW5kRmlsbCwgdGhpcy5vcHRzLmJhY2tncm91bmRGaWxsQWxwaGEpXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZC5kcmF3UmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KVxuICAgICAgICB0aGlzLmJhY2tncm91bmQuZW5kRmlsbCgpXG5cbiAgICAgICAgLy8gcG9zaXRpb25cbiAgICAgICAgdGhpcy5wb3B1cC54ID0gd2lkdGggLyAyIC0gdGhpcy5wb3B1cC53aWR0aCAvIDJcbiAgICAgICAgdGhpcy5wb3B1cC55ID0gaGVpZ2h0IC8gMiAtIHRoaXMucG9wdXAuaGVpZ2h0IC8gMlxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBtb2RhbCAoc2V0cyBoaXMgYWxwaGEgdmFsdWVzIHRvIDEpLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge01vZGFsfSBBIHJlZmVyZW5jZSB0byB0aGUgbW9kYWwgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNob3coKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogMSwgb25TdGFydDogKCkgPT4gdGhpcy52aXNpYmxlID0gdHJ1ZX0pXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIG1vZGFsIChzZXRzIGhpcyBhbHBoYSB2YWx1ZXMgdG8gMCkuXG4gICAgICogXG4gICAgICogQHJldHVybiB7TW9kYWx9IEEgcmVmZXJlbmNlIHRvIHRoZSBtb2RhbCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgaGlkZSgpIHtcbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAwLCBvbkNvbXBsZXRlOiAoKSA9PiB0aGlzLnZpc2libGUgPSBmYWxzZX0pXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2V0cyBvciBnZXRzIHRoZSBoZWFkZXIuIFRoZSBnZXR0ZXIgYWx3YXlzIHJldHVybnMgYSBQSVhJLlRleHQgb2JqZWN0LiBUaGUgc2V0dGVyIGNhbiByZWNlaXZlXG4gICAgICogYSBzdHJpbmcgb3IgYSBQSVhJLlRleHQgb2JqZWN0LlxuICAgICAqIFxuICAgICAqIEBtZW1iZXIge3N0cmluZ3xQSVhJLlRleHR9XG4gICAgICovXG4gICAgZ2V0IGhlYWRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9wdXAuaGVhZGVyXG4gICAgfVxuICAgIHNldCBoZWFkZXIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5vcHRzLmhlYWRlciA9IHZhbHVlXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZC5kZXN0cm95KClcbiAgICAgICAgdGhpcy5wb3B1cC5kZXN0cm95KClcbiAgICAgICAgdGhpcy5zZXR1cCgpLmxheW91dCgpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFNldHMgb3IgZ2V0cyB0aGUgY29udGVudC4gVGhlIGdldHRlciBhbHdheXMgcmV0dXJucyBhbiBQSVhJLkRpc3BsYXlPYmplY3QuIFRoZSBzZXR0ZXIgY2FuIHJlY2VpdmVcbiAgICAgKiBhIHN0cmluZyBvciBhIFBJWEkuRGlzcGxheU9iamVjdC5cbiAgICAgKiBcbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd8UElYSS5EaXNwbGF5T2JqZWN0fVxuICAgICAqL1xuICAgIGdldCBjb250ZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wb3B1cC5jb250ZW50XG4gICAgfVxuICAgIHNldCBjb250ZW50KHZhbHVlKSB7XG4gICAgICAgIHRoaXMub3B0cy5jb250ZW50ID0gdmFsdWVcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kLmRlc3Ryb3koKVxuICAgICAgICB0aGlzLnBvcHVwLmRlc3Ryb3koKVxuICAgICAgICB0aGlzLnNldHVwKCkubGF5b3V0KClcbiAgICB9XG59XG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCB7SW50ZXJhY3RpdmVQb3B1cH0gZnJvbSAnLi9wb3B1cC5qcydcblxuLyoqXG4gKiBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBNZXNzYWdlLiBBIG1lc3NhZ2UgcG9wcyB1cCBhbmQgZGlzYXBwZWFycyBhZnRlciBhIHNwZWNpZmljIGFtb3VudCBvZiB0aW1lLlxuICogXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBQaXhpSlMgQXBwXG4gKiBjb25zdCBhcHAgPSBuZXcgUElYSUFwcCh7XG4gKiAgICAgdmlldzogY2FudmFzLFxuICogICAgIHdpZHRoOiA5MDAsXG4gKiAgICAgaGVpZ2h0OiAyNTBcbiAqIH0pLnNldHVwKCkucnVuKClcbiAqIFxuICogLy8gQ3JlYXRlIGEgYnV0dG9uXG4gKiBsZXQgYnV0dG9uID0gbmV3IEJ1dHRvbih7XG4gKiAgICAgbGFiZWw6ICdDbGljayBtZScsXG4gKiAgICAgYWN0aW9uOiBlID0+IHtcbiAqICAgICAgICAgY29uc3QgbWVzc2FnZSA9IG5ldyBNZXNzYWdlKHtcbiAqICAgICAgICAgICAgIGFwcDogYXBwLFxuICogICAgICAgICAgICAgaGVhZGVyOiAnSGVhZGVyJyxcbiAqICAgICAgICAgICAgIGNvbnRlbnQ6ICdUZXh0LidcbiAqICAgICAgICAgfSlcbiAqICAgICAgICAgYXBwLnNjZW5lLmFkZENoaWxkKG1lc3NhZ2UpXG4gKiAgICAgfVxuICogfSlcbiAqIFxuICogLy8gQWRkIHRoZSBidXR0b24gdG8gdGhlIHNjZW5lXG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQoYnV0dG9uKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgSW50ZXJhY3RpdmVQb3B1cFxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cuaXdtLXR1ZWJpbmdlbi5kZS9pd21icm93c2VyL2xpYi9waXhpL21lc3NhZ2UuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlIGV4dGVuZHMgSW50ZXJhY3RpdmVQb3B1cCB7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgTWVzc2FnZS5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBtZXNzYWdlLlxuICAgICAqIEBwYXJhbSB7UElYSUFwcH0gW29wdHMuYXBwPXdpbmRvdy5hcHBdIC0gVGhlIFBJWElBcHAgd2hlcmUgdGhpcyBtZXNzYWdlIGJlbG9uZ3MgdG8uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5jbG9zZUJ1dHRvbj1mYWxzZV0gLSBTaG91bGQgYSBjbG9zZSBidXR0b24gYmUgZGlzcGxheWVkIGluIHRoZSB1cHBlciByaWdodCBjb3JuZXI/XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLm1pbldpZHRoPTI4MF0gLSBUaGUgbWluaW11bSB3aWR0aCBvZiB0aGUgbWVzc2FnZSBib3guIEF1dG9tYXRpY2FsbHkgZXhwYW5kcyB3aXRoIHRoZSBjb250ZW50LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5taW5IZWlnaHQ9MTAwXSAtIFRoZSBtaW5pbXVtIGhlaWdodCBvZiB0aGUgbWVzc2FnZSBib3guIEF1dG9tYXRpY2FsbHkgZXhwYW5kcyB3aXRoIHRoZSBjb250ZW50LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5tYXJnaW49VGhlbWUubWFyZ2luXSAtIFRoZSBvdXRlciBzcGFjaW5nIG9mIHRoZSBtZXNzYWdlIGJveC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuYWxpZ249cmlnaHRdIC0gVGhlIGhvcml6b250YWwgcG9zaXRpb24gb2YgdGhlIG1lc3NhZ2UgYm94IHJlbGF0aXZlIHRvIHRoZSBhcHAuIFBvc3NpYmxlXG4gICAgICogICAgIHZhbHVlcyBhcmUgbGVmdCwgY2VudGVyLCByaWdodC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudmVydGljYWxBbGlnbj10b3BdIC0gVGhlIHZlcnRpY2FsIHBvc2l0aW9uIG9mIHRoZSBtZXNzYWdlIGJveCByZWxhdGl2ZSB0byB0aGUgYXBwLiBQb3NzaWJsZVxuICAgICAqICAgICB2YWx1ZXMgYXJlIHRvcCwgbWlkZGxlLCBib3R0b20uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmR1cmF0aW9uPTVdIC0gVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgd2hlbiB0aGUgbWVzc2FnZSBib3ggc2hvdWxkIGRpc2FwcGVhci5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmF1dG9DbG9zZT10cnVlXSAtIFNob3VsZCB0aGUgbWVzc2FnZSBib3ggYmUgY2xvc2VkIGF1dG9tYXRpY2FsbHk/XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNsb3NlRHVyYXRpb249VGhlbWUuZmFzdF0gLSBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBvZiB0aGUgY2xvc2luZyBvZiB0aGUgbWVzc2FnZSBib3guXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcblxuICAgICAgICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgYXBwOiB3aW5kb3cuYXBwLFxuICAgICAgICAgICAgY2xvc2VCdXR0b246IGZhbHNlLFxuICAgICAgICAgICAgbWluV2lkdGg6IDI4MCxcbiAgICAgICAgICAgIG1pbkhlaWdodDogMTAwLFxuICAgICAgICAgICAgbWFyZ2luOiB0aGVtZS5tYXJnaW4sXG4gICAgICAgICAgICBhbGlnbjogJ3JpZ2h0JywgICAgICAgICAgICAgICAgICAgICAvLyBsZWZ0LCBjZW50ZXIsIHJpZ2h0XG4gICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAndG9wJywgICAgICAgICAgICAgICAvLyB0b3AsIG1pZGRsZSwgYm90dG9tXG4gICAgICAgICAgICBkdXJhdGlvbjogNSxcbiAgICAgICAgICAgIGF1dG9DbG9zZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlRHVyYXRpb246IHRoZW1lLmZhc3RcbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICBzdXBlcihvcHRzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbGF5b3V0cyB0aGUgcG9zaXRpb24gb2YgdGhlIG1lc3NhZ2UgYm94LlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge01lc3NhZ2V9IFJldHVybnMgdGhlIG1lc3NhZ2UgYm94IGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG5cbiAgICAgICAgc3VwZXIubGF5b3V0KClcblxuICAgICAgICAvLyBob3Jpem9udGFsXG4gICAgICAgIHN3aXRjaCAodGhpcy5vcHRzLmFsaWduKSB7XG4gICAgICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgICAgICB0aGlzLnggPSB0aGlzLm9wdHMubWFyZ2luXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgICAgICAgICAgdGhpcy54ID0gKHRoaXMub3B0cy5hcHAuc2l6ZS53aWR0aCAvIDIpIC0gKHRoaXMud2lkdGggLyAyKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgdGhpcy54ID0gdGhpcy5vcHRzLmFwcC5zaXplLndpZHRoIC0gdGhpcy5vcHRzLm1hcmdpbiAtIHRoaXMud2lkdGhcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmVydGljYWxcbiAgICAgICAgc3dpdGNoICh0aGlzLm9wdHMudmVydGljYWxBbGlnbikge1xuICAgICAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgICAgICB0aGlzLnkgPSB0aGlzLm9wdHMubWFyZ2luXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgJ21pZGRsZSc6XG4gICAgICAgICAgICAgICAgdGhpcy55ID0gKHRoaXMub3B0cy5hcHAuc2l6ZS5oZWlnaHQgLyAyKSAtICh0aGlzLmhlaWdodCAvIDIpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICAgICAgdGhpcy55ID0gdGhpcy5vcHRzLmFwcC5zaXplLmhlaWdodCAtIHRoaXMub3B0cy5tYXJnaW4gLSB0aGlzLmhlaWdodFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgbWVzc2FnZSBib3guXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzaG93KCkge1xuXG4gICAgICAgIHN1cGVyLnNob3coKVxuXG4gICAgICAgIGlmICh0aGlzLm9wdHMuYXV0b0Nsb3NlKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgICAgIH0sIHRoaXMub3B0cy5kdXJhdGlvbiAqIDEwMDApXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKiBnbG9iYWxzIFdlYktpdFBvaW50ICovXG5cbi8qKiBUZXN0cyB3aGV0aGVyIGFuIG9iamVjdCBpcyBlbXB0eVxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHRoZSBvYmplY3QgdG8gYmUgdGVzdGVkXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShvYmopIHtcbiAgICAvLyA+IGlzRW1wdHkoe30pXG4gICAgLy8gdHJ1ZVxuICAgIGZvciAobGV0IGkgaW4gb2JqKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxufVxuXG4vKiogUmV0dXJucyBhIHVuaXZlcnNhbCB1bmlxdWUgaWRcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqIFNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDUwMzQvY3JlYXRlLWd1aWQtdXVpZC1pbi1qYXZhc2NyaXB0LzIxOTYzMTM2IzIxOTYzMTM2XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1dWlkKCkge1xuICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGMgPT4ge1xuICAgICAgICBsZXQgciA9IChNYXRoLnJhbmRvbSgpICogMTYpIHwgMCxcbiAgICAgICAgICAgIHYgPSBjID09ICd4JyA/IHIgOiAociAmIDB4MykgfCAweDhcbiAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpXG4gICAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxlcnAoc3RhcnQsIHN0b3AsIGFtdCkge1xuICAgIHJldHVybiBhbXQgKiAoc3RvcCAtIHN0YXJ0KSArIHN0YXJ0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYW1wbGUocG9wdWxhdGlvbiwgaykge1xuICAgIC8qXG4gICAgICAgIEZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTkyNjk1NDUvaG93LXRvLWdldC1uLW5vLWVsZW1lbnRzLXJhbmRvbWx5LWZyb20tYW4tYXJyYXkvMzg1NzExMzJcbiAgICAgICAgXG4gICAgICAgIENob29zZXMgayB1bmlxdWUgcmFuZG9tIGVsZW1lbnRzIGZyb20gYSBwb3B1bGF0aW9uIHNlcXVlbmNlIG9yIHNldC5cblxuICAgICAgICBSZXR1cm5zIGEgbmV3IGxpc3QgY29udGFpbmluZyBlbGVtZW50cyBmcm9tIHRoZSBwb3B1bGF0aW9uIHdoaWxlXG4gICAgICAgIGxlYXZpbmcgdGhlIG9yaWdpbmFsIHBvcHVsYXRpb24gdW5jaGFuZ2VkLiAgVGhlIHJlc3VsdGluZyBsaXN0IGlzXG4gICAgICAgIGluIHNlbGVjdGlvbiBvcmRlciBzbyB0aGF0IGFsbCBzdWItc2xpY2VzIHdpbGwgYWxzbyBiZSB2YWxpZCByYW5kb21cbiAgICAgICAgc2FtcGxlcy4gIFRoaXMgYWxsb3dzIHJhZmZsZSB3aW5uZXJzICh0aGUgc2FtcGxlKSB0byBiZSBwYXJ0aXRpb25lZFxuICAgICAgICBpbnRvIGdyYW5kIHByaXplIGFuZCBzZWNvbmQgcGxhY2Ugd2lubmVycyAodGhlIHN1YnNsaWNlcykuXG5cbiAgICAgICAgTWVtYmVycyBvZiB0aGUgcG9wdWxhdGlvbiBuZWVkIG5vdCBiZSBoYXNoYWJsZSBvciB1bmlxdWUuICBJZiB0aGVcbiAgICAgICAgcG9wdWxhdGlvbiBjb250YWlucyByZXBlYXRzLCB0aGVuIGVhY2ggb2NjdXJyZW5jZSBpcyBhIHBvc3NpYmxlXG4gICAgICAgIHNlbGVjdGlvbiBpbiB0aGUgc2FtcGxlLlxuXG4gICAgICAgIFRvIGNob29zZSBhIHNhbXBsZSBpbiBhIHJhbmdlIG9mIGludGVnZXJzLCB1c2UgcmFuZ2UgYXMgYW4gYXJndW1lbnQuXG4gICAgICAgIFRoaXMgaXMgZXNwZWNpYWxseSBmYXN0IGFuZCBzcGFjZSBlZmZpY2llbnQgZm9yIHNhbXBsaW5nIGZyb20gYVxuICAgICAgICBsYXJnZSBwb3B1bGF0aW9uOiAgIHNhbXBsZShyYW5nZSgxMDAwMDAwMCksIDYwKVxuXG4gICAgICAgIFNhbXBsaW5nIHdpdGhvdXQgcmVwbGFjZW1lbnQgZW50YWlscyB0cmFja2luZyBlaXRoZXIgcG90ZW50aWFsXG4gICAgICAgIHNlbGVjdGlvbnMgKHRoZSBwb29sKSBpbiBhIGxpc3Qgb3IgcHJldmlvdXMgc2VsZWN0aW9ucyBpbiBhIHNldC5cblxuICAgICAgICBXaGVuIHRoZSBudW1iZXIgb2Ygc2VsZWN0aW9ucyBpcyBzbWFsbCBjb21wYXJlZCB0byB0aGVcbiAgICAgICAgcG9wdWxhdGlvbiwgdGhlbiB0cmFja2luZyBzZWxlY3Rpb25zIGlzIGVmZmljaWVudCwgcmVxdWlyaW5nXG4gICAgICAgIG9ubHkgYSBzbWFsbCBzZXQgYW5kIGFuIG9jY2FzaW9uYWwgcmVzZWxlY3Rpb24uICBGb3JcbiAgICAgICAgYSBsYXJnZXIgbnVtYmVyIG9mIHNlbGVjdGlvbnMsIHRoZSBwb29sIHRyYWNraW5nIG1ldGhvZCBpc1xuICAgICAgICBwcmVmZXJyZWQgc2luY2UgdGhlIGxpc3QgdGFrZXMgbGVzcyBzcGFjZSB0aGFuIHRoZVxuICAgICAgICBzZXQgYW5kIGl0IGRvZXNuJ3Qgc3VmZmVyIGZyb20gZnJlcXVlbnQgcmVzZWxlY3Rpb25zLlxuICAgICovXG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocG9wdWxhdGlvbikpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQb3B1bGF0aW9uIG11c3QgYmUgYW4gYXJyYXkuXCIpXG4gICAgbGV0IG4gPSBwb3B1bGF0aW9uLmxlbmd0aFxuICAgIGlmIChrIDwgMCB8fCBrID4gbilcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJTYW1wbGUgbGFyZ2VyIHRoYW4gcG9wdWxhdGlvbiBvciBpcyBuZWdhdGl2ZVwiKVxuXG4gICAgbGV0IHJlc3VsdCA9IG5ldyBBcnJheShrKVxuICAgIGxldCBzZXRzaXplID0gMjEgICAvLyBzaXplIG9mIGEgc21hbGwgc2V0IG1pbnVzIHNpemUgb2YgYW4gZW1wdHkgbGlzdFxuXG4gICAgaWYgKGsgPiA1KVxuICAgICAgICBzZXRzaXplICs9IE1hdGgucG93KDQsIE1hdGguY2VpbChNYXRoLmxvZyhrICogMywgNCkpKVxuXG4gICAgaWYgKG4gPD0gc2V0c2l6ZSkge1xuICAgICAgICAvLyBBbiBuLWxlbmd0aCBsaXN0IGlzIHNtYWxsZXIgdGhhbiBhIGstbGVuZ3RoIHNldFxuICAgICAgICBsZXQgcG9vbCA9IHBvcHVsYXRpb24uc2xpY2UoKVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGs7IGkrKykgeyAgICAgICAgICAvLyBpbnZhcmlhbnQ6ICBub24tc2VsZWN0ZWQgYXQgWzAsbi1pKVxuICAgICAgICAgICAgbGV0IGogPSBNYXRoLnJhbmRvbSgpICogKG4gLSBpKSB8IDBcbiAgICAgICAgICAgIHJlc3VsdFtpXSA9IHBvb2xbal1cbiAgICAgICAgICAgIHBvb2xbal0gPSBwb29sW24gLSBpIC0gMV0gICAgICAgLy8gbW92ZSBub24tc2VsZWN0ZWQgaXRlbSBpbnRvIHZhY2FuY3lcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBzZWxlY3RlZCA9IG5ldyBTZXQoKVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGs7IGkrKykge1xuICAgICAgICAgICAgbGV0IGogPSBNYXRoLnJhbmRvbSgpICogKG4gLSBpKSB8IDBcbiAgICAgICAgICAgIHdoaWxlIChzZWxlY3RlZC5oYXMoaikpIHtcbiAgICAgICAgICAgICAgICBqID0gTWF0aC5yYW5kb20oKSAqIChuIC0gaSkgfCAwXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxlY3RlZC5hZGQoailcbiAgICAgICAgICAgIHJlc3VsdFtpXSA9IHBvcHVsYXRpb25bal1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbn1cblxuXG4vLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIGFzIGxvbmcgYXMgaXQgY29udGludWVzIHRvIGJlIGludm9rZWQsIHdpbGwgbm90XG4vLyBiZSB0cmlnZ2VyZWQuIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciBpdCBzdG9wcyBiZWluZyBjYWxsZWQgZm9yXG4vLyBOIG1pbGxpc2Vjb25kcy4gSWYgYGltbWVkaWF0ZWAgaXMgcGFzc2VkLCB0cmlnZ2VyIHRoZSBmdW5jdGlvbiBvbiB0aGVcbi8vIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG4vLyBUYWtlbiBmcm9tOiBodHRwczovL2Rhdmlkd2Fsc2gubmFtZS9lc3NlbnRpYWwtamF2YXNjcmlwdC1mdW5jdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICBsZXQgdGltZW91dFxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gdGhpcyxcbiAgICAgICAgICAgIGFyZ3MgPSBhcmd1bWVudHNcbiAgICAgICAgbGV0IGxhdGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGltZW91dCA9IG51bGxcbiAgICAgICAgICAgIGlmICghaW1tZWRpYXRlKSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNhbGxOb3cgPSBpbW1lZGlhdGUgJiYgIXRpbWVvdXRcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0KVxuICAgICAgICBpZiAoY2FsbE5vdykgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKVxuICAgIH1cbn1cblxuLyoqIFJldHVybnMgYW4gaWQgdGhhdCBpcyBndWFyYW50ZWVkIHRvIGJlIHVuaXF1ZSB3aXRoaW4gdGhlIGxpdmV0aW1lIG9mIHRoZVxuICogYXBwbGljYXRpb25cbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xubGV0IF9pZEdlbmVyYXRvciA9IDBcbmV4cG9ydCBmdW5jdGlvbiBnZXRJZCgpIHtcbiAgICByZXR1cm4gJ2lkJyArIF9pZEdlbmVyYXRvcisrXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21JbnQobWluID0gMCwgbWF4ID0gMTAwKSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSArIG1pbilcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbUZsb2F0KG1pbiA9IDAuMCwgbWF4ID0gMS4wKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluKSArIG1pblxufVxuXG5leHBvcnQgY2xhc3MgRGF0ZXMge1xuXG4gICAgc3RhdGljIGNyZWF0ZShmdWxsWWVhciwgbW9udGgsIGRheSkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoZnVsbFllYXIsIG1vbnRoLCBkYXkpKVxuICAgIH1cblxuICAgIHN0YXRpYyBkYXlzSW5Nb250aChkYXRlKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSArIDEsIDApLmdldERhdGUoKVxuICAgIH1cblxuICAgIHN0YXRpYyBzdGFydFllYXJSYW5nZShkYXRlKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhkYXRlLmdldEZ1bGxZZWFyKCkgLSAxLCAxMSwgMzEsIDIzLCA1OSwgNTksIDk5OSkpXG4gICAgfVxuXG4gICAgc3RhdGljIGVuZFllYXJSYW5nZShkYXRlKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhkYXRlLmdldEZ1bGxZZWFyKCkgKyAxLCAwLCAxKSlcbiAgICB9XG5cbiAgICBzdGF0aWMgcHJldlllYXIoZGF0ZSwgb2Zmc2V0ID0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUoZGF0ZS5nZXRGdWxsWWVhcigpIC0gb2Zmc2V0LCAwLCAxKVxuICAgIH1cblxuICAgIHN0YXRpYyBuZXh0WWVhcihkYXRlLCBvZmZzZXQgPSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZShkYXRlLmdldEZ1bGxZZWFyKCkgKyBvZmZzZXQsIDAsIDEpXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRNb250aChkYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSArIDEsIDEpXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHREYXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICAgICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgICAgICBkYXRlLmdldE1vbnRoKCksXG4gICAgICAgICAgICBkYXRlLmdldERhdGUoKSArIDFcbiAgICAgICAgKVxuICAgIH1cblxuICAgIHN0YXRpYyBuZXh0SG91cihkYXRlKSB7XG4gICAgICAgIC8vIFNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTA3MjAvYWRkaW5nLWhvdXJzLXRvLWphdmFzY3JpcHQtZGF0ZS1vYmplY3RcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpICsgNjAgKiA2MCAqIDEwMDApXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRNaW51dGUoZGF0ZSkge1xuICAgICAgICAvLyBTZWUgYWJvdmVcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpICsgNjAgKiAxMDAwKVxuICAgIH1cblxuICAgIHN0YXRpYyBuZXh0U2Vjb25kKGRhdGUpIHtcbiAgICAgICAgLy8gU2VlIGFib3ZlXG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSArIDEwMDApXG4gICAgfVxuXG4gICAgc3RhdGljIG5leHRNaWxsaXNlY29uZChkYXRlKSB7XG4gICAgICAgIC8vIFNlZSBhYm92ZVxuICAgICAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkgKyAxKVxuICAgIH1cblxuICAgIHN0YXRpYyAqaXRlclllYXJzKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgbGV0IGRhdGUgPSB0aGlzLmNyZWF0ZShzdGFydC5nZXRGdWxsWWVhcigpLCAwLCAxKVxuICAgICAgICB3aGlsZSAoZGF0ZSA8PSBlbmQpIHtcbiAgICAgICAgICAgIHlpZWxkIGRhdGVcbiAgICAgICAgICAgIGRhdGUgPSB0aGlzLm5leHRZZWFyKGRhdGUpXG4gICAgICAgIH1cbiAgICAgICAgeWllbGQgZGF0ZVxuICAgIH1cblxuICAgIHN0YXRpYyAqaXRlck1vbnRocyh5ZWFyLCBsaW1pdCA9IDEyKSB7XG4gICAgICAgIGxldCBtb250aCA9IDBcbiAgICAgICAgd2hpbGUgKG1vbnRoIDwgbGltaXQpIHtcbiAgICAgICAgICAgIGxldCBkYXRlID0gdGhpcy5jcmVhdGUoeWVhci5nZXRGdWxsWWVhcigpLCBtb250aCwgMSlcbiAgICAgICAgICAgIHlpZWxkIGRhdGVcbiAgICAgICAgICAgIG1vbnRoICs9IDFcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyAqaXRlck1vbnRoc09mWWVhcnMoeWVhcnMpIHtcbiAgICAgICAgZm9yIChsZXQgeWVhciBvZiB5ZWFycykge1xuICAgICAgICAgICAgZm9yIChsZXQgbW9udGggb2YgdGhpcy5pdGVyTW9udGhzKHllYXIpKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgbW9udGhcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyAqaXRlckRheXMobW9udGgpIHtcbiAgICAgICAgbGV0IGRheSA9IDFcbiAgICAgICAgbGV0IGxpbWl0ID0gRGF0ZXMuZGF5c0luTW9udGgobW9udGgpXG4gICAgICAgIHdoaWxlIChkYXkgPD0gbGltaXQpIHtcbiAgICAgICAgICAgIGxldCBkYXRlID0gdGhpcy5jcmVhdGUobW9udGguZ2V0RnVsbFllYXIoKSwgbW9udGguZ2V0TW9udGgoKSwgZGF5KVxuICAgICAgICAgICAgeWllbGQgZGF0ZVxuICAgICAgICAgICAgZGF5ICs9IDFcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyAqaXRlckRheXNPZk1vbnRocyhtb250aHMpIHtcbiAgICAgICAgZm9yIChsZXQgbW9udGggb2YgbW9udGhzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBkYXkgb2YgdGhpcy5pdGVyRGF5cyhtb250aCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBkYXlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8qIENvbG9yIGNvbnZlcnNpb24gZnVuY3Rpb25zICovXG5cbmV4cG9ydCBjbGFzcyBDb2xvcnMge1xuICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTYyMzgzOC9yZ2ItdG8taGV4LWFuZC1oZXgtdG8tcmdiXG5cbiAgICBzdGF0aWMgcmdiMm51bShyZWQsIGdyZWVuLCBibHVlKSB7XG4gICAgICAgIGxldCByZ2IgPSBibHVlIHwgKGdyZWVuIDw8IDgpIHwgKHJlZCA8PCAxNilcbiAgICAgICAgcmV0dXJuIDB4MDAwMDAwICsgcmdiXG4gICAgfVxuXG4gICAgc3RhdGljIHJnYjJoZXgocmVkLCBncmVlbiwgYmx1ZSkge1xuICAgICAgICBsZXQgcmdiID0gYmx1ZSB8IChncmVlbiA8PCA4KSB8IChyZWQgPDwgMTYpXG4gICAgICAgIHJldHVybiAnIycgKyAoMHgxMDAwMDAwICsgcmdiKS50b1N0cmluZygxNikuc2xpY2UoMSlcbiAgICB9XG5cbiAgICBzdGF0aWMgaGV4MnJnYihoZXgpIHtcbiAgICAgICAgLy8gbG9uZyB2ZXJzaW9uXG4gICAgICAgIGxldCByID0gaGV4Lm1hdGNoKC9eIyhbMC05YS1mXXsyfSkoWzAtOWEtZl17Mn0pKFswLTlhLWZdezJ9KSQvaSlcbiAgICAgICAgaWYgKHIpIHtcbiAgICAgICAgICAgIHJldHVybiByLnNsaWNlKDEsIDQpLm1hcCh4ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQoeCwgMTYpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIC8vIHNob3J0IHZlcnNpb25cbiAgICAgICAgciA9IGhleC5tYXRjaCgvXiMoWzAtOWEtZl0pKFswLTlhLWZdKShbMC05YS1mXSkkL2kpXG4gICAgICAgIGlmIChyKSB7XG4gICAgICAgICAgICByZXR1cm4gci5zbGljZSgxLCA0KS5tYXAoeCA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDB4MTEgKiBwYXJzZUludCh4LCAxNilcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBzdGF0aWMgcmdiKHIsIGcsIGIpIHtcbiAgICAgICAgcmV0dXJuIHsgciwgZywgYiB9XG4gICAgfVxuXG4gICAgc3RhdGljIHN0cmluZzJoZXgoc3RyKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUludCgnMHgnICsgc3RyLnNsaWNlKDEpKVxuICAgIH1cblxuICAgIHN0YXRpYyBsZXJwKHJnYjEsIHJnYjIsIGFtb3VudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcjogTWF0aC5yb3VuZChsZXJwKHJnYjEuciwgcmdiMi5yLCBhbW91bnQpKSxcbiAgICAgICAgICAgIGc6IE1hdGgucm91bmQobGVycChyZ2IxLmcsIHJnYjIuZywgYW1vdW50KSksXG4gICAgICAgICAgICBiOiBNYXRoLnJvdW5kKGxlcnAocmdiMS5iLCByZ2IyLmIsIGFtb3VudCkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0IHZpb2xldCgpIHtcbiAgICAgICAgcmV0dXJuIENvbG9ycy5yZ2IybnVtKDg5LCAzNCwgMTMxKVxuICAgIH1cblxuICAgIHN0YXRpYyBnZXQgc3RlZWxibHVlKCkge1xuICAgICAgICByZXR1cm4gQ29sb3JzLnJnYjJudW0oMCwgMTMwLCAxNjQpXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCBvY2hyZSgpIHtcbiAgICAgICAgcmV0dXJuIENvbG9ycy5yZ2IybnVtKDE4MSwgMTU3LCAwKVxuICAgIH1cblxuICAgIHN0YXRpYyBnZXQgdHVycXVvaXNlKCkge1xuICAgICAgICByZXR1cm4gQ29sb3JzLnJnYjJudW0oMzQsIDE2NCwgMTMxKVxuICAgIH1cblxuICAgIHN0YXRpYyBnZXQgZW1pbmVuY2UoKSB7XG4gICAgICAgIHJldHVybiBDb2xvcnMucmdiMm51bSgxNTAsIDYwLCAxMzQpXG4gICAgfVxuXG4gICAgc3RhdGljIHJhbmRvbSgpIHtcbiAgICAgICAgbGV0IHIgPSBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAyNTUpXG4gICAgICAgIGxldCBnID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMjU1KVxuICAgICAgICBsZXQgYiA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDI1NSlcbiAgICAgICAgcmV0dXJuIENvbG9ycy5yZ2IybnVtKHIsIGcsIGIpXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ3ljbGUgZXh0ZW5kcyBBcnJheSB7XG4gICAgY29uc3RydWN0b3IoLi4uaXRlbXMpIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICBmb3IgKGxldCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgICAgICB0aGlzLnB1c2goaXRlbSlcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluZGV4ID0gMFxuICAgIH1cblxuICAgIG5leHQoKSB7XG4gICAgICAgIGlmICh0aGlzLmluZGV4ID09IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmluZGV4ID0gMFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzW3RoaXMuaW5kZXgrK11cbiAgICB9XG5cbiAgICBjdXJyZW50KCkge1xuICAgICAgICBpZiAodGhpcy5pbmRleCA9PT0gdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXggPSAwXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXNbdGhpcy5pbmRleF1cbiAgICB9XG59XG5cbi8qKiBTdGF0aWMgbWV0aG9kcyB0byBjb21wdXRlIDJEIHBvaW50cyB3aXRoIHggYW5kIHkgY29vcmRpbmF0ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQb2ludHMge1xuICAgIHN0YXRpYyBsZW5ndGgoYSkge1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGEueCAqIGEueCArIGEueSAqIGEueSlcbiAgICB9XG5cbiAgICBzdGF0aWMgbm9ybWFsaXplKHApIHtcbiAgICAgICAgbGV0IGxlbiA9IHRoaXMubGVuZ3RoKHApXG4gICAgICAgIHJldHVybiB0aGlzLm11bHRpcGx5U2NhbGFyKHAsIDEgLyBsZW4pXG4gICAgfVxuXG4gICAgc3RhdGljIG1lYW4oYSwgYikge1xuICAgICAgICByZXR1cm4geyB4OiAoYS54ICsgYi54KSAvIDIsIHk6IChhLnkgKyBiLnkpIC8gMiB9XG4gICAgfVxuXG4gICAgc3RhdGljIHN1YnRyYWN0KGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogYS54IC0gYi54LCB5OiBhLnkgLSBiLnkgfVxuICAgIH1cblxuICAgIHN0YXRpYyBtdWx0aXBseShhLCBiKSB7XG4gICAgICAgIHJldHVybiB7IHg6IGEueCAqIGIueCwgeTogYS55ICogYi55IH1cbiAgICB9XG5cbiAgICBzdGF0aWMgZGl2aWRlKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogYS54IC8gYi54LCB5OiBhLnkgLyBiLnkgfVxuICAgIH1cblxuICAgIHN0YXRpYyBtdWx0aXBseVNjYWxhcihhLCBiKSB7XG4gICAgICAgIHJldHVybiB7IHg6IGEueCAqIGIsIHk6IGEueSAqIGIgfVxuICAgIH1cblxuICAgIHN0YXRpYyBhZGQoYSwgYikge1xuICAgICAgICByZXR1cm4geyB4OiBhLnggKyBiLngsIHk6IGEueSArIGIueSB9XG4gICAgfVxuXG4gICAgc3RhdGljIG5lZ2F0ZShwKSB7XG4gICAgICAgIHJldHVybiB7IHg6IC1wLngsIHk6IC1wLnkgfVxuICAgIH1cblxuICAgIHN0YXRpYyBhbmdsZShwMSwgcDIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIocDEueSAtIHAyLnksIHAxLnggLSBwMi54KVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemVkQW5nbGUocDEsIHAyKSB7XG4gICAgICAgIHJldHVybiBBbmdsZS5ub3JtYWxpemUodGhpcy5hbmdsZShwMSwgcDIpKVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemVkMkFuZ2xlKHAxLCBwMikge1xuICAgICAgICByZXR1cm4gQW5nbGUubm9ybWFsaXplMih0aGlzLmFuZ2xlKHAxLCBwMikpXG4gICAgfVxuXG4gICAgc3RhdGljIGFyYyhwLCBhbHBoYSwgcmFkaXVzKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBwLnggKyByYWRpdXMgKiBNYXRoLmNvcyhhbHBoYSksXG4gICAgICAgICAgICB5OiBwLnkgKyByYWRpdXMgKiBNYXRoLnNpbihhbHBoYSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBkaXN0YW5jZShhLCBiKSB7XG4gICAgICAgIGxldCBkeCA9IGEueCAtIGIueFxuICAgICAgICBsZXQgZHkgPSBhLnkgLSBiLnlcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSlcbiAgICB9XG5cbiAgICBzdGF0aWMgZnJvbVBhZ2VUb05vZGUoZWxlbWVudCwgcCkge1xuICAgICAgICAvLyAgICBpZiAod2luZG93LndlYmtpdENvbnZlcnRQb2ludEZyb21QYWdlVG9Ob2RlKSB7XG4gICAgICAgIC8vICAgICAgICAgICAgIHJldHVybiB3aW5kb3cud2Via2l0Q29udmVydFBvaW50RnJvbVBhZ2VUb05vZGUoZWxlbWVudCxcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBXZWJLaXRQb2ludChwLngsIHAueSkpXG4gICAgICAgIC8vICAgICAgICAgfVxuICAgICAgICByZXR1cm4gd2luZG93LmNvbnZlcnRQb2ludEZyb21QYWdlVG9Ob2RlKGVsZW1lbnQsIHAueCwgcC55KVxuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tTm9kZVRvUGFnZShlbGVtZW50LCBwKSB7XG4gICAgICAgIC8vICBpZiAod2luZG93LndlYmtpdENvbnZlcnRQb2ludEZyb21Ob2RlVG9QYWdlKSB7XG4gICAgICAgIC8vICAgICAgICAgICAgIHJldHVybiB3aW5kb3cud2Via2l0Q29udmVydFBvaW50RnJvbU5vZGVUb1BhZ2UoZWxlbWVudCxcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBXZWJLaXRQb2ludChwLngsIHAueSkpXG4gICAgICAgIC8vICAgICAgICAgfVxuICAgICAgICByZXR1cm4gd2luZG93LmNvbnZlcnRQb2ludEZyb21Ob2RlVG9QYWdlKGVsZW1lbnQsIHAueCwgcC55KVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIGhlbHBlciBjbGFzcyBmb3IgY29tbW9uIHNldCBvcGVyYXRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBTZXRzXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXRzIHtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGludGVyc2VjdGlvbiBvZiBhbGwgc2V0c1xuICAgICAqIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMxOTMwODk0L2phdmFzY3JpcHQtc2V0LWRhdGEtc3RydWN0dXJlLWludGVyc2VjdFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyp9IHNldHNcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBTZXRzXG4gICAgICovXG4gICAgc3RhdGljIGludGVyc2VjdCguLi5zZXRzKSB7XG4gICAgICAgIGlmICghc2V0cy5sZW5ndGgpIHJldHVybiBuZXcgU2V0KClcbiAgICAgICAgY29uc3QgaSA9IHNldHMucmVkdWNlKChtLCBzLCBpKSA9PiBzLnNpemUgPCBzZXRzW21dLnNpemUgPyBpIDogbSwgMClcbiAgICAgICAgY29uc3QgW3NtYWxsZXN0XSA9IHNldHMuc3BsaWNlKGksIDEpXG4gICAgICAgIGNvbnN0IHJlcyA9IG5ldyBTZXQoKVxuICAgICAgICBmb3IgKGxldCB2YWwgb2Ygc21hbGxlc3QpXG4gICAgICAgICAgICBpZiAoc2V0cy5ldmVyeShzID0+IHMuaGFzKHZhbCkpKVxuICAgICAgICAgICAgICAgIHJlcy5hZGQodmFsKVxuICAgICAgICByZXR1cm4gcmVzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdW5pb24gb2YgYWxsIHNldHNcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyp9IHNldHNcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBTZXRzXG4gICAgICovXG4gICAgc3RhdGljIHVuaW9uKC4uLnNldHMpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyBTZXQoKVxuICAgICAgICBmb3IgKGxldCBzZXQgb2Ygc2V0cykge1xuICAgICAgICAgICAgZm9yIChsZXQgbSBvZiBzZXQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuYWRkKG0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIGdpdmVuIHNldHMuIFN0YXJ0cyB3aXRoIHRoZSBmaXJzdCBzZXQgYW5kIHJlbW92aW5nIGFsbCBlbGVtZW50cyBvZiB0aGUgZm9sbG93aW5nIHNldHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHsqfSBzZXRcbiAgICAgKiBAcGFyYW0geyp9IHNldHNcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBTZXRzXG4gICAgICovXG4gICAgc3RhdGljIGRpZmZlcmVuY2Uoc2V0LCAuLi5zZXRzKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBuZXcgU2V0KClcbiAgICAgICAgZm9yIChsZXQgbSBvZiBzZXQpIHtcbiAgICAgICAgICAgIHJlc3VsdC5hZGQobSlcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBzIG9mIHNldHMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IG0gb2Ygcykge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5kZWxldGUobSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxufVxuXG4vKiogU3RhdGljIG1ldGhvZHMgdG8gY29tcHV0ZSBhbmdsZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmdsZSB7XG5cbiAgICBzdGF0aWMgbm9ybWFsaXplKGFuZ2xlKSB7XG4gICAgICAgIGxldCBUQVUgPSBNYXRoLlBJICogMi4wXG4gICAgICAgIHdoaWxlIChhbmdsZSA+IE1hdGguUEkpIHtcbiAgICAgICAgICAgIGFuZ2xlIC09IFRBVVxuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChhbmdsZSA8IC1NYXRoLlBJKSB7XG4gICAgICAgICAgICBhbmdsZSArPSBUQVVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYW5nbGVcbiAgICB9XG5cbiAgICBzdGF0aWMgbm9ybWFsaXplMihhbmdsZSkge1xuICAgICAgICBsZXQgVEFVID0gTWF0aC5QSSAqIDIuMFxuICAgICAgICB3aGlsZSAoYW5nbGUgPiBUQVUpIHtcbiAgICAgICAgICAgIGFuZ2xlIC09IFRBVVxuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChhbmdsZSA8IDApIHtcbiAgICAgICAgICAgIGFuZ2xlICs9IFRBVVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmdsZVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemVEZWdyZWUoYW5nbGUpIHtcbiAgICAgICAgbGV0IGZ1bGwgPSAzNjAuMFxuICAgICAgICB3aGlsZSAoYW5nbGUgPiAxODAuMCkge1xuICAgICAgICAgICAgYW5nbGUgLT0gZnVsbFxuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChhbmdsZSA8IC0xODAuMCkge1xuICAgICAgICAgICAgYW5nbGUgKz0gZnVsbFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmdsZVxuICAgIH1cblxuICAgIHN0YXRpYyBub3JtYWxpemVkRGlmZihhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZSh0aGlzLmRpZmYoYSwgYikpXG4gICAgfVxuXG4gICAgc3RhdGljIG5vcm1hbGl6ZWQyRGlmZihhLCBiKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZTIodGhpcy5kaWZmKGEsIGIpKVxuICAgIH1cblxuICAgIHN0YXRpYyBkaWZmKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIoTWF0aC5zaW4oYSAtIGIpLCBNYXRoLmNvcyhhIC0gYikpXG4gICAgfVxuXG4gICAgc3RhdGljIGRlZ3JlZTJyYWRpYW4oZGVncmVlKSB7XG4gICAgICAgIHJldHVybiBNYXRoLlBJICogZGVncmVlIC8gMTgwLjBcbiAgICB9XG5cbiAgICBzdGF0aWMgcmFkaWFuMmRlZ3JlZShyYWQpIHtcbiAgICAgICAgcmV0dXJuIDE4MC4wIC8gTWF0aC5QSSAqIHJhZFxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEVsZW1lbnRzIHtcbiAgICBzdGF0aWMgc2V0U3R5bGUoZWxlbWVudCwgc3R5bGVzKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBzdHlsZXMpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlc1trZXldXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgYWRkQ2xhc3MoZWxlbWVudCwgY3NzQ2xhc3MpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKGNzc0NsYXNzKVxuICAgIH1cblxuICAgIHN0YXRpYyByZW1vdmVDbGFzcyhlbGVtZW50LCBjc3NDbGFzcykge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoY3NzQ2xhc3MpXG4gICAgfVxuXG4gICAgc3RhdGljIHRvZ2dsZUNsYXNzKGVsZW1lbnQsIGNzc0NsYXNzKSB7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShjc3NDbGFzcylcbiAgICB9XG5cbiAgICBzdGF0aWMgaGFzQ2xhc3MoZWxlbWVudCwgY3NzQ2xhc3MpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNzc0NsYXNzKVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1hcFByb3h5IHtcbiAgICAvKiBUaGlzIGNsYXNzIGlzIG5lZWRlZCBpZiB3ZSB3YW50IHRvIHVzZSB0aGUgaW50ZXJhY3Rpb24gY2xhc3Nlc1xuICAgIGluIEZpcmVmb3ggNDUuOCBhbmQgbW9kZXJuIEJyb3dzZXJzLlxuXG4gICAgQSB3b3JrYXJvdW5kIGZvciBodHRwczovL2dpdGh1Yi5jb20vYmFiZWwvYmFiZWwvaXNzdWVzLzIzMzRcbiAgKi9cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5tYXAgPSBuZXcgTWFwKClcbiAgICB9XG5cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLnNpemVcbiAgICB9XG5cbiAgICBnZXQoa2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoa2V5KVxuICAgIH1cblxuICAgIHNldChrZXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5zZXQoa2V5LCB2YWx1ZSlcbiAgICB9XG5cbiAgICBkZWxldGUoa2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5kZWxldGUoa2V5KVxuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuY2xlYXIoKVxuICAgIH1cblxuICAgIGhhcyhrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmhhcyhrZXkpXG4gICAgfVxuXG4gICAga2V5cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmtleXMoKVxuICAgIH1cblxuICAgIHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLnZhbHVlcygpXG4gICAgfVxuXG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmVudHJpZXMoKVxuICAgIH1cblxuICAgIGZvckVhY2goZnVuYykge1xuICAgICAgICB0aGlzLm1hcC5mb3JFYWNoKGZ1bmMpXG4gICAgfVxufVxuXG4vKiBCYXNlZCBvbSBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9jd2xlb25hcmQvZTEyNGQ2MzIzOGJkYTdhM2NiZmEgKi9cbmV4cG9ydCBjbGFzcyBQb2x5Z29uIHtcbiAgICAvKlxuICAgICAqICBUaGlzIGlzIHRoZSBQb2x5Z29uIGNvbnN0cnVjdG9yLiBBbGwgcG9pbnRzIGFyZSBjZW50ZXItcmVsYXRpdmUuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2VudGVyKSB7XG4gICAgICAgIHRoaXMucG9pbnRzID0gbmV3IEFycmF5KClcbiAgICAgICAgdGhpcy5jZW50ZXIgPSBjZW50ZXJcbiAgICB9XG5cbiAgICAvKlxuICAgICAqICBQb2ludCB4IGFuZCB5IHZhbHVlcyBzaG91bGQgYmUgcmVsYXRpdmUgdG8gdGhlIGNlbnRlci5cbiAgICAgKi9cbiAgICBhZGRQb2ludChwKSB7XG4gICAgICAgIHRoaXMucG9pbnRzLnB1c2gocClcbiAgICB9XG5cbiAgICAvKlxuICAgICAqICBQb2ludCB4IGFuZCB5IHZhbHVlcyBzaG91bGQgYmUgYWJzb2x1dGUgY29vcmRpbmF0ZXMuXG4gICAgICovXG4gICAgYWRkQWJzb2x1dGVQb2ludChwKSB7XG4gICAgICAgIHRoaXMucG9pbnRzLnB1c2goeyB4OiBwLnggLSB0aGlzLmNlbnRlci54LCB5OiBwLnkgLSB0aGlzLmNlbnRlci55IH0pXG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygc2lkZXMuIEVxdWFsIHRvIHRoZSBudW1iZXIgb2YgdmVydGljZXMuXG4gICAgICovXG4gICAgZ2V0TnVtYmVyT2ZTaWRlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9pbnRzLmxlbmd0aFxuICAgIH1cblxuICAgIC8qXG4gICAgICogcm90YXRlIHRoZSBwb2x5Z29uIGJ5IGEgbnVtYmVyIG9mIHJhZGlhbnNcbiAgICAgKi9cbiAgICByb3RhdGUocmFkcykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeCA9IHRoaXMucG9pbnRzW2ldLnhcbiAgICAgICAgICAgIGxldCB5ID0gdGhpcy5wb2ludHNbaV0ueVxuICAgICAgICAgICAgdGhpcy5wb2ludHNbaV0ueCA9IE1hdGguY29zKHJhZHMpICogeCAtIE1hdGguc2luKHJhZHMpICogeVxuICAgICAgICAgICAgdGhpcy5wb2ludHNbaV0ueSA9IE1hdGguc2luKHJhZHMpICogeCArIE1hdGguY29zKHJhZHMpICogeVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiAgVGhlIGRyYXcgZnVuY3Rpb24gdGFrZXMgYXMgYSBwYXJhbWV0ZXIgYSBDb250ZXh0IG9iamVjdCBmcm9tXG4gICAgICogIGEgQ2FudmFzIGVsZW1lbnQgYW5kIGRyYXdzIHRoZSBwb2x5Z29uIG9uIGl0LlxuICAgICAqL1xuICAgIGRyYXcoY29udGV4dCwgeyBsaW5lV2lkdGggPSAyLCBzdHJva2UgPSAnIzAwMDAwMCcsIGZpbGwgPSBudWxsIH0gPSB7fSkge1xuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpXG4gICAgICAgIGNvbnRleHQubW92ZVRvKFxuICAgICAgICAgICAgdGhpcy5wb2ludHNbMF0ueCArIHRoaXMuY2VudGVyLngsXG4gICAgICAgICAgICB0aGlzLnBvaW50c1swXS55ICsgdGhpcy5jZW50ZXIueVxuICAgICAgICApXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdGhpcy5wb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnRleHQubGluZVRvKFxuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRzW2ldLnggKyB0aGlzLmNlbnRlci54LFxuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRzW2ldLnkgKyB0aGlzLmNlbnRlci55XG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKVxuICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IGxpbmVXaWR0aFxuICAgICAgICBpZiAoc3Ryb2tlKSB7XG4gICAgICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gc3Ryb2tlXG4gICAgICAgICAgICBjb250ZXh0LnN0cm9rZSgpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbGwpIHtcbiAgICAgICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gZmlsbFxuICAgICAgICAgICAgY29udGV4dC5maWxsKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFic29sdXRlUG9pbnRzKCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3IEFycmF5KClcbiAgICAgICAgZm9yIChsZXQgcCBvZiB0aGlzLnBvaW50cykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goUG9pbnRzLmFkZChwLCB0aGlzLmNlbnRlcikpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIGZsYXRBYnNvbHV0ZVBvaW50cygpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyBBcnJheSgpXG4gICAgICAgIGZvciAobGV0IHAgb2YgdGhpcy5wb2ludHMpIHtcbiAgICAgICAgICAgIGxldCBhID0gUG9pbnRzLmFkZChwLCB0aGlzLmNlbnRlcilcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGEueClcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGEueSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHBvaW50IGlzIGluc2lkZSB0aGUgcG9seWdvbixcbiAgICAgKiAgYW5kIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBjb250YWluc1BvaW50KHBudCkge1xuICAgICAgICBsZXQgbnZlcnQgPSB0aGlzLnBvaW50cy5sZW5ndGhcbiAgICAgICAgbGV0IHRlc3R4ID0gcG50LnhcbiAgICAgICAgbGV0IHRlc3R5ID0gcG50LnlcblxuICAgICAgICBsZXQgdmVydHggPSBuZXcgQXJyYXkoKVxuICAgICAgICBmb3IgKGxldCBxID0gMDsgcSA8IHRoaXMucG9pbnRzLmxlbmd0aDsgcSsrKSB7XG4gICAgICAgICAgICB2ZXJ0eC5wdXNoKHRoaXMucG9pbnRzW3FdLnggKyB0aGlzLmNlbnRlci54KVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZlcnR5ID0gbmV3IEFycmF5KClcbiAgICAgICAgZm9yIChsZXQgdyA9IDA7IHcgPCB0aGlzLnBvaW50cy5sZW5ndGg7IHcrKykge1xuICAgICAgICAgICAgdmVydHkucHVzaCh0aGlzLnBvaW50c1t3XS55ICsgdGhpcy5jZW50ZXIueSlcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpLFxuICAgICAgICAgICAgaiA9IDBcbiAgICAgICAgbGV0IGMgPSBmYWxzZVxuICAgICAgICBmb3IgKGkgPSAwLCBqID0gbnZlcnQgLSAxOyBpIDwgbnZlcnQ7IGogPSBpKyspIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB2ZXJ0eVtpXSA+IHRlc3R5ICE9IHZlcnR5W2pdID4gdGVzdHkgJiZcbiAgICAgICAgICAgICAgICB0ZXN0eCA8XG4gICAgICAgICAgICAgICAgKHZlcnR4W2pdIC0gdmVydHhbaV0pICpcbiAgICAgICAgICAgICAgICAodGVzdHkgLSB2ZXJ0eVtpXSkgL1xuICAgICAgICAgICAgICAgICh2ZXJ0eVtqXSAtIHZlcnR5W2ldKSArXG4gICAgICAgICAgICAgICAgdmVydHhbaV1cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBjID0gIWNcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY1xuICAgIH1cblxuICAgIG11bHRpcGx5U2NhbGFyKHNjYWxlKSB7XG4gICAgICAgIGxldCBjZW50ZXIgPSBQb2ludHMubXVsdGlwbHlTY2FsYXIodGhpcy5jZW50ZXIsIHNjYWxlKVxuICAgICAgICBsZXQgY2xvbmUgPSBuZXcgUG9seWdvbihjZW50ZXIpXG4gICAgICAgIGZvciAobGV0IHAgb2YgdGhpcy5wb2ludHMpIHtcbiAgICAgICAgICAgIGNsb25lLmFkZFBvaW50KFBvaW50cy5tdWx0aXBseVNjYWxhcihwLCBzY2FsZSkpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNsb25lXG4gICAgfVxuXG4gICAgLypcbiAgICAgKiAgVG8gZGV0ZWN0IGludGVyc2VjdGlvbiB3aXRoIGFub3RoZXIgUG9seWdvbiBvYmplY3QsIHRoaXNcbiAgICAgKiAgZnVuY3Rpb24gdXNlcyB0aGUgU2VwYXJhdGluZyBBeGlzIFRoZW9yZW0uIEl0IHJldHVybnMgZmFsc2VcbiAgICAgKiAgaWYgdGhlcmUgaXMgbm8gaW50ZXJzZWN0aW9uLCBvciBhbiBvYmplY3QgaWYgdGhlcmUgaXMuIFRoZSBvYmplY3RcbiAgICAgKiAgY29udGFpbnMgMiBmaWVsZHMsIG92ZXJsYXAgYW5kIGF4aXMuIE1vdmluZyB0aGUgcG9seWdvbiBieSBvdmVybGFwXG4gICAgICogIG9uIGF4aXMgd2lsbCBnZXQgdGhlIHBvbHlnb25zIG91dCBvZiBpbnRlcnNlY3Rpb24uXG4gICAgICovXG4gICAgaW50ZXJzZWN0c1dpdGgob3RoZXIpIHtcbiAgICAgICAgbGV0IGF4aXMgPSB7IHg6IDAsIHk6IDAgfVxuICAgICAgICBsZXQgdG1wLCBtaW5BLCBtYXhBLCBtaW5CLCBtYXhCXG4gICAgICAgIGxldCBzaWRlLCBpXG4gICAgICAgIGxldCBzbWFsbGVzdCA9IG51bGxcbiAgICAgICAgbGV0IG92ZXJsYXAgPSA5OTk5OTk5OVxuXG4gICAgICAgIC8qIHRlc3QgcG9seWdvbiBBJ3Mgc2lkZXMgKi9cbiAgICAgICAgZm9yIChzaWRlID0gMDsgc2lkZSA8IHRoaXMuZ2V0TnVtYmVyT2ZTaWRlcygpOyBzaWRlKyspIHtcbiAgICAgICAgICAgIC8qIGdldCB0aGUgYXhpcyB0aGF0IHdlIHdpbGwgcHJvamVjdCBvbnRvICovXG4gICAgICAgICAgICBpZiAoc2lkZSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgYXhpcy54ID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2ludHNbdGhpcy5nZXROdW1iZXJPZlNpZGVzKCkgLSAxXS55IC1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2ludHNbMF0ueVxuICAgICAgICAgICAgICAgIGF4aXMueSA9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucG9pbnRzWzBdLnggLVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50c1t0aGlzLmdldE51bWJlck9mU2lkZXMoKSAtIDFdLnhcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXhpcy54ID0gdGhpcy5wb2ludHNbc2lkZSAtIDFdLnkgLSB0aGlzLnBvaW50c1tzaWRlXS55XG4gICAgICAgICAgICAgICAgYXhpcy55ID0gdGhpcy5wb2ludHNbc2lkZV0ueCAtIHRoaXMucG9pbnRzW3NpZGUgLSAxXS54XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qIG5vcm1hbGl6ZSB0aGUgYXhpcyAqL1xuICAgICAgICAgICAgdG1wID0gTWF0aC5zcXJ0KGF4aXMueCAqIGF4aXMueCArIGF4aXMueSAqIGF4aXMueSlcbiAgICAgICAgICAgIGF4aXMueCAvPSB0bXBcbiAgICAgICAgICAgIGF4aXMueSAvPSB0bXBcblxuICAgICAgICAgICAgLyogcHJvamVjdCBwb2x5Z29uIEEgb250byBheGlzIHRvIGRldGVybWluZSB0aGUgbWluL21heCAqL1xuICAgICAgICAgICAgbWluQSA9IG1heEEgPSB0aGlzLnBvaW50c1swXS54ICogYXhpcy54ICsgdGhpcy5wb2ludHNbMF0ueSAqIGF4aXMueVxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHRoaXMuZ2V0TnVtYmVyT2ZTaWRlcygpOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnBvaW50c1tpXS54ICogYXhpcy54ICsgdGhpcy5wb2ludHNbaV0ueSAqIGF4aXMueVxuICAgICAgICAgICAgICAgIGlmICh0bXAgPiBtYXhBKSBtYXhBID0gdG1wXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodG1wIDwgbWluQSkgbWluQSA9IHRtcFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyogY29ycmVjdCBmb3Igb2Zmc2V0ICovXG4gICAgICAgICAgICB0bXAgPSB0aGlzLmNlbnRlci54ICogYXhpcy54ICsgdGhpcy5jZW50ZXIueSAqIGF4aXMueVxuICAgICAgICAgICAgbWluQSArPSB0bXBcbiAgICAgICAgICAgIG1heEEgKz0gdG1wXG5cbiAgICAgICAgICAgIC8qIHByb2plY3QgcG9seWdvbiBCIG9udG8gYXhpcyB0byBkZXRlcm1pbmUgdGhlIG1pbi9tYXggKi9cbiAgICAgICAgICAgIG1pbkIgPSBtYXhCID1cbiAgICAgICAgICAgICAgICBvdGhlci5wb2ludHNbMF0ueCAqIGF4aXMueCArIG90aGVyLnBvaW50c1swXS55ICogYXhpcy55XG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgb3RoZXIuZ2V0TnVtYmVyT2ZTaWRlcygpOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0bXAgPSBvdGhlci5wb2ludHNbaV0ueCAqIGF4aXMueCArIG90aGVyLnBvaW50c1tpXS55ICogYXhpcy55XG4gICAgICAgICAgICAgICAgaWYgKHRtcCA+IG1heEIpIG1heEIgPSB0bXBcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0bXAgPCBtaW5CKSBtaW5CID0gdG1wXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBjb3JyZWN0IGZvciBvZmZzZXQgKi9cbiAgICAgICAgICAgIHRtcCA9IG90aGVyLmNlbnRlci54ICogYXhpcy54ICsgb3RoZXIuY2VudGVyLnkgKiBheGlzLnlcbiAgICAgICAgICAgIG1pbkIgKz0gdG1wXG4gICAgICAgICAgICBtYXhCICs9IHRtcFxuXG4gICAgICAgICAgICAvKiB0ZXN0IGlmIGxpbmVzIGludGVyc2VjdCwgaWYgbm90LCByZXR1cm4gZmFsc2UgKi9cbiAgICAgICAgICAgIGlmIChtYXhBIDwgbWluQiB8fCBtaW5BID4gbWF4Qikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgbyA9IG1heEEgPiBtYXhCID8gbWF4QiAtIG1pbkEgOiBtYXhBIC0gbWluQlxuICAgICAgICAgICAgICAgIGlmIChvIDwgb3ZlcmxhcCkge1xuICAgICAgICAgICAgICAgICAgICBvdmVybGFwID0gb1xuICAgICAgICAgICAgICAgICAgICBzbWFsbGVzdCA9IHsgeDogYXhpcy54LCB5OiBheGlzLnkgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qIHRlc3QgcG9seWdvbiBCJ3Mgc2lkZXMgKi9cbiAgICAgICAgZm9yIChzaWRlID0gMDsgc2lkZSA8IG90aGVyLmdldE51bWJlck9mU2lkZXMoKTsgc2lkZSsrKSB7XG4gICAgICAgICAgICAvKiBnZXQgdGhlIGF4aXMgdGhhdCB3ZSB3aWxsIHByb2plY3Qgb250byAqL1xuICAgICAgICAgICAgaWYgKHNpZGUgPT0gMCkge1xuICAgICAgICAgICAgICAgIGF4aXMueCA9XG4gICAgICAgICAgICAgICAgICAgIG90aGVyLnBvaW50c1tvdGhlci5nZXROdW1iZXJPZlNpZGVzKCkgLSAxXS55IC1cbiAgICAgICAgICAgICAgICAgICAgb3RoZXIucG9pbnRzWzBdLnlcbiAgICAgICAgICAgICAgICBheGlzLnkgPVxuICAgICAgICAgICAgICAgICAgICBvdGhlci5wb2ludHNbMF0ueCAtXG4gICAgICAgICAgICAgICAgICAgIG90aGVyLnBvaW50c1tvdGhlci5nZXROdW1iZXJPZlNpZGVzKCkgLSAxXS54XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF4aXMueCA9IG90aGVyLnBvaW50c1tzaWRlIC0gMV0ueSAtIG90aGVyLnBvaW50c1tzaWRlXS55XG4gICAgICAgICAgICAgICAgYXhpcy55ID0gb3RoZXIucG9pbnRzW3NpZGVdLnggLSBvdGhlci5wb2ludHNbc2lkZSAtIDFdLnhcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyogbm9ybWFsaXplIHRoZSBheGlzICovXG4gICAgICAgICAgICB0bXAgPSBNYXRoLnNxcnQoYXhpcy54ICogYXhpcy54ICsgYXhpcy55ICogYXhpcy55KVxuICAgICAgICAgICAgYXhpcy54IC89IHRtcFxuICAgICAgICAgICAgYXhpcy55IC89IHRtcFxuXG4gICAgICAgICAgICAvKiBwcm9qZWN0IHBvbHlnb24gQSBvbnRvIGF4aXMgdG8gZGV0ZXJtaW5lIHRoZSBtaW4vbWF4ICovXG4gICAgICAgICAgICBtaW5BID0gbWF4QSA9IHRoaXMucG9pbnRzWzBdLnggKiBheGlzLnggKyB0aGlzLnBvaW50c1swXS55ICogYXhpcy55XG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgdGhpcy5nZXROdW1iZXJPZlNpZGVzKCk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRtcCA9IHRoaXMucG9pbnRzW2ldLnggKiBheGlzLnggKyB0aGlzLnBvaW50c1tpXS55ICogYXhpcy55XG4gICAgICAgICAgICAgICAgaWYgKHRtcCA+IG1heEEpIG1heEEgPSB0bXBcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0bXAgPCBtaW5BKSBtaW5BID0gdG1wXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBjb3JyZWN0IGZvciBvZmZzZXQgKi9cbiAgICAgICAgICAgIHRtcCA9IHRoaXMuY2VudGVyLnggKiBheGlzLnggKyB0aGlzLmNlbnRlci55ICogYXhpcy55XG4gICAgICAgICAgICBtaW5BICs9IHRtcFxuICAgICAgICAgICAgbWF4QSArPSB0bXBcblxuICAgICAgICAgICAgLyogcHJvamVjdCBwb2x5Z29uIEIgb250byBheGlzIHRvIGRldGVybWluZSB0aGUgbWluL21heCAqL1xuICAgICAgICAgICAgbWluQiA9IG1heEIgPVxuICAgICAgICAgICAgICAgIG90aGVyLnBvaW50c1swXS54ICogYXhpcy54ICsgb3RoZXIucG9pbnRzWzBdLnkgKiBheGlzLnlcbiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCBvdGhlci5nZXROdW1iZXJPZlNpZGVzKCk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRtcCA9IG90aGVyLnBvaW50c1tpXS54ICogYXhpcy54ICsgb3RoZXIucG9pbnRzW2ldLnkgKiBheGlzLnlcbiAgICAgICAgICAgICAgICBpZiAodG1wID4gbWF4QikgbWF4QiA9IHRtcFxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRtcCA8IG1pbkIpIG1pbkIgPSB0bXBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIGNvcnJlY3QgZm9yIG9mZnNldCAqL1xuICAgICAgICAgICAgdG1wID0gb3RoZXIuY2VudGVyLnggKiBheGlzLnggKyBvdGhlci5jZW50ZXIueSAqIGF4aXMueVxuICAgICAgICAgICAgbWluQiArPSB0bXBcbiAgICAgICAgICAgIG1heEIgKz0gdG1wXG5cbiAgICAgICAgICAgIC8qIHRlc3QgaWYgbGluZXMgaW50ZXJzZWN0LCBpZiBub3QsIHJldHVybiBmYWxzZSAqL1xuICAgICAgICAgICAgaWYgKG1heEEgPCBtaW5CIHx8IG1pbkEgPiBtYXhCKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBvID0gbWF4QSA+IG1heEIgPyBtYXhCIC0gbWluQSA6IG1heEEgLSBtaW5CXG4gICAgICAgICAgICAgICAgaWYgKG8gPCBvdmVybGFwKSB7XG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXAgPSBvXG4gICAgICAgICAgICAgICAgICAgIHNtYWxsZXN0ID0geyB4OiBheGlzLngsIHk6IGF4aXMueSB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG92ZXJsYXA6IG92ZXJsYXAgKyAwLjAwMSwgYXhpczogc21hbGxlc3QgfVxuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tUG9pbnRzKHBvaW50cykge1xuICAgICAgICBsZXQgbWluID0geyB4OiBOdW1iZXIuTUFYX1ZBTFVFLCB5OiBOdW1iZXIuTUFYX1ZBTFVFIH1cbiAgICAgICAgbGV0IG1heCA9IHsgeDogTnVtYmVyLk1JTl9WQUxVRSwgeTogTnVtYmVyLk1JTl9WQUxVRSB9XG4gICAgICAgIGZvciAobGV0IHAgb2YgcG9pbnRzKSB7XG4gICAgICAgICAgICBtaW4ueCA9IE1hdGgubWluKHAueCwgbWluLngpXG4gICAgICAgICAgICBtYXgueCA9IE1hdGgubWF4KHAueCwgbWF4LngpXG4gICAgICAgICAgICBtaW4ueSA9IE1hdGgubWluKHAueSwgbWluLnkpXG4gICAgICAgICAgICBtYXgueSA9IE1hdGgubWF4KHAueSwgbWF4LnkpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNlbnRlciA9IFBvaW50cy5tZWFuKG1pbiwgbWF4KVxuICAgICAgICBsZXQgcG9seWdvbiA9IG5ldyBQb2x5Z29uKGNlbnRlcilcbiAgICAgICAgZm9yIChsZXQgcCBvZiBwb2ludHMpIHtcbiAgICAgICAgICAgIHBvbHlnb24uYWRkQWJzb2x1dGVQb2ludChwKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb2x5Z29uXG4gICAgfVxufVxuXG5cbi8qKlxuICogVXRpbCBmdW5jdGlvbnMgdG8gZGVhbCB3aXRoIERPTVJlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgUmVjdCB7XG5cblxuICAgIC8qKlxuICAgICAqIFRlc3QgaWYgYSBnaXZlbiBwb2ludCBpcyBjb250YWluZWQgYnkgdGhlIHByb3ZpZGVkIFJlY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtET01SZWN0fSByZWN0IC0gUmVjdGFuZ2xlIHRvIGNoZWNrIHRoZSBjb2xsaXNpb24gd2l0aC5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwb2ludCAtIFBvaW50IHRoYXQgc2hvdWxkIGJlIHRlc3RlZC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBUcnVlIGlmIHBvaW50IGlzIGluc2lkZSBvZiByZWN0LCBvdGhlcndpc2UgZmFsc2UuXG4gICAgICogQG1lbWJlcm9mIFJlY3RcbiAgICAgKi9cbiAgICBzdGF0aWMgY29udGFpbnMocmVjdCwgcG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIChwb2ludC54ID4gcmVjdC5sZWZ0ICYmXG4gICAgICAgICAgICBwb2ludC54IDwgcmVjdC54ICsgcmVjdC5yaWdodFxuICAgICAgICAgICAgJiYgcG9pbnQueSA+IHJlY3QudG9wICYmIHBvaW50LnkgPCByZWN0LmJvdHRvbSlcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqUmV0dXJucyB0aGUgcG9zaXRpb24gb2YgYW4gcmVjdCBhcyBwb2ludCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtSZWN0fSByZWN0IC0gVGhlIHJlY3RhbmdsZSB3ZSB3YW50IHRvIGdldCB0aGUgcG9zaXRpb24gZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7UG9pbnR9IC0gUmV0dXJucyB0aGUgcG9zaXRpb24gYXMgUG9pbnQuXG4gICAgICogQG1lbWJlcm9mIFJlY3RcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UG9zaXRpb24ocmVjdCkge1xuICAgICAgICByZXR1cm4geyB4OiByZWN0LngsIHk6IHJlY3QueSB9XG4gICAgfVxufVxuXG4vKiogU3RyaW5nIHV0aWxpdHkgZnVuY3Rpb25zICovXG5cbmV4cG9ydCBjbGFzcyBTdHJpbmdzIHtcblxuICAgIHN0YXRpYyB0b1VwcGVyQ2FzZUZpcnN0Q2hhcihzdHIpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5zdWJzdHIoMCwgMSkudG9VcHBlckNhc2UoKSArIHN0ci5zdWJzdHIoMSlcbiAgICB9XG5cbiAgICBzdGF0aWMgdG9Mb3dlckNhc2VGaXJzdENoYXIoc3RyKSB7XG4gICAgICAgIHJldHVybiBzdHIuc3Vic3RyKDAsIDEpLnRvTG93ZXJDYXNlKCkgKyBzdHIuc3Vic3RyKDEpXG4gICAgfVxuXG4gICAgc3RhdGljIHRvVXBwZXJDYXNlRWFjaFdvcmQoc3RyLCBkZWxpbSA9ICcgJykge1xuICAgICAgICByZXR1cm4gc3RyLnNwbGl0KGRlbGltKS5tYXAoKHYpID0+IHYudG9VcHBlckNhc2VGaXJzdENoYXIoKSkuam9pbihkZWxpbSlcbiAgICB9XG5cbiAgICBzdGF0aWMgdG9Mb3dlckNhc2VFYWNoV29yZChzdHIsIGRlbGltID0gJyAnKSB7XG4gICAgICAgIHJldHVybiBzdHIuc3BsaXQoZGVsaW0pLm1hcCgodikgPT4gdi50b0xvd2VyQ2FzZUZpcnN0Q2hhcigpKS5qb2luKGRlbGltKVxuICAgIH1cblxufVxuXG5cblxuIiwiLyogZ2xvYmFsIGFwb2xsbywgc3Vic2NyaXB0aW9ucywgZ3FsICovXG5cbmltcG9ydCBUaGVtZSBmcm9tICcuL3RoZW1lLmpzJ1xuaW1wb3J0IFByb2dyZXNzIGZyb20gJy4vcHJvZ3Jlc3MuanMnXG5pbXBvcnQgTW9kYWwgZnJvbSAnLi9tb2RhbC5qcydcbmltcG9ydCBNZXNzYWdlIGZyb20gJy4vbWVzc2FnZS5qcydcbmltcG9ydCB7ZGVib3VuY2V9IGZyb20gJy4uL3V0aWxzLmpzJ1xuXG4vKipcbiAqIEEgc3BlY2lhbCBJbnRlcmFjdGlvbk1hbmFnZXIgZm9yIGZ1bGxzY3JlZW4gYXBwcywgd2hpY2ggbWF5XG4gKiBnbyBiZXlvbmQgdGhlIGxpbWl0cyBvZiBXZWJHTCBkcmF3aW5nIGJ1ZmZlcnMuIE9uIFNhZmFyaSBhbmQgQ2hyb21lXG4gKiB0aGUgZHJhd2luZyBidWZmZXJzIGFyZSBsaW1pdGVkIHRvIDQwOTYgaW4gd2lkdGggKFNhZmFyaSkgb3IgNDA5Nng0MDk2XG4gKiBpbiB0b3RhbCBidWZmZXIgc2l6ZSAoQ2hyb21lKS4gVGhlIG9yaWdpbmFsIEludGVyYWN0aW9uTWFuYWdlci5tYXBQb3NpdGlvblRvUG9pbnRcbiAqIGRvZXMgbm90IHdvcmsgd2l0aCB0aGVzZSBleHRyZW1lIHNpemVzIHdoaWNoIG1haW5seSBvY2N1ciBpZiBsYXJnZVxuICogcmV0aW5hIGRpc3BsYXlzICg+PSA0SykgYXJlIHVzZWQgd2l0aCBkZXZpY2VQaXhlbFJhdGlvID4gMS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBQSVhJLmludGVyYWN0aW9uLkludGVyYWN0aW9uTWFuYWdlclxuICogQHNlZSB7QGxpbmsgaHR0cDovL3BpeGlqcy5kb3dubG9hZC9kZXYvZG9jcy9QSVhJLmludGVyYWN0aW9uLkludGVyYWN0aW9uTWFuYWdlci5odG1sfFBJWEkuaW50ZXJhY3Rpb24uSW50ZXJhY3Rpb25NYW5hZ2VyfVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjk3MTA2OTYvd2ViZ2wtZHJhd2luZy1idWZmZXItc2l6ZS1kb2VzLW5vdC1lcXVhbC1jYW52YXMtc2l6ZX1cbiAqL1xuY2xhc3MgRnVsbHNjcmVlbkludGVyYWN0aW9uTWFuYWdlciBleHRlbmRzIFBJWEkuaW50ZXJhY3Rpb24uSW50ZXJhY3Rpb25NYW5hZ2VyIHtcblxuICAgIG1hcFBvc2l0aW9uVG9Qb2ludChwb2ludCwgeCwgeSkge1xuICAgICAgICBsZXQgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZXIucmVzb2x1dGlvblxuICAgICAgICBsZXQgZXh0ZW5kV2lkdGggPSAxLjBcbiAgICAgICAgbGV0IGV4dGVuZEhlaWdodCA9IDEuMFxuICAgICAgICBsZXQgZHkgPSAwXG4gICAgICAgIGxldCBjYW52YXMgPSB0aGlzLnJlbmRlcmVyLnZpZXdcbiAgICAgICAgbGV0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKVxuICAgICAgICBpZiAoY29udGV4dC5kcmF3aW5nQnVmZmVyV2lkdGggPCBjYW52YXMud2lkdGggfHxcbiAgICAgICAgICAgIGNvbnRleHQuZHJhd2luZ0J1ZmZlckhlaWdodCA8IGNhbnZhcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIGV4dGVuZFdpZHRoID0gY29udGV4dC5kcmF3aW5nQnVmZmVyV2lkdGggLyBjYW52YXMud2lkdGhcbiAgICAgICAgICAgIGV4dGVuZEhlaWdodCA9IGNvbnRleHQuZHJhd2luZ0J1ZmZlckhlaWdodCAvIGNhbnZhcy5oZWlnaHRcbiAgICAgICAgICAgIC8vZHggPSB3YW50ZWRXaWR0aCAtIGNvbnRleHQuZHJhd2luZ0J1ZmZlcldpZHRoXG4gICAgICAgICAgICBkeSA9IChjYW52YXMuaGVpZ2h0IC0gY29udGV4dC5kcmF3aW5nQnVmZmVySGVpZ2h0KSAvIHJlc29sdXRpb25cbiAgICAgICAgfVxuICAgICAgICB4ICo9IGV4dGVuZFdpZHRoXG4gICAgICAgIHkgKj0gZXh0ZW5kSGVpZ2h0XG5cbiAgICAgICAgc3VwZXIubWFwUG9zaXRpb25Ub1BvaW50KHBvaW50LCB4LCB5ICsgZHkpXG4gICAgfVxufVxuXG4vKipcbiAqIFRoZSBjbGFzcyBQaXhpQXBwIGV4dGVuZHMgdGhlIGNsYXNzIFBJWEkuQXBwbGljYXRpb25cbiAqIGJ5IHNldmVyYWwgZnVuY3Rpb25zIGFuZCBtYWtlcyBtZWFuaW5nZnVsIHByZS1hc3N1bXB0aW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBhcHBcbiAqIGNvbnN0IGFwcCA9IG5ldyBQSVhJQXBwKHtcbiAqICAgICB2aWV3OiBjYW52YXMsXG4gKiAgICAgd2lkdGg6IDQ1MCxcbiAqICAgICBoZWlnaHQ6IDE1MCxcbiAqICAgICBmcHNMb2dnaW5nOiB0cnVlLFxuICogICAgIHRoZW1lOiAnbGlnaHQnLFxuICogICAgIHRyYW5zcGFyZW50OiBmYWxzZVxuICogfSkuc2V0dXAoKS5ydW4oKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5BcHBsaWNhdGlvblxuICogQHNlZSB7QGxpbmsgaHR0cDovL3BpeGlqcy5kb3dubG9hZC9kZXYvZG9jcy9QSVhJLkFwcGxpY2F0aW9uLmh0bWx8UElYSS5BcHBsaWNhdGlvbn1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUElYSUFwcCBleHRlbmRzIFBJWEkuQXBwbGljYXRpb24ge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFBpeGlBcHAuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHM9e31dIC0gQW4gb3B0aW9ucyBvYmplY3QuIFRoZSBmb2xsb3dpbmcgb3B0aW9ucyBjYW4gYmUgc2V0OlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy53aWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIHJlbmRlcmVyLiBJZiBubyBzZXQsIHRoZSBhcHBsaWNhdGlvbiB3aWxsIHJ1biBpbiBmdWxsc2NyZWVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5oZWlnaHRdIC0gVGhlIGhlaWdodCBvZiB0aGUgcmVuZGVyZXIuIElmIG5vIHNldCwgdGhlIGFwcGxpY2F0aW9uIHdpbGwgcnVuIGluIGZ1bGxzY3JlZW4uXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW29wdHMudmlld10gLSBUaGUgY2FudmFzIEhUTUwgZWxlbWVudC4gSWYgbm90IHNldCwgYSByZW5kZXItZWxlbWVudCBpcyBhZGRlZCBpbnNpZGUgdGhlIGJvZHkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy50cmFuc3BhcmVudD10cnVlXSAtIFNob3VsZCB0aGUgcmVuZGVyIHZpZXcgYmUgdHJhbnNwYXJlbnQ/XG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5hbnRpYWxpYXM9dHJ1ZV0gLSBTZXRzIGFudGlhbGlhcyAob25seSBhcHBsaWNhYmxlIGluIGNocm9tZSBhdCB0aGUgbW9tZW50KS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMucmVzb2x1dGlvbj13aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8IDFdIC0gVGhlIHJlc29sdXRpb24gLyBkZXZpY2UgcGl4ZWwgcmF0aW8gb2YgdGhlIHJlbmRlcmVyLCByZXRpbmEgd291bGQgYmUgMi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmF1dG9SZXNpemU9dHJ1ZV0gLSBTaG91bGQgdGhlIGNhbnZhcy1lbGVtZW50IGJlIHJlc2l6ZWQgYXV0b21hdGljYWxseSBpZiB0aGUgcmVzb2x1dGlvbiB3YXMgc2V0P1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5iYWNrZ3JvdW5kQ29sb3I9MHgyODI4MjhdIC0gVGhlIGNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFRoZW1lfSBbb3B0cy50aGVtZT1kYXJrXSAtIFRoZSBuYW1lIG9mIHRoZSB0aGVtZSAoZGFyaywgbGlnaHQsIHJlZCkgb3IgYSBUaGVtZSBvYmplY3QgdG8gdXNlIGZvciBzdHlsaW5nLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZnBzTG9nZ2luZz1mYWxzZV0gLSBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGN1cnJlbnQgZnJhbWVzIHBlciBzZWNvbmQgYXJlIGRpc3BsYXllZCBpbiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzLnByb2dyZXNzPXt9XSAtIENhbiBiZSB1c2VkIHRvIGFkZCBvcHRpb25zIHRvIHRoZSBwcm9ncmVzcyBiYXIuIFNlZSBjbGFzcyBQcm9ncmVzcyBmb3IgbW9yZSBpbmZvcm1hdGlvbnMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5mb3JjZUNhbnZhcz1mYWxzZV0gLSBQcmV2ZW50cyBzZWxlY3Rpb24gb2YgV2ViR0wgcmVuZGVyZXIsIGV2ZW4gaWYgc3VjaCBpcyBwcmVzZW50LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMucm91bmRQaXhlbHM9dHJ1ZV0gLSBBbGlnbiBQSVhJLkRpc3BsYXlPYmplY3QgY29vcmRpbmF0ZXMgdG8gc2NyZWVuIHJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5tb25rZXlQYXRjaE1hcHBpbmc9dHJ1ZV0gLSBNb25rZXkgcGF0Y2ggZm9yIGNhbnZhcyBmdWxsc2NyZWVuIHN1cHBvcnQgb24gbGFyZ2UgZGlzcGxheXMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5hZGFwdGl2ZT10cnVlXSAtIEFkZHMgR3JhcGhpY3MgYWRhcHRpdmUgY2FsY3VsYXRpb24gb2YgcXVhZHJhdGljIGN1cnZlIGFuZCBhcmMgc3ViZGl2aXNpb24uXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioe1xuICAgICAgICB3aWR0aCA9IG51bGwsIGhlaWdodCA9IG51bGwsIHZpZXcgPSBudWxsLFxuICAgICAgICB0cmFuc3BhcmVudCA9IHRydWUsIGJhY2tncm91bmRDb2xvciA9IDB4MjgyODI4LCB0aGVtZSA9ICdkYXJrJyxcbiAgICAgICAgYW50aWFsaWFzID0gdHJ1ZSwgcmVzb2x1dGlvbiA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEsIGF1dG9SZXNpemUgPSB0cnVlLFxuICAgICAgICBmcHNMb2dnaW5nID0gZmFsc2UsIHByb2dyZXNzID0ge30sIGZvcmNlQ2FudmFzID0gZmFsc2UsIHJvdW5kUGl4ZWxzID0gdHJ1ZSwgbW9ua2V5UGF0Y2hNYXBwaW5nID0gdHJ1ZSwgYWRhcHRpdmUgPSB0cnVlLFxuICAgICAgICBncmFwaHFsID0gZmFsc2UgfSkge1xuXG4gICAgICAgIGNvbnN0IGZ1bGxTY3JlZW4gPSAhd2lkdGggfHwgIWhlaWdodFxuXG4gICAgICAgIGlmIChmdWxsU2NyZWVuKSB7XG4gICAgICAgICAgICB3aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoXG4gICAgICAgICAgICBoZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICAgICAgfVxuXG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIHZpZXc6IHZpZXcsXG4gICAgICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICAgIHRyYW5zcGFyZW50OiB0cmFuc3BhcmVudCxcbiAgICAgICAgICAgIGFudGlhbGlhczogYW50aWFsaWFzLFxuICAgICAgICAgICAgcmVzb2x1dGlvbjogcmVzb2x1dGlvbixcbiAgICAgICAgICAgIGF1dG9SZXNpemU6IGF1dG9SZXNpemUsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIHJvdW5kUGl4ZWxzOiByb3VuZFBpeGVscyxcbiAgICAgICAgICAgIGZvcmNlQ2FudmFzOiBmb3JjZUNhbnZhc1xuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aFxuICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodFxuICAgICAgICB0aGlzLnRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyh0aGVtZSlcbiAgICAgICAgdGhpcy5mcHNMb2dnaW5nID0gZnBzTG9nZ2luZ1xuICAgICAgICB0aGlzLnByb2dyZXNzT3B0cyA9IHByb2dyZXNzXG4gICAgICAgIHRoaXMuZnVsbFNjcmVlbiA9IGZ1bGxTY3JlZW5cbiAgICAgICAgdGhpcy5vcmllbnQgPSBudWxsXG4gICAgICAgIHRoaXMub3JpZ2luYWxNYXBQb3NpdGlvblRvUG9pbnQgPSBudWxsXG4gICAgICAgIHRoaXMubW9ua2V5UGF0Y2hNYXBwaW5nID0gbW9ua2V5UGF0Y2hNYXBwaW5nXG4gICAgICAgIFBJWEkuR3JhcGhpY3MuQ1VSVkVTLmFkYXB0aXZlID0gYWRhcHRpdmVcbiAgICAgICAgdGhpcy5ncmFwaHFsID0gZ3JhcGhxbFxuICAgICAgICBpZiAoZnVsbFNjcmVlbiB8fCBhdXRvUmVzaXplKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnQXBwIGlzIGluIGZ1bGxTY3JlZW4gbW9kZSBvciBhdXRvUmVzaXplIG1vZGUnKVxuICAgICAgICAgICAgY29uc3QgcmVzaXplRGVib3VuY2VkID0gZGVib3VuY2UoZXZlbnQgPT4gdGhpcy5yZXNpemUoZXZlbnQpLCA1MClcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCByZXNpemVEZWJvdW5jZWQpXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgdGhpcy5jaGVja09yaWVudGF0aW9uLmJpbmQodGhpcykpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbmtleVBhdGNoTWFwcGluZykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1VzaW5nIG1vbmtleSBwYXRjaGVkIGNvb3JkaW5hdGUgbWFwcGluZycpXG4gICAgICAgICAgICAvLyBQbHVnZ2luIHRoZSBzcGVjaWFsaXp0aW9uIGRvZXMgbm90IHdvcmsuIE1vbmtleSBwYXRjaGluZyBkb2VzXG4gICAgICAgICAgICAvLyB0aGlzLnJlbmRlcmVyLnBsdWdpbnMuaW50ZXJhY3Rpb24gPSBuZXcgRnVsbHNjcmVlbkludGVyYWN0aW9uTWFuYWdlcih0aGlzLnJlbmRlcmVyKVxuICAgICAgICAgICAgdGhpcy5tb25rZXlQYXRjaFBpeGlNYXBwaW5nKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhIHNldHVwIG1ldGhvZCB0byBjb25zdHJ1Y3QgY29tcGxleCBzY2VuZXMsIGV0Yy4uLlxuICAgICAqIE92ZXJ3cml0ZSB0aGlzIG1ldGhvZCBpZiB5b3UgbmVlZCBhZGRpdG9uYWwgdmlld3MgYW5kIGNvbXBvbmVudHMuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtQSVhJQXBwfSBBIHJlZmVyZW5jZSB0byB0aGUgUElYSUFwcCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG4gICAgICAgIHRoaXMuc2NlbmUgPSB0aGlzLnNjZW5lRmFjdG9yeSgpXG4gICAgICAgIHRoaXMuc3RhZ2UuYWRkQ2hpbGQodGhpcy5zY2VuZSlcblxuICAgICAgICAvLyBmcHNMb2dnaW5nXG4gICAgICAgIGlmICh0aGlzLmZwc0xvZ2dpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkRnBzRGlzcGxheSgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBHcmFwaFFMXG4gICAgICAgIGlmICh0aGlzLmdyYXBocWwgJiYgdHlwZW9mIGFwb2xsbyAhPT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgICAgICAgICAgY29uc3QgbmV0d29ya0ludGVyZmFjZSA9IGFwb2xsby5jcmVhdGVOZXR3b3JrSW50ZXJmYWNlKHtcbiAgICAgICAgICAgICAgICB1cmk6ICcvZ3JhcGhxbCdcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGNvbnN0IHdzQ2xpZW50ID0gbmV3IHN1YnNjcmlwdGlvbnMuU3Vic2NyaXB0aW9uQ2xpZW50KGB3c3M6Ly8ke2xvY2F0aW9uLmhvc3RuYW1lfS9zdWJzY3JpcHRpb25zYCwge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uUGFyYW1zOiB7fVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3QgbmV0d29ya0ludGVyZmFjZVdpdGhTdWJzY3JpcHRpb25zID0gc3Vic2NyaXB0aW9ucy5hZGRHcmFwaFFMU3Vic2NyaXB0aW9ucyhcbiAgICAgICAgICAgICAgICBuZXR3b3JrSW50ZXJmYWNlLFxuICAgICAgICAgICAgICAgIHdzQ2xpZW50XG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIHRoaXMuYXBvbGxvQ2xpZW50ID0gbmV3IGFwb2xsby5BcG9sbG9DbGllbnQoe1xuICAgICAgICAgICAgICAgIG5ldHdvcmtJbnRlcmZhY2U6IG5ldHdvcmtJbnRlcmZhY2VXaXRoU3Vic2NyaXB0aW9uc1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHByb2dyZXNzXG4gICAgICAgIHRoaXMuX3Byb2dyZXNzID0gbmV3IFByb2dyZXNzKE9iamVjdC5hc3NpZ24oeyB0aGVtZTogdGhpcy50aGVtZSB9LCB0aGlzLnByb2dyZXNzT3B0cywgeyBhcHA6IHRoaXMgfSkpXG4gICAgICAgIHRoaXMuX3Byb2dyZXNzLnZpc2libGUgPSBmYWxzZVxuICAgICAgICB0aGlzLnN0YWdlLmFkZENoaWxkKHRoaXMuX3Byb2dyZXNzKVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVzdHMgd2hldGhlciB0aGUgd2lkdGggaXMgbGFyZ2VyIHRoYW4gdGhlIGhlaWdodCBvZiB0aGUgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgYXBwIGlzIGluIGxhbmRzY2FwZSBtb2RlLlxuICAgICAqL1xuICAgIG9yaWVudGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aWR0aCA+IHRoaXMuaGVpZ2h0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIG9yaWVudGF0aW9uIGFuZCBhZGFwdHMgdmlldyBzaXplIGlmIG5lY2Vzc2FyeS4gSW1wbGVtZW50cyBhXG4gICAgICogaGFuZGxlciBmb3IgdGhlIG9yaWVudGF0aW9uY2hhbmdlIGV2ZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtldmVudD19IC0gb3JpZW50YXRpb25jaGFuZ2UgZXZlbnRcbiAgICAgKi9cbiAgICBjaGVja09yaWVudGF0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMub3JpZW50YXRpb24oKVxuICAgICAgICBpZiAodmFsdWUgIT0gdGhpcy5vcmllbnQpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoMTAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcmllbnRhdGlvbkNoYW5nZWQodHJ1ZSlcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSlcbiAgICAgICAgICAgIHRoaXMub3JpZW50ID0gdmFsdWVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBpZiBjaGVja09yaWVudGF0aW9uIGRldGVjdHMgYW4gb3JpZW50YXRpb24gY2hhbmdlIGV2ZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gW2ZvcmNlPWZhbHNlXSAtIENhbGxlZCBpZiBjaGVja09yaWVudGF0aW9uIGRldGVjdHMgYW4gb3JpZW50YXRpb24gY2hhbmdlIGV2ZW50LlxuICAgICAqL1xuICAgIG9yaWVudGF0aW9uQ2hhbmdlZChmb3JjZSA9IGZhbHNlKSB7XG4gICAgICAgIGlmICh0aGlzLmV4cGFuZFJlbmRlcmVyKCkgfHwgZm9yY2UpIHtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0KClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBhZnRlciBhIHJlc2l6ZS4gRW1wdHkgbWV0aG9kIGJ1dCBjYW4gYmUgb3ZlcndyaXR0ZW4gdG9cbiAgICAgKiBhZGFwdCB0aGVpciBsYXlvdXQgdG8gdGhlIG5ldyBhcHAgc2l6ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2lkdGhdIC0gVGhlIHdpZHRoIG9mIHRoZSBhcHAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtoZWlnaHRdIC0gVGhlIGhlaWdodCBvZiB0aGUgYXBwLlxuICAgICAqL1xuICAgIGxheW91dCh3aWR0aCwgaGVpZ2h0KSB7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEcmF3cyB0aGUgZGlzcGxheSB0cmVlIG9mIHRoZSBhcHAuIFR5cGljYWxseSB0aGlzIGNhbiBiZSBkZWxlZ2F0ZWRcbiAgICAgKiB0byB0aGUgbGF5b3V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqL1xuICAgIGRyYXcoKSB7XG4gICAgICAgIHRoaXMubGF5b3V0KHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KVxuICAgIH1cblxuICAgIC8qXG4gICAgICogUnVuIHRoZSBhcHBsaWNhdGlvbi4gT3ZlcnJpZGUgdGhpcyBtZXRob2Qgd2l0aCBldmVyeXRoaW5nXG4gICAgICogdGhhdCBpcyBuZWVkZWQgdG8gbWFpbnRhaW4geW91ciBBcHAsIGUuZy4gc2V0dXAgY2FsbHMsIG1haW4gbG9vcHMsIGV0Yy5cbiAgICAgKlxuICAgICAqL1xuICAgIHJ1bigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIE92ZXJ3cml0ZSB0aGlzIGZhY3RvcnkgbWV0aG9kIGlmIHlvdXIgYXBwbGljYXRpb24gbmVlZHMgYSBzcGVjaWFsXG4gICAgICogc2NlbmUgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHJldHVybnMge1BJWEkuQ29udGFpbmVyfSAtIEEgbmV3IFBJWEkgQ29udGFpbmVyIGZvciB1c2UgYXMgYSBzY2VuZS5cbiAgICAgKi9cbiAgICBzY2VuZUZhY3RvcnkoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUElYSS5Db250YWluZXIoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgdGhlIGRpc3BsYXkgb2YgdGhlIGZyYW1lcyBwZXIgc2Vjb25kIHRvIHRoZSByZW5kZXJlciBpbiB0aGUgdXBwZXIgbGVmdCBjb3JuZXIuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtQSVhJQXBwfSAtIFJldHVybnMgdGhlIFBJWElBcHAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGFkZEZwc0Rpc3BsYXkoKSB7XG4gICAgICAgIGNvbnN0IGZwc0Rpc3BsYXkgPSBuZXcgRnBzRGlzcGxheSh0aGlzKVxuICAgICAgICB0aGlzLnN0YWdlLmFkZENoaWxkKGZwc0Rpc3BsYXkpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSByZW5kZXJlciBhcyBhbiBvYmplY3Qgd2l0aCB0aGUga2V5cyB3aWR0aCBhbmQgaGVpZ2h0LlxuICAgICAqXG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQG1lbWJlciB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4geyB3aWR0aDogdGhpcy53aWR0aCwgaGVpZ2h0OiB0aGlzLmhlaWdodCB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY2VudGVyIG9mIHRoZSByZW5kZXJlciBhcyBhbiBvYmplY3Qgd2l0aCB0aGUga2V5cyB4IGFuZCB5LlxuICAgICAqXG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQG1lbWJlciB7b2JqZWN0fVxuICAgICAqL1xuICAgIGdldCBjZW50ZXIoKSB7XG4gICAgICAgIHJldHVybiB7IHg6IHRoaXMud2lkdGggLyAyLCB5OiB0aGlzLmhlaWdodCAvIDIgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2l6ZXMgdGhlIHJlbmRlcmVyIHRvIGZpdCBpbnRvIHRoZSB3aW5kb3cgb3IgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbZXZlbnRdIC0gVGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSB7b2JqZWN0PX0gW29wdHM9e31dIC0gVGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy53aWR0aD13aW5kb3cuaW5uZXJXaWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIGFwcCB0byByZXNpemUgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmhlaWdodD13aW5kb3cuaW5uZXJIZWlnaHRdIC0gVGhlIGhlaWdodCBvZiB0aGUgYXBwIHRvIHJlc2l6ZSB0by5cbiAgICAgKiBAcmV0dXJuIHtQSVhJQXBwfSAtIFJldHVybnMgdGhlIFBJWElBcHAgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHJlc2l6ZShldmVudCwgeyB3aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoLCBoZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgfSA9IHt9KSB7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aFxuICAgICAgICB0aGlzLmhlaWdodCA9IGhlaWdodFxuICAgICAgICB0aGlzLmV4cGFuZFJlbmRlcmVyKClcbiAgICAgICAgdGhpcy5sYXlvdXQod2lkdGgsIGhlaWdodClcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIkFwcC5yZXNpemVcIiwgd2lkdGgsIGhlaWdodCwgd2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lckhlaWdodCApXG4gICAgICAgIC8vIGlmICh0aGlzLnNjZW5lKSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiZ2wuZHJhd2luZ0J1ZmZlcldpZHRoXCIsIHRoaXMucmVuZGVyZXIudmlldy5nZXRDb250ZXh0KCd3ZWJnbCcpLmRyYXdpbmdCdWZmZXJXaWR0aClcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJzY2VuZVwiLCB0aGlzLnNjZW5lLnNjYWxlLCB0aGlzLnJlbmRlcmVyLCB0aGlzLnJlbmRlcmVyLmF1dG9SZXNpemUsIHRoaXMucmVuZGVyZXIucmVzb2x1dGlvbilcbiAgICAgICAgLy8gfVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEB0b2RvIFdyaXRlIHRoZSBkb2N1bWVudGF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBtb25rZXlQYXRjaFBpeGlNYXBwaW5nKCkge1xuICAgICAgICBpZiAodGhpcy5vcmlnaW5hbE1hcFBvc2l0aW9uVG9Qb2ludCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGludGVyYWN0aW9uTWFuYWdlciA9IHRoaXMucmVuZGVyZXIucGx1Z2lucy5pbnRlcmFjdGlvblxuICAgICAgICAgICAgdGhpcy5vcmlnaW5hbE1hcFBvc2l0aW9uVG9Qb2ludCA9IGludGVyYWN0aW9uTWFuYWdlci5tYXBQb3NpdGlvblRvUG9pbnRcbiAgICAgICAgICAgIGludGVyYWN0aW9uTWFuYWdlci5tYXBQb3NpdGlvblRvUG9pbnQgPSAocG9pbnQsIHgsIHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maXhlZE1hcFBvc2l0aW9uVG9Qb2ludChwb2ludCwgeCwgeSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluIHNvbWUgYnJvd3NlcnMgdGhlIGNhbnZhcyBpcyBkaXN0b3J0ZWQgaWYgdGhlIHNjcmVlbiByZXNvbHV0aW9uIGFuZCBcbiAgICAgKiBvdmVyYWxsIHNpemUgb2YgdGhlIGNhbnZhcyBleGNlZWRzIHRoZSBpbnRlcm5hbCBsaW1pdHMgKGUuZy4gNDA5NiB4IDQwOTYgcGl4ZWxzKS5cbiAgICAgKiBUbyBjb21wZW5zYXRlIHRoZXNlIGRpc3RvcnRpb25zIHdlIG5lZWQgdG8gZml4IHRoZSBtYXBwaW5nIHRvIHRoZSBhY3R1YWxcbiAgICAgKiBkcmF3aW5nIGJ1ZmZlciBjb29yZGluYXRlcy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7YW55fSBsb2NhbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHlcbiAgICAgKiBAcmV0dXJuIHt9IGludGVyYWN0aW9uTWFuYWdlci5tYXBQb3NpdGlvblRvUG9pbnRcbiAgICAgKi9cbiAgICBmaXhlZE1hcFBvc2l0aW9uVG9Qb2ludChsb2NhbCwgeCwgeSkge1xuICAgICAgICBsZXQgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZXIucmVzb2x1dGlvblxuICAgICAgICBsZXQgaW50ZXJhY3Rpb25NYW5hZ2VyID0gdGhpcy5yZW5kZXJlci5wbHVnaW5zLmludGVyYWN0aW9uXG4gICAgICAgIGxldCBleHRlbmRXaWR0aCA9IDEuMFxuICAgICAgICBsZXQgZXh0ZW5kSGVpZ2h0ID0gMS4wXG4gICAgICAgIGxldCBkeSA9IDBcbiAgICAgICAgbGV0IGNhbnZhcyA9IHRoaXMucmVuZGVyZXIudmlld1xuICAgICAgICBsZXQgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcpXG5cbiAgICAgICAgaWYgKGNvbnRleHQgIT09IG51bGwgJiYgKGNvbnRleHQuZHJhd2luZ0J1ZmZlcldpZHRoIDwgY2FudmFzLndpZHRoIHx8XG4gICAgICAgICAgICBjb250ZXh0LmRyYXdpbmdCdWZmZXJIZWlnaHQgPCBjYW52YXMuaGVpZ2h0KSkge1xuICAgICAgICAgICAgZXh0ZW5kV2lkdGggPSBjb250ZXh0LmRyYXdpbmdCdWZmZXJXaWR0aCAvIGNhbnZhcy53aWR0aFxuICAgICAgICAgICAgZXh0ZW5kSGVpZ2h0ID0gY29udGV4dC5kcmF3aW5nQnVmZmVySGVpZ2h0IC8gY2FudmFzLmhlaWdodFxuICAgICAgICAgICAgLy9keCA9IHdhbnRlZFdpZHRoIC0gY29udGV4dC5kcmF3aW5nQnVmZmVyV2lkdGhcbiAgICAgICAgICAgIGR5ID0gKGNhbnZhcy5oZWlnaHQgLSBjb250ZXh0LmRyYXdpbmdCdWZmZXJIZWlnaHQpIC8gcmVzb2x1dGlvblxuICAgICAgICB9XG4gICAgICAgIHggKj0gZXh0ZW5kV2lkdGhcbiAgICAgICAgeSAqPSBleHRlbmRIZWlnaHRcbiAgICAgICAgcmV0dXJuIHRoaXMub3JpZ2luYWxNYXBQb3NpdGlvblRvUG9pbnQuY2FsbChpbnRlcmFjdGlvbk1hbmFnZXIsIGxvY2FsLCB4LCB5ICsgZHkpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhwYW5kIHRoZSByZW5kZXJlciBzdGVwLXdpc2Ugb24gcmVzaXplLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtleHBhbmRdIC0gVGhlIGFtb3VudCBvZiBhZGRpdGlvbmFsIHNwYWNlIGZvciB0aGUgcmVuZGVyZXIgW3B4XS5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIHRoZSByZW5kZXJlciB3YXMgcmVzaXplZC5cbiAgICAgKi9cbiAgICBleHBhbmRSZW5kZXJlcihleHBhbmQgPSAyNTYpIHtcbiAgICAgICAgbGV0IHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlclxuICAgICAgICBsZXQgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZXIucmVzb2x1dGlvblxuICAgICAgICBsZXQgd3cgPSB0aGlzLndpZHRoXG4gICAgICAgIGxldCBoaCA9IHRoaXMuaGVpZ2h0XG4gICAgICAgIGxldCBzdyA9IHRoaXMuc2NyZWVuLndpZHRoXG4gICAgICAgIGxldCBzaCA9IHRoaXMuc2NyZWVuLmhlaWdodFxuICAgICAgICBpZiAod3cgPiBzdyB8fCBoaCA+IHNoKSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdBcHAuZXhwYW5kUmVuZGVyZXInKVxuICAgICAgICAgICAgcmVuZGVyZXIucmVzaXplKHd3ICsgZXhwYW5kLCBoaCArIGV4cGFuZClcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICByZW5kZXJlci5yZXNpemUod3csIGhoKVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvYWRpbmcgcHJvZ3Jlc3Mgb2YgdGhlIGFwcGxpY2F0aW9uLiBJZiBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lLCBkaXNwbGF5IHRoZSBwcm9ncmVzcyBiYXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ZhbHVlXSAtIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLiBJZiAxMDAsIHRoZSBwcm9ncmVzcyBiYXIgd2lsbCBkaXNhcHBlYXIuXG4gICAgICogQHJldHVybiB7UElYSUFwcHxQcm9ncmVzc30gVGhlIFBpeGlBcHAgb2JqZWN0IGZvciBjaGFpbmluZyBvciB0aGUgUHJvZ3Jlc3Mgb2JqZWN0IHdoZW4gdGhlIG1ldGhvZCB3YXNcbiAgICAgKiAgICAgY2FsbGVkIHdpdGhvdXQgYSBwYXJhbWV0ZXIuXG4gICAgICovXG4gICAgcHJvZ3Jlc3ModmFsdWUpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2dyZXNzXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcm9ncmVzcy52aXNpYmxlID0gdHJ1ZVxuICAgICAgICB0aGlzLl9wcm9ncmVzcy5wcm9ncmVzcyA9IHZhbHVlXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyBhIG5ldyBNb2RhbCBvYmplY3QgYmluZGVkIHRvIHRoaXMgYXBwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IGZvciB0aGUgTW9kYWwgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge01vZGFsfSBSZXR1cm5zIHRoZSBNb2RhbCBvYmplY3QuXG4gICAgICovXG4gICAgbW9kYWwob3B0cyA9IHt9KSB7XG5cbiAgICAgICAgbGV0IG1vZGFsID0gbmV3IE1vZGFsKE9iamVjdC5hc3NpZ24oeyB0aGVtZTogdGhpcy50aGVtZSB9LCBvcHRzLCB7IGFwcDogdGhpcyB9KSlcbiAgICAgICAgdGhpcy5zY2VuZS5hZGRDaGlsZChtb2RhbClcblxuICAgICAgICByZXR1cm4gbW9kYWxcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyBhIG5ldyBNZXNzYWdlIG9iamVjdCBiaW5kZWQgdG8gdGhpcyBhcHAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgZm9yIHRoZSBNZXNzYWdlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtNZXNzYWdlfSBSZXR1cm5zIHRoZSBNZXNzYWdlIG9iamVjdC5cbiAgICAgKi9cbiAgICBtZXNzYWdlKG9wdHMgPSB7fSkge1xuXG4gICAgICAgIGxldCBtZXNzYWdlID0gbmV3IE1lc3NhZ2UoT2JqZWN0LmFzc2lnbih7IHRoZW1lOiB0aGlzLnRoZW1lIH0sIG9wdHMsIHsgYXBwOiB0aGlzIH0pKVxuICAgICAgICB0aGlzLnNjZW5lLmFkZENoaWxkKG1lc3NhZ2UpXG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2FkcyBzcHJpdGVzLCBlLmcuIGltYWdlcyBpbnRvIHRoZSBQSVhJIFRleHR1cmVDYWNoZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfHN0cmluZ1tdfSByZXNvdXJjZXMgLSBBIFN0cmluZyBvciBhbiBBcnJheSBvZiB1cmxzIHRvIHRoZSBpbWFnZXMgdG8gbG9hZC5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbbG9hZGVkXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgZXhlY3V0ZWQgYWZ0ZXIgYWxsIHJlc291cmNlcyBoYXMgYmVlbiBsb2FkZWQuXG4gICAgICogICAgIFJlY2VpdmVzIG9uZSBwYXJhbXRlciwgYSBNYXAgb2Ygc3ByaXRlcyB3aGVyZSB0aGUga2V5IGlzIHRoZSBwYXRoIG9mIHRoZSBpbWFnZSB3aGljaCB3YXNcbiAgICAgKiAgICAgbG9hZGVkIGFuZCB0aGUgdmFsdWUgaXMgdGhlIFBJWEkuU3ByaXRlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgZm9yIG1vcmUgc3BlY2lmaWMgcGFyYW1ldGVycy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnJlc29sdXRpb25EZXBlbmRlbnQ9dHJ1ZV0gLSBTaG91bGQgdGhlIHNwcml0ZXMgYmUgbG9hZGVkIGRlcGVuZGVudCBvZiB0aGVcbiAgICAgKiAgICAgcmVuZGVyZXIgcmVzb2x1dGlvbj9cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnByb2dyZXNzPWZhbHNlXSAtIFNob3VsZCBhIHByb2dyZXNzIGJhciBkaXNwbGF5IHRoZSBsb2FkaW5nIHN0YXR1cz9cbiAgICAgKiBAcmV0dXJuIHtQSVhJQXBwfSBUaGUgUElYSUFwcCBvYmplY3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxvYWRTcHJpdGVzKHJlc291cmNlcywgbG9hZGVkID0gbnVsbCwgeyByZXNvbHV0aW9uRGVwZW5kZW50ID0gdHJ1ZSwgcHJvZ3Jlc3MgPSBmYWxzZSB9ID0ge30pIHtcblxuICAgICAgICB0aGlzLmxvYWRUZXh0dXJlcyhyZXNvdXJjZXMsIHRleHR1cmVzID0+IHtcblxuICAgICAgICAgICAgbGV0IHNwcml0ZXMgPSBuZXcgTWFwKClcblxuICAgICAgICAgICAgZm9yIChsZXQgW2tleSwgdGV4dHVyZV0gb2YgdGV4dHVyZXMpIHtcbiAgICAgICAgICAgICAgICBzcHJpdGVzLnNldChrZXksIG5ldyBQSVhJLlNwcml0ZSh0ZXh0dXJlKSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGxvYWRlZCkge1xuICAgICAgICAgICAgICAgIGxvYWRlZC5jYWxsKHRoaXMsIHNwcml0ZXMpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSwgeyByZXNvbHV0aW9uRGVwZW5kZW50LCBwcm9ncmVzcyB9KVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgdGV4dHVyZXMsIGUuZy4gaW1hZ2VzIGludG8gdGhlIFBJWEkgVGV4dHVyZUNhY2hlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IHJlc291cmNlcyAtIEEgU3RyaW5nIG9yIGFuIEFycmF5IG9mIHVybHMgdG8gdGhlIGltYWdlcyB0byBsb2FkLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtsb2FkZWRdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBleGVjdXRlZCBhZnRlciBhbGwgcmVzb3VyY2VzIGhhcyBiZWVuIGxvYWRlZC5cbiAgICAgKiAgICAgUmVjZWl2ZXMgb25lIHBhcmFtdGVyLCBhIE1hcCBvZiB0ZXh0dXJlcyB3aGVyZSB0aGUga2V5IGlzIHRoZSBwYXRoIG9mIHRoZSBpbWFnZSB3aGljaCB3YXNcbiAgICAgKiAgICAgbG9hZGVkIGFuZCB0aGUgdmFsdWUgaXMgdGhlIFBJWEkuVGV4dHVyZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IGZvciBtb3JlIHNwZWNpZmljIHBhcmFtZXRlcnMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5yZXNvbHV0aW9uRGVwZW5kZW50PXRydWVdIC0gU2hvdWxkIHRoZSB0ZXh0dXJlcyBiZSBsb2FkZWQgZGVwZW5kZW50IG9mIHRoZVxuICAgICAqICAgICByZW5kZXJlciByZXNvbHV0aW9uP1xuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMucHJvZ3Jlc3M9ZmFsc2VdIC0gU2hvdWxkIGEgcHJvZ3Jlc3MgYmFyIGRpc3BsYXkgdGhlIGxvYWRpbmcgc3RhdHVzP1xuICAgICAqIEByZXR1cm4ge1BJWElBcHB9IFRoZSBQSVhJQXBwIG9iamVjdCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgbG9hZFRleHR1cmVzKHJlc291cmNlcywgbG9hZGVkID0gbnVsbCwgeyByZXNvbHV0aW9uRGVwZW5kZW50ID0gdHJ1ZSwgcHJvZ3Jlc3MgPSBmYWxzZSB9ID0ge30pIHtcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVzb3VyY2VzKSkge1xuICAgICAgICAgICAgcmVzb3VyY2VzID0gW3Jlc291cmNlc11cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxvYWRlciA9IHRoaXMubG9hZGVyXG5cbiAgICAgICAgZm9yIChsZXQgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSB7XG5cbiAgICAgICAgICAgIGlmICghbG9hZGVyLnJlc291cmNlc1tyZXNvdXJjZV0pIHtcblxuICAgICAgICAgICAgICAgIGlmIChyZXNvbHV0aW9uRGVwZW5kZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXNvbHV0aW9uID0gTWF0aC5yb3VuZCh0aGlzLnJlbmRlcmVyLnJlc29sdXRpb24pXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocmVzb2x1dGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlci5hZGQocmVzb3VyY2UsIHJlc291cmNlLnJlcGxhY2UoL1xcLihbXi5dKikkLywgJ0AyeC4kMScpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVyLmFkZChyZXNvdXJjZSwgcmVzb3VyY2UucmVwbGFjZSgvXFwuKFteLl0qKSQvLCAnQDN4LiQxJykpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVyLmFkZChyZXNvdXJjZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVyLmFkZChyZXNvdXJjZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGxvYWRlci5vbigncHJvZ3Jlc3MnLCBlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2dyZXNzKGUucHJvZ3Jlc3MpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgbG9hZGVyLmxvYWQoKGxvYWRlciwgcmVzb3VyY2VzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0dXJlcyA9IG5ldyBNYXAoKVxuXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gcmVzb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgdGV4dHVyZXMuc2V0KGtleSwgcmVzb3VyY2VzW2tleV0udGV4dHVyZSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGxvYWRlZCkge1xuICAgICAgICAgICAgICAgIGxvYWRlZC5jYWxsKHRoaXMsIHRleHR1cmVzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUXVlcmllcyB0aGUgR3JhcGhRTCBlbmRwb2ludC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbcXVlcnldIC0gVGhlIEdyYXBoUUwgcXVlcnkgc3RyaW5nLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cz17fV0gLSBBbiBvcHRpb25zIG9iamVjdC4gVGhlIGZvbGxvd2luZyBvcHRpb25zIGNhbiBiZSBzZXQ6XG4gICAgICogICAgIGh0dHA6Ly9kZXYuYXBvbGxvZGF0YS5jb20vY29yZS9hcG9sbG8tY2xpZW50LWFwaS5odG1sI0Fwb2xsb0NsaWVudC5xdWVyeVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9IFJldHVybnMgYSBQcm9taXNlIHdoaWNoIGlzIGVpdGhlciByZXNvbHZlZCB3aXRoIHRoZSByZXN1bHRpbmcgZGF0YSBvclxuICAgICAqICAgICByZWplY3RlZCB3aXRoIGFuIGVycm9yLlxuICAgICAqL1xuICAgIHF1ZXJ5KHF1ZXJ5LCBvcHRzID0ge30pIHtcblxuICAgICAgICBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdHMsIHsgcXVlcnkgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCBxdWVyeSlcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdHMucXVlcnkgPSBvcHRzLnF1ZXJ5LnRyaW0oKVxuXG4gICAgICAgIGlmICghb3B0cy5xdWVyeS5zdGFydHNXaXRoKCdxdWVyeScpKSB7XG4gICAgICAgICAgICBpZiAob3B0cy5xdWVyeS5zdGFydHNXaXRoKCd7JykpIHtcbiAgICAgICAgICAgICAgICBvcHRzLnF1ZXJ5ID0gYHF1ZXJ5ICR7b3B0cy5xdWVyeX1gXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG9wdHMucXVlcnkgPSBgcXVlcnkgeyR7b3B0cy5xdWVyeX19YFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgb3B0cy5xdWVyeSA9IGdxbChvcHRzLnF1ZXJ5KVxuXG4gICAgICAgIHJldHVybiB0aGlzLmFwb2xsb0NsaWVudC5xdWVyeShvcHRzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11dGF0ZSB0aGUgR3JhcGhRTCBlbmRwb2ludC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbXV0YXRpb25dIC0gVGhlIEdyYXBoUUwgbXV0YXRpb24gc3RyaW5nLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0cz17fV0gLSBBbiBvcHRpb25zIG9iamVjdC4gVGhlIGZvbGxvd2luZyBvcHRpb25zIGNhbiBiZSBzZXQ6XG4gICAgICogICAgIGh0dHA6Ly9kZXYuYXBvbGxvZGF0YS5jb20vY29yZS9hcG9sbG8tY2xpZW50LWFwaS5odG1sI0Fwb2xsb0NsaWVudC5tdXRhdGVcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfSBSZXR1cm5zIGEgUHJvbWlzZSB3aGljaCBpcyBlaXRoZXIgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0aW5nIGRhdGEgb3JcbiAgICAgKiAgICAgcmVqZWN0ZWQgd2l0aCBhbiBlcnJvci5cbiAgICAgKi9cbiAgICBtdXRhdGUobXV0YXRpb24sIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgbXV0YXRpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwgb3B0cywgeyBtdXRhdGlvbiB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIG11dGF0aW9uKVxuICAgICAgICB9XG5cbiAgICAgICAgb3B0cy5tdXRhdGlvbiA9IG9wdHMubXV0YXRpb24udHJpbSgpXG5cbiAgICAgICAgaWYgKCFvcHRzLm11dGF0aW9uLnN0YXJ0c1dpdGgoJ211dGF0aW9uJykpIHtcbiAgICAgICAgICAgIGlmIChvcHRzLm11dGF0aW9uLnN0YXJ0c1dpdGgoJ3snKSkge1xuICAgICAgICAgICAgICAgIG9wdHMubXV0YXRpb24gPSBgbXV0YXRpb24gJHtvcHRzLm11dGF0aW9ufWBcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb3B0cy5tdXRhdGlvbiA9IGBtdXRhdGlvbiB7JHtvcHRzLm11dGF0aW9ufX1gXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBvcHRzLm11dGF0aW9uID0gZ3FsKG9wdHMubXV0YXRpb24pXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBvbGxvQ2xpZW50Lm11dGF0ZShvcHRzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSB0aGUgR3JhcGhRTCBlbmRwb2ludC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3Vic2NyaXB0aW9uXSAtIFRoZSBHcmFwaFFMIHN1YnNjcmlwdGlvbi5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHM9e31dIC0gQW4gb3B0aW9ucyBvYmplY3QuIFRoZSBmb2xsb3dpbmcgb3B0aW9ucyBjYW4gYmUgc2V0OlxuICAgICAqICAgICBodHRwOi8vZGV2LmFwb2xsb2RhdGEuY29tL2NvcmUvYXBvbGxvLWNsaWVudC1hcGkuaHRtbCNBcG9sbG9DbGllbnQucXVlcnlcbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlfSBSZXR1cm5zIGEgUHJvbWlzZSB3aGljaCBpcyBlaXRoZXIgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0aW5nIGRhdGEgb3JcbiAgICAgKiAgICAgcmVqZWN0ZWQgd2l0aCBhbiBlcnJvci5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoc3Vic2NyaXB0aW9uLCBvcHRzID0ge30pIHtcblxuICAgICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRzLCB7IHN1YnNjcmlwdGlvbiB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHN1YnNjcmlwdGlvbilcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdHMuc3Vic2NyaXB0aW9uID0gb3B0cy5zdWJzY3JpcHRpb24udHJpbSgpXG5cbiAgICAgICAgaWYgKCFvcHRzLnN1YnNjcmlwdGlvbi5zdGFydHNXaXRoKCdzdWJzY3JpcHRpb24nKSkge1xuICAgICAgICAgICAgaWYgKG9wdHMuc3Vic2NyaXB0aW9uLnN0YXJ0c1dpdGgoJ3snKSkge1xuICAgICAgICAgICAgICAgIG9wdHMuc3Vic2NyaXB0aW9uID0gYHN1YnNjcmlwdGlvbiAke29wdHMuc3Vic2NyaXB0aW9ufWBcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb3B0cy5zdWJzY3JpcHRpb24gPSBgc3Vic2NyaXB0aW9uIHske29wdHMuc3Vic2NyaXB0aW9ufX1gXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBvcHRzLnF1ZXJ5ID0gZ3FsKG9wdHMuc3Vic2NyaXB0aW9uKVxuXG4gICAgICAgIGRlbGV0ZSBvcHRzLnN1YnNjcmlwdGlvblxuXG4gICAgICAgIHJldHVybiB0aGlzLmFwb2xsb0NsaWVudC5zdWJzY3JpYmUob3B0cylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdXBwb3J0cyB0aGUgcGFnZSBhcyBhIGdsb2JhbCBjb29yZGluYXRlIHN5c3RlbSBhbmQgY29udmVydHMgYnJvd3NlciBwYWdlIGNvb3JkaW5hdGVzXG4gICAgICogdG8gbG9jYWwgRGlzcGxheU9iamVjdCBjb29yZGluYXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RGlzcGxheU9iamVjdH0gZGlzcGxheU9iamVjdCAtIFRoZSBQSVhJIGRpc3BsYXlPYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHggLSBUaGUgeCBjb29yZGluYXRlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5IC0gVGhlIHkgY29vcmRpbmF0ZS5cbiAgICAgKiAgXG4gICAgICogQHJldHVybiB7UElYSS5Qb2ludH0gUmV0dXJucyBhIFBJWEkuUG9pbnQuXG4gICAgICovXG5cbiAgICBjb252ZXJ0UG9pbnRGcm9tUGFnZVRvTm9kZShkaXNwbGF5T2JqZWN0LCB4LCB5KSB7XG4gICAgICAgIGxldCByZXNvbHV0aW9uID0gdGhpcy5yZW5kZXJlci5yZXNvbHV0aW9uXG4gICAgICAgIGNvbnNvbGUubG9nKFwicmVzb2x1dGlvblwiLCByZXNvbHV0aW9uKVxuICAgICAgICBsZXQgcGl4aUdsb2JhbCA9IHdpbmRvdy5jb252ZXJ0UG9pbnRGcm9tUGFnZVRvTm9kZShhcHAudmlldywgeCwgeSlcbiAgICAgICAgcGl4aUdsb2JhbC54IC89IHJlc29sdXRpb25cbiAgICAgICAgcGl4aUdsb2JhbC55IC89IHJlc29sdXRpb25cbiAgICAgICAgcmV0dXJuIGRpc3BsYXlPYmplY3QudG9Mb2NhbChuZXcgUElYSS5Qb2ludChwaXhpR2xvYmFsLngsIHBpeGlHbG9iYWwueSkpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3VwcG9ydHMgdGhlIHBhZ2UgYXMgYSBnbG9iYWwgY29vcmRpbmF0ZSBzeXN0ZW0gYW5kIGNvbnZlcnRzIGxvY2FsIERpc3BsYXlPYmplY3QgY29vcmRpbmF0ZXNcbiAgICAgKiB0byBicm93c2VyIHBhZ2UgY29vcmRpbmF0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Rpc3BsYXlPYmplY3R9IGRpc3BsYXlPYmplY3QgLSBUaGUgUElYSSBkaXNwbGF5T2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4IC0gVGhlIHggY29vcmRpbmF0ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0geSAtIFRoZSB5IGNvb3JkaW5hdGUuXG4gICAgICogIFxuICAgICAqIEByZXR1cm4ge1BvaW50fSBSZXR1cm5zIGEgRE9NIFBvaW50LlxuICAgICAqL1xuXG4gICAgY29udmVydFBvaW50RnJvbU5vZGVUb1BhZ2UoZGlzcGxheU9iamVjdCwgeCwgeSkge1xuICAgICAgICBsZXQgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZXIucmVzb2x1dGlvblxuICAgICAgICBsZXQgcGl4aUdsb2JhbCA9IGRpc3BsYXlPYmplY3QudG9HbG9iYWwobmV3IFBJWEkuUG9pbnQoeCwgeSkpXG4gICAgICAgIHBpeGlHbG9iYWwueCAqPSByZXNvbHV0aW9uXG4gICAgICAgIHBpeGlHbG9iYWwueSAqPSByZXNvbHV0aW9uXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiYXBwLmNvbnZlcnRQb2ludEZyb21Ob2RlVG9QYWdlXCIsIHBpeGlHbG9iYWwpXG4gICAgICAgIHJldHVybiB3aW5kb3cuY29udmVydFBvaW50RnJvbU5vZGVUb1BhZ2UoYXBwLnZpZXcsIHBpeGlHbG9iYWwueCwgcGl4aUdsb2JhbC55KVxuICAgIH1cbn1cblxuLyoqXG4gKiBUaGUgY2xhc3MgZnBzZGlzcGxheSBzaG93cyBpbiB0aGUgdXBwZXIgbGVmdCBjb3JuZXJcbiAqIG9mIHRoZSByZW5kZXJlciB0aGUgY3VycmVudCBpbWFnZSByZWZyZXNoIHJhdGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5HcmFwaGljc1xuICogQHNlZSB7QGxpbmsgaHR0cDovL3BpeGlqcy5kb3dubG9hZC9kZXYvZG9jcy9QSVhJLkdyYXBoaWNzLmh0bWx8UElYSS5HcmFwaGljc31cbiAqL1xuY2xhc3MgRnBzRGlzcGxheSBleHRlbmRzIFBJWEkuR3JhcGhpY3Mge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIEZwc0Rpc3BsYXkuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1BJWElBcHB9IGFwcCAtIFRoZSBQSVhJQXBwIHdoZXJlIHRoZSBmcmFtZXMgcGVyIHNlY29uZCBzaG91bGQgYmUgZGlzcGxheWVkLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGFwcCkge1xuXG4gICAgICAgIHN1cGVyKClcblxuICAgICAgICB0aGlzLmFwcCA9IGFwcFxuXG4gICAgICAgIHRoaXMubGluZVN0eWxlKDMsIDB4NDM0ZjRmLCAxKVxuICAgICAgICAgICAgLmJlZ2luRmlsbCgweDQzNGY0ZiwgLjYpXG4gICAgICAgICAgICAuZHJhd1JvdW5kZWRSZWN0KDAsIDAsIDY4LCAzMiwgNSlcbiAgICAgICAgICAgIC5lbmRGaWxsKClcbiAgICAgICAgICAgIC5wb3NpdGlvbi5zZXQoMjAsIDIwKVxuXG4gICAgICAgIHRoaXMudGV4dCA9IG5ldyBQSVhJLlRleHQodGhpcy5mcHMsIG5ldyBQSVhJLlRleHRTdHlsZSh7XG4gICAgICAgICAgICBmb250RmFtaWx5OiAnQXJpYWwnLFxuICAgICAgICAgICAgZm9udFNpemU6IDE0LFxuICAgICAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnLFxuICAgICAgICAgICAgZmlsbDogJyNmNmY2ZjYnLFxuICAgICAgICAgICAgc3Ryb2tlOiAnIzQzNGY0ZicsXG4gICAgICAgICAgICBzdHJva2VUaGlja25lc3M6IDNcbiAgICAgICAgfSkpXG4gICAgICAgIHRoaXMudGV4dC5wb3NpdGlvbi5zZXQoNiwgNilcblxuICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMudGV4dClcblxuICAgICAgICB0aGlzLnJlZnJlc2hGcHMoKVxuXG4gICAgICAgIHdpbmRvdy5zZXRJbnRlcnZhbCh0aGlzLnJlZnJlc2hGcHMuYmluZCh0aGlzKSwgMTAwMClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWZyZXNoZXMgZnBzIG51bWVyLlxuICAgICAqXG4gICAgICogQHJldHVybiB7UElYSUFwcH0gUmV0dXJucyB0aGUgUElYSUFwcCBvYmplY3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHJlZnJlc2hGcHMoKSB7XG4gICAgICAgIHRoaXMudGV4dC50ZXh0ID0gYCR7KHRoaXMuYXBwLnRpY2tlci5GUFMpLnRvRml4ZWQoMSl9IGZwc2BcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cbiIsIi8qKlxuICogQSBHYXVzc2lhbiBibHVyIGZpbHRlci4gV2l0aCB0aGlzIGZpbHRlciwgeW91IGNhbiBibHVyIGFuIGFyZWEgb2YgYSBQSVhJLkRpc3BsYXlPYmplY3QuIFRoaXMgY2Fubm90XG4gKiBiZSBkb25lIHdpdGggdGhlIFBJWEkuZmlsdGVycy5CbHVyRmlsdGVyICh3aGVuIHlvdSB1c2UgdGhlIFBJWEkuZmlsdGVycy5CbHVyRmlsdGVyIHdpdGhcbiAqIGFuIGZpbHRlciBhcmVhLCBhbGwgcGl4ZWxzIG91dHNpZGUgb2YgdGhlIGFyZWEgYXJlIG5vdCBkaXNwbGF5ZWQpLiBBdHRlbnRpb246IFRoZSBhcmVhIG9mXG4gKiB0aGUgZmlsdGVyIGlzIGFsd2F5cyBpbiBnbG9iYWwgc2NvcGUsIE5PVCByZWxhdGl2ZSB0byB0aGUgUElYSS5EaXNwbGF5T2JqZWN0IHRoZSBmaWx0ZXJcbiAqIGlzIGFzc2lnbmVkIHRvIVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgdGhlIGFwcFxuICogY29uc3QgYXBwID0gbmV3IFBJWElBcHAoe1xuICogICAgIHZpZXc6IGNhbnZhcyxcbiAqICAgICB3aWR0aDogNDgwLFxuICogICAgIGhlaWdodDogMjcwLFxuICogICAgIHRyYW5zcGFyZW50OiBmYWxzZVxuICogfSkuc2V0dXAoKS5ydW4oKVxuICogXG4gKiAvLyBBZGQgYSB2aWRlbyBzcHJpdGVcbiAqIGNvbnN0IHNwcml0ZSA9IG5ldyBQSVhJLlNwcml0ZShQSVhJLlRleHR1cmUuZnJvbVZpZGVvKFwiYXNzZXRzL2JsdXJmaWx0ZXIubXA0XCIpKVxuICogc3ByaXRlLndpZHRoID0gYXBwLnNpemUud2lkdGhcbiAqIHNwcml0ZS5oZWlnaHQgPSBhcHAuc2l6ZS5oZWlnaHRcbiAqIGFwcC5zY2VuZS5hZGRDaGlsZChzcHJpdGUpXG4gKiBcbiAqIC8vIENyZWF0ZSB0aGUgZmlsdGVyIGFuZCBhc3NpZ24gaXQgdG8gdGhlIHNjZW5lXG4gKiBjb25zdCBibHVyRmlsdGVyID0gbmV3IEJsdXJGaWx0ZXIobmV3IFBJWEkuUmVjdGFuZ2xlKDIwLCAyMCwgODAsIDYwKSlcbiAqIGFwcC5zY2VuZS5maWx0ZXJzID0gW2JsdXJGaWx0ZXJdXG4gKiBcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5GaWx0ZXJcbiAqIEBwYXJhbSB7UElYSS5SZWN0YW5nbGV8UElYSS5DaXJjbGV8UElYSS5EaXNwbGF5T2JqZWN0fSBzaGFwZSBUaGUgYXJlYSB3aGVyZSB0aGUgYmx1ciBlZmZlY3Qgc2hvdWxkIGJlIGFwcGxpZWQgdG8uIFJlbGF0aXZlIHRvIHRoZVxuICogICAgIGNhbnZhcywgTk9UIHJlbGF0aXZlIHRvIHRoZSBQSVhJLkRpc3BsYXlPYmplY3Qgd2hlcmUgdGhlIGJsdXIgZWZmZWN0IGlzIGFzc2lnbmVkIHRvIVxuICogQHBhcmFtIHtudW1iZXJ9IFtibHVyPTUwXSBUaGUgc3RyZW5ndGggb2YgdGhlIGJsdXIuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJsdXJGaWx0ZXIgZXh0ZW5kcyBQSVhJLkZpbHRlciB7XG4gICAgXG4gICAgY29uc3RydWN0b3Ioc2hhcGUsIGJsdXIgPSA1MCkge1xuICAgICAgICBzdXBlcigpXG5cbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IHRoaXMubm9ybWFsaXplKHNoYXBlKVxuXG4gICAgICAgIHRoaXMudGlsdFNoaWZ0WEZpbHRlciA9IG5ldyBUaWx0U2hpZnRYRmlsdGVyKG5vcm1hbGl6ZWQsIGJsdXIpXG4gICAgICAgIHRoaXMudGlsdFNoaWZ0WUZpbHRlciA9IG5ldyBUaWx0U2hpZnRZRmlsdGVyKG5vcm1hbGl6ZWQsIGJsdXIpXG4gICAgfVxuXG4gICAgYXBwbHkoZmlsdGVyTWFuYWdlciwgaW5wdXQsIG91dHB1dCkge1xuICAgICAgICBsZXQgcmVuZGVyVGFyZ2V0ID0gZmlsdGVyTWFuYWdlci5nZXRSZW5kZXJUYXJnZXQodHJ1ZSlcbiAgICAgICAgdGhpcy50aWx0U2hpZnRYRmlsdGVyLmFwcGx5KGZpbHRlck1hbmFnZXIsIGlucHV0LCByZW5kZXJUYXJnZXQpXG4gICAgICAgIHRoaXMudGlsdFNoaWZ0WUZpbHRlci5hcHBseShmaWx0ZXJNYW5hZ2VyLCByZW5kZXJUYXJnZXQsIG91dHB1dClcbiAgICAgICAgZmlsdGVyTWFuYWdlci5yZXR1cm5SZW5kZXJUYXJnZXQocmVuZGVyVGFyZ2V0KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzdHJlbmd0aCBvZiB0aGUgYmx1ci5cbiAgICAgKlxuICAgICAqIEBtZW1iZXIge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgYmx1cigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGlsdFNoaWZ0WEZpbHRlci5ibHVyXG4gICAgfVxuICAgIHNldCBibHVyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudGlsdFNoaWZ0WEZpbHRlci5ibHVyID0gdGhpcy50aWx0U2hpZnRZRmlsdGVyLmJsdXIgPSB2YWx1ZVxuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBUaGUgYmx1ciBzaGFwZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXIge1BJWEkuUmVjdGFuZ2xlfFBJWEkuQ2lyY2xlfFBJWEkuRGlzcGxheU9iamVjdH1cbiAgICAgKi9cbiAgICBnZXQgc2hhcGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRpbHRTaGlmdFhGaWx0ZXIuc2hhcGVcbiAgICB9XG4gICAgc2V0IHNoYXBlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudGlsdFNoaWZ0WEZpbHRlci5zaGFwZSA9IHRoaXMudGlsdFNoaWZ0WUZpbHRlci5zaGFwZSA9IHRoaXMubm9ybWFsaXplKHZhbHVlKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtQSVhJLlJlY3RhbmdsZXxQSVhJLkNpcmNsZXxQSVhJLkRpc3BsYXlPYmplY3R9IHZhbHVlXG4gICAgICogQHJldHVybnMge09iamVjdH1cbiAgICAgKi9cbiAgICBub3JtYWxpemUodmFsdWUpIHtcblxuICAgICAgICBsZXQgc2hhcGUgPSBudWxsXG5cbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUElYSS5DaXJjbGUpIHtcbiAgICAgICAgICAgIHNoYXBlID0ge3R5cGU6ICdjaXJjbGUnLCB4OiB2YWx1ZS54LCB5OiB2YWx1ZS55LCByOiB2YWx1ZS5yYWRpdXN9XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBQSVhJLlJlY3RhbmdsZSkge1xuICAgICAgICAgICAgc2hhcGUgPSB7dHlwZTogJ3JlY3RhbmdsZScsIHg6IHZhbHVlLngsIHk6IHZhbHVlLnksIHdpZHRoOiB2YWx1ZS53aWR0aCwgaGVpZ2h0OiB2YWx1ZS5oZWlnaHR9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBib3VuZHMgPSB2YWx1ZS5nZXRCb3VuZHMoKVxuICAgICAgICAgICAgc2hhcGUgPSB7dHlwZTogJ3JlY3RhbmdsZScsIHg6IGJvdW5kcy54LCB5OiBib3VuZHMueSwgd2lkdGg6IGJvdW5kcy53aWR0aCwgaGVpZ2h0OiBib3VuZHMuaGVpZ2h0fVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNoYXBlXG4gICAgfVxufVxuXG4vKipcbiAqIEEgVGlsdFNoaWZ0QXhpc0ZpbHRlci5cbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFBJWEkuRmlsdGVyXG4gKiBAYWJzdHJhY3RcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFRpbHRTaGlmdEF4aXNGaWx0ZXIgZXh0ZW5kcyBQSVhJLkZpbHRlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihzaGFwZSwgYmx1cil7XG5cbiAgICAgICAgY29uc3QgdmVydGV4ID0gYFxuICAgICAgICAgICAgYXR0cmlidXRlIHZlYzIgYVZlcnRleFBvc2l0aW9uO1xuICAgICAgICAgICAgYXR0cmlidXRlIHZlYzIgYVRleHR1cmVDb29yZDtcblxuICAgICAgICAgICAgdW5pZm9ybSBtYXQzIHByb2plY3Rpb25NYXRyaXg7XG5cbiAgICAgICAgICAgIHZhcnlpbmcgdmVjMiB2VGV4dHVyZUNvb3JkO1xuXG4gICAgICAgICAgICB2b2lkIG1haW4odm9pZCkge1xuICAgICAgICAgICAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNCgocHJvamVjdGlvbk1hdHJpeCAqIHZlYzMoYVZlcnRleFBvc2l0aW9uLCAxLjApKS54eSwgMC4wLCAxLjApO1xuICAgICAgICAgICAgICAgIHZUZXh0dXJlQ29vcmQgPSBhVGV4dHVyZUNvb3JkO1xuICAgICAgICAgICAgfVxuICAgICAgICBgXG5cbiAgICAgICAgY29uc3QgZnJhZ21lbnQgPSBgXG4gICAgICAgICAgICB2YXJ5aW5nIHZlYzIgdlRleHR1cmVDb29yZDtcblxuICAgICAgICAgICAgdW5pZm9ybSB2ZWM0IGZpbHRlckFyZWE7XG4gICAgICAgICAgICB1bmlmb3JtIHNhbXBsZXIyRCB1U2FtcGxlcjtcbiAgICAgICAgICAgIHVuaWZvcm0gaW50IHNoYXBlO1xuICAgICAgICAgICAgdW5pZm9ybSB2ZWM0IHJlY3RhbmdsZTtcbiAgICAgICAgICAgIHVuaWZvcm0gdmVjMyBjaXJjbGU7XG4gICAgICAgICAgICB1bmlmb3JtIGZsb2F0IGJsdXI7XG4gICAgICAgICAgICB1bmlmb3JtIHZlYzIgZGVsdGE7XG4gICAgICAgICAgICB1bmlmb3JtIHZlYzIgdGV4U2l6ZTtcblxuICAgICAgICAgICAgZmxvYXQgcmFuZG9tKHZlYzMgc2NhbGUsIGZsb2F0IHNlZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJhY3Qoc2luKGRvdChnbF9GcmFnQ29vcmQueHl6ICsgc2VlZCwgc2NhbGUpKSAqIDQzNzU4LjU0NTMgKyBzZWVkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdm9pZCBtYWluKHZvaWQpIHtcbiAgICAgICAgICAgICAgICAvLyB0ZXh0dXJlQ29vcmQgdG8gcGl4ZWxDb29yZFxuICAgICAgICAgICAgICAgIHZlYzIgcGl4ZWxDb29yZCA9IHZUZXh0dXJlQ29vcmQgKiBmaWx0ZXJBcmVhLnh5IC0gdmVjMig0LjAsIDQuMCk7ICAgLy8gRklYTUU6IFRoZXJlJ3MgYSBzaGlmdCBvZiA0ICogNCBwaXhlbHMsIGRvbid0IGtub3cgd2h5Li4uXG5cbiAgICAgICAgICAgICAgICBib29sIGluc2lkZSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNoYXBlID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5zaWRlID0gZGlzdGFuY2UocGl4ZWxDb29yZCwgY2lyY2xlLnh5KSA8PSBjaXJjbGUuejtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNoYXBlID09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5zaWRlID0gcGl4ZWxDb29yZC54ID49IHJlY3RhbmdsZS54ICYmIHBpeGVsQ29vcmQueCA8PSByZWN0YW5nbGUueiAmJiBwaXhlbENvb3JkLnkgPj0gcmVjdGFuZ2xlLnkgJiYgcGl4ZWxDb29yZC55IDw9IHJlY3RhbmdsZS53O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbnNpZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBjb2xvciA9IHZlYzQoMC4wKTtcbiAgICAgICAgICAgICAgICAgICAgZmxvYXQgdG90YWwgPSAwLjA7XG5cbiAgICAgICAgICAgICAgICAgICAgZmxvYXQgb2Zmc2V0ID0gcmFuZG9tKHZlYzMoMTIuOTg5OCwgNzguMjMzLCAxNTEuNzE4MiksIDAuMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChmbG9hdCB0ID0gLTMwLjA7IHQgPD0gMzAuMDsgdCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBwZXJjZW50ID0gKHQgKyBvZmZzZXQgLSAwLjUpIC8gMzAuMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IHdlaWdodCA9IDEuMCAtIGFicyhwZXJjZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgc2FtcGxlID0gdGV4dHVyZTJEKHVTYW1wbGVyLCB2VGV4dHVyZUNvb3JkICsgZGVsdGEgLyB0ZXhTaXplICogcGVyY2VudCAqIGJsdXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlLnJnYiAqPSBzYW1wbGUuYTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yICs9IHNhbXBsZSAqIHdlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHdlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGdsX0ZyYWdDb2xvciA9IGNvbG9yIC8gdG90YWw7XG4gICAgICAgICAgICAgICAgICAgIGdsX0ZyYWdDb2xvci5yZ2IgLz0gZ2xfRnJhZ0NvbG9yLmEgKyAwLjAwMDAxO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRCh1U2FtcGxlciwgdmVjMih2VGV4dHVyZUNvb3JkLnMsIHZUZXh0dXJlQ29vcmQudCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgYFxuXG4gICAgICAgIHN1cGVyKHZlcnRleCwgZnJhZ21lbnQpXG4gICAgICAgIFxuICAgICAgICBpZiAoc2hhcGUudHlwZSA9PT0gJ2NpcmNsZScpIHtcbiAgICAgICAgICAgIHRoaXMudW5pZm9ybXMuc2hhcGUgPSAxXG4gICAgICAgICAgICB0aGlzLnVuaWZvcm1zLmNpcmNsZSA9IFtzaGFwZS54LCBzaGFwZS55LCBzaGFwZS5yXVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy51bmlmb3Jtcy5zaGFwZSA9IDJcbiAgICAgICAgICAgIHRoaXMudW5pZm9ybXMucmVjdGFuZ2xlID0gW3NoYXBlLngsIHNoYXBlLnksIHNoYXBlLnggKyBzaGFwZS53aWR0aCwgc2hhcGUueSArIHNoYXBlLmhlaWdodF1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVuaWZvcm1zLmJsdXIgPSBibHVyXG4gICAgICAgIHRoaXMudW5pZm9ybXMuZGVsdGEgPSBuZXcgUElYSS5Qb2ludCgwLCAwKVxuICAgICAgICB0aGlzLnVuaWZvcm1zLnRleFNpemUgPSBuZXcgUElYSS5Qb2ludCg0ODAsIDI3MClcblxuICAgICAgICB0aGlzLnVwZGF0ZURlbHRhKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3RyZW5ndGggb2YgdGhlIGJsdXIuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mIFBJWEkuZmlsdGVycy5UaWx0U2hpZnRBeGlzRmlsdGVyI1xuICAgICAqL1xuICAgIGdldCBibHVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy51bmlmb3Jtcy5ibHVyXG4gICAgfVxuICAgIHNldCBibHVyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudW5pZm9ybXMuYmx1ciA9IHZhbHVlXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFRoZSBibHVyIHNoYXBlLlxuICAgICAqXG4gICAgICogQG1lbWJlciB7UElYSS5SZWN0YW5nbGV9XG4gICAgICogQG1lbWJlcm9mIFBJWEkuZmlsdGVycy5UaWx0U2hpZnRBeGlzRmlsdGVyI1xuICAgICAqL1xuICAgIGdldCBzaGFwZSgpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pZm9ybXMuc2hhcGUgPT09IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGNpcmNsZSA9IHRoaXMudW5pZm9ybXMuY2lyY2xlXG4gICAgICAgICAgICByZXR1cm4gbmV3IFBJWEkuQ2lyY2xlKGNpcmNsZVswXSwgY2lyY2xlWzFdLCBjaXJjbGVbMl0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZWN0YW5nbGUgPSB0aGlzLnVuaWZvcm1zLnJlY3RhbmdsZVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQSVhJLlJlY3RhbmdsZShyZWN0YW5nbGVbMF0sIHJlY3RhbmdsZVsxXSwgcmVjdGFuZ2xlWzJdLCByZWN0YW5nbGVbM10pXG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IHNoYXBlKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnY2lyY2xlJykge1xuICAgICAgICAgICAgdGhpcy51bmlmb3Jtcy5zaGFwZSA9IDFcbiAgICAgICAgICAgIHRoaXMudW5pZm9ybXMuY2lyY2xlID0gW3ZhbHVlLngsIHZhbHVlLnksIHZhbHVlLnJdXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnVuaWZvcm1zLnNoYXBlID0gMlxuICAgICAgICAgICAgdGhpcy51bmlmb3Jtcy5yZWN0YW5nbGUgPSBbdmFsdWUueCwgdmFsdWUueSwgdmFsdWUueCArIHZhbHVlLndpZHRoLCB2YWx1ZS55ICsgdmFsdWUuaGVpZ2h0XVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEEgVGlsdFNoaWZ0WEZpbHRlci5cbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFBJWEkuVGlsdFNoaWZ0QXhpc0ZpbHRlclxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgVGlsdFNoaWZ0WEZpbHRlciBleHRlbmRzIFRpbHRTaGlmdEF4aXNGaWx0ZXIge1xuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIGZpbHRlciBkZWx0YSB2YWx1ZXMuXG4gICAgICovXG4gICAgdXBkYXRlRGVsdGEoKSB7XG4gICAgICAgIHRoaXMudW5pZm9ybXMuZGVsdGEueCA9IDAuMVxuICAgICAgICB0aGlzLnVuaWZvcm1zLmRlbHRhLnkgPSAwXG4gICAgfVxufVxuXG4vKipcbiAqIEEgVGlsdFNoaWZ0WUZpbHRlci5cbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFBJWEkuVGlsdFNoaWZ0QXhpc0ZpbHRlclxuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgVGlsdFNoaWZ0WUZpbHRlciBleHRlbmRzIFRpbHRTaGlmdEF4aXNGaWx0ZXIge1xuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIGZpbHRlciBkZWx0YSB2YWx1ZXMuXG4gICAgICovXG4gICAgdXBkYXRlRGVsdGEoKSB7XG4gICAgICAgIHRoaXMudW5pZm9ybXMuZGVsdGEueCA9IDBcbiAgICAgICAgdGhpcy51bmlmb3Jtcy5kZWx0YS55ID0gMC4xXG4gICAgfVxufVxuXG4iLCIvLyBJbiBvcmRlciB0byB0ZXN0IHRoaXMgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uIHJ1biBqc2MgaW50ZXJmYWNlLmpzXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEludGVyZmFjZSB7XG4gICAgLy8gQWJzdHJhY3QgaW50ZXJmYWNlIHRoYXQgc2hvdWxkIGJlIGV4dGVuZGVkIGluIGludGVyZmFjZSBzdWJjbGFzc2VzLlxuICAgIC8vIEJ5IGNvbnZlbnRpb24gYWxsIGludGVyZmFjZXMgc2hvdWxkIHN0YXJ0IHdpdGggYW4gdXBwZXIgJ0knXG5cbiAgICBzdGF0aWMgaW1wbGVtZW50YXRpb25FcnJvcihrbGFzcykge1xuICAgICAgICBsZXQgaW50ZXJmYWNlS2V5cyA9IFJlZmxlY3Qub3duS2V5cyh0aGlzLnByb3RvdHlwZSlcbiAgICAgICAgbGV0IGNsYXNzS2V5cyA9IFJlZmxlY3Qub3duS2V5cyhrbGFzcy5wcm90b3R5cGUpXG4gICAgICAgIGZvcihsZXQga2V5IG9mIGludGVyZmFjZUtleXMpIHtcbiAgICAgICAgICAgIGxldCBpbnRlcmZhY2VEZXNjID0gdGhpcy5wcm90b3R5cGVba2V5XVxuICAgICAgICAgICAgbGV0IGNsYXNzRGVzYyA9IGtsYXNzLnByb3RvdHlwZVtrZXldXG4gICAgICAgICAgICBpZiAodHlwZW9mKGNsYXNzRGVzYykgPT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuICdNaXNzaW5nICcgKyBrZXlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHN0YXRpYyBpbXBsZW1lbnRlZEJ5KGtsYXNzKSB7XG4gICAgICAgIC8vIEluIHRoZSBmaXJzdCBzdGVwIG9ubHkgY2hlY2tzIHdoZXRoZXIgdGhlIG1ldGhvZHMgb2YgdGhpc1xuICAgICAgICAvLyBpbnRlcmZhY2UgYXJlIGFsbCBpbXBsZW1lbnRlZCBieSB0aGUgZ2l2ZW4gY2xhc3NcbiAgICAgICAgbGV0IGVycm9yID0gdGhpcy5pbXBsZW1lbnRhdGlvbkVycm9yKGtsYXNzKVxuICAgICAgICByZXR1cm4gZXJyb3IgPT0gbnVsbFxuICAgIH1cblxuICAgICAgICAvLyBUT0RPOiBTcGVjaWZ5IG9wdGlvbmFsIG1ldGhvZHNcbi8vICAgICBzdGF0aWMgb3B0aW9uYWxNZXRob2RzKCkge1xuLy8gICAgICAgICByZXR1cm4gW3RoaXMub25Nb3VzZVdoZWVsXVxuLy8gICAgIH1cbn1cbiIsIi8qIGdsb2JhbHMgSGFtbWVyLCBwcm9wYWdhdGluZyAqL1xuLyplc2xpbnQgbm8tY29uc29sZTogW1wiZXJyb3JcIiwgeyBhbGxvdzogW1wibG9nXCIsIFwid2FyblwiLCBcImluZm9cIiwgXCJlcnJvclwiXSB9XSovXG5cbmltcG9ydCBJbnRlcmZhY2UgZnJvbSAnLi9pbnRlcmZhY2UuanMnXG5pbXBvcnQgeyBQb2ludHMsIEFuZ2xlLCBNYXBQcm94eSB9IGZyb20gJy4vdXRpbHMuanMnXG5pbXBvcnQgRXZlbnRzIGZyb20gJy4vZXZlbnRzLmpzJ1xuXG4vKiogSW50ZXJhY3Rpb24gcGF0dGVybnNcblxuICAgIFNlZSBpbnRlcmFjdGlvbi5odG1sIGZvciBleHBsYW5hdGlvblxuKi9cblxuZXhwb3J0IGNsYXNzIElJbnRlcmFjdGlvblRhcmdldCBleHRlbmRzIEludGVyZmFjZSB7XG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHRydWVcbiAgICB9XG5cbiAgICBvblN0YXJ0KGV2ZW50LCBpbnRlcmFjdGlvbikgeyB9XG4gICAgb25Nb3ZlKGV2ZW50LCBpbnRlcmFjdGlvbikgeyB9XG4gICAgb25FbmQoZXZlbnQsIGludGVyYWN0aW9uKSB7IH1cblxuICAgIG9uTW91c2VXaGVlbChldmVudCkgeyB9XG59XG5cbmV4cG9ydCBjbGFzcyBJSW50ZXJhY3Rpb25NYXBwZXJUYXJnZXQgZXh0ZW5kcyBJbnRlcmZhY2Uge1xuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB0cnVlXG4gICAgfVxuXG4gICAgZmluZFRhcmdldChldmVudCwgbG9jYWwsIGdsb2JhbCkge1xuICAgICAgICByZXR1cm4gSUludGVyYWN0aW9uVGFyZ2V0XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgUG9pbnRNYXAgZXh0ZW5kcyBNYXBQcm94eSB7XG4gICAgLy8gQ29sbGVjdHMgdG91Y2ggcG9pbnRzLCBtb3VzZSBjb29yZGluYXRlcywgZXRjLiBhcyBrZXkgdmFsdWUgcGFpcnMuXG4gICAgLy8gS2V5cyBhcmUgcG9pbnRlciBhbmQgdG91Y2ggaWRzLCB0aGUgc3BlY2lhbCBcIm1vdXNlXCIga2V5LlxuICAgIC8vIFZhbHVlcyBhcmUgcG9pbnRzLCBpLmUuIGFsbCBvYmplY3RzIHdpdGggbnVtZXJpYyB4IGFuZCB5IHByb3BlcnRpZXMuXG4gICAgY29uc3RydWN0b3IocG9pbnRzID0ge30pIHtcbiAgICAgICAgc3VwZXIoKVxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gcG9pbnRzKSB7XG4gICAgICAgICAgICB0aGlzLnNldChrZXksIHBvaW50c1trZXldKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBwb2ludHMgPSBbXVxuICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5rZXlzKCkpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuZ2V0KGtleSlcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKGAke2tleX06e3g6JHt2YWx1ZS54fSwgeToke3ZhbHVlLnl9fWApXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGF0dHJzID0gcG9pbnRzLmpvaW4oJywgJylcbiAgICAgICAgcmV0dXJuIGBbUG9pbnRNYXAgJHthdHRyc31dYFxuICAgIH1cblxuICAgIGNsb25lKCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3IFBvaW50TWFwKClcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmdldChrZXkpXG4gICAgICAgICAgICByZXN1bHQuc2V0KGtleSwgeyB4OiB2YWx1ZS54LCB5OiB2YWx1ZS55IH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIGtleU9mKHZhbHVlKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBvZiB0aGlzLmtleXMoKSkge1xuICAgICAgICAgICAgbGV0IHAgPSB0aGlzLmdldChrZXkpXG4gICAgICAgICAgICBpZiAocC54ID09IHZhbHVlLnggJiYgcC55ID09IHZhbHVlLnkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBmaXJzdEtleSgpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICByZXR1cm4ga2V5XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBmaXJzdCgpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXQoa2V5KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgZmFydGhlc3RzKCkge1xuICAgICAgICBpZiAodGhpcy5zaXplID09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhaXJzID0gW11cbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICBsZXQgcCA9IHRoaXMuZ2V0KGtleSlcbiAgICAgICAgICAgIHAua2V5ID0ga2V5XG4gICAgICAgICAgICBmb3IgKGxldCBrIG9mIHRoaXMua2V5cygpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHEgPSB0aGlzLmdldChrKVxuICAgICAgICAgICAgICAgIHEua2V5ID0ga1xuICAgICAgICAgICAgICAgIHBhaXJzLnB1c2goW3AsIHFdKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBzb3J0ZWQgPSBwYWlycy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUG9pbnRzLmRpc3RhbmNlKGJbMF0sIGJbMV0pIC0gUG9pbnRzLmRpc3RhbmNlKGFbMF0sIGFbMV0pXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBzb3J0ZWRbMF1cbiAgICB9XG5cbiAgICBtZWFuKCkge1xuICAgICAgICBpZiAodGhpcy5zaXplID09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHggPSAwLjAsXG4gICAgICAgICAgICB5ID0gMC4wXG4gICAgICAgIGZvciAobGV0IHAgb2YgdGhpcy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgeCArPSBwLnhcbiAgICAgICAgICAgIHkgKz0gcC55XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgeDogeCAvIHRoaXMuc2l6ZSwgeTogeSAvIHRoaXMuc2l6ZSB9XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpb25EZWx0YSB7XG4gICAgY29uc3RydWN0b3IoeCwgeSwgem9vbSwgcm90YXRlLCBhYm91dCkge1xuICAgICAgICB0aGlzLnggPSB4XG4gICAgICAgIHRoaXMueSA9IHlcbiAgICAgICAgdGhpcy56b29tID0gem9vbVxuICAgICAgICB0aGlzLnJvdGF0ZSA9IHJvdGF0ZVxuICAgICAgICB0aGlzLmFib3V0ID0gYWJvdXRcbiAgICB9XG5cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgbGV0IHZhbHVlcyA9IFtdXG4gICAgICAgIGZvciAobGV0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzKSkge1xuICAgICAgICAgICAgbGV0IHZhbHVlID0gdGhpc1trZXldXG4gICAgICAgICAgICBpZiAoa2V5ID09ICdhYm91dCcpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChgJHtrZXl9Ont4OiR7dmFsdWUueH0sIHk6JHt2YWx1ZS55fX1gKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChgJHtrZXl9OiR7dmFsdWV9YClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgYXR0cnMgPSB2YWx1ZXMuam9pbignLCAnKVxuICAgICAgICByZXR1cm4gYFtJbnRlcmFjdGlvbkRlbHRhICR7YXR0cnN9XWBcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJbnRlcmFjdGlvblBvaW50cyB7XG4gICAgY29uc3RydWN0b3IocGFyZW50ID0gbnVsbCkge1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudFxuICAgICAgICB0aGlzLmN1cnJlbnQgPSBuZXcgUG9pbnRNYXAoKVxuICAgICAgICB0aGlzLnByZXZpb3VzID0gbmV3IFBvaW50TWFwKClcbiAgICAgICAgdGhpcy5zdGFydCA9IG5ldyBQb2ludE1hcCgpXG4gICAgICAgIHRoaXMuZW5kZWQgPSBuZXcgUG9pbnRNYXAoKVxuICAgICAgICB0aGlzLnRpbWVzdGFtcHMgPSBuZXcgTWFwKClcbiAgICB9XG5cbiAgICBtb3ZlZChrZXkpIHtcbiAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnQuZ2V0KGtleSlcbiAgICAgICAgbGV0IHByZXZpb3VzID0gdGhpcy5wcmV2aW91cy5nZXQoa2V5KVxuICAgICAgICByZXR1cm4gUG9pbnRzLnN1YnRyYWN0KGN1cnJlbnQsIHByZXZpb3VzKVxuICAgIH1cblxuICAgIG1vdmUoKSB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jdXJyZW50Lm1lYW4oKVxuICAgICAgICBsZXQgcHJldmlvdXMgPSB0aGlzLnByZXZpb3VzLm1lYW4oKVxuICAgICAgICByZXR1cm4gUG9pbnRzLnN1YnRyYWN0KGN1cnJlbnQsIHByZXZpb3VzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBkZWx0YSBiZXR3ZWVuIHByZXZpb3VzIGFuZCBjdXJyZW50IGFuZ2xlcy4gQ29ycmVjdHNcbiAgICAgKiB2YWx1ZSB0aGF0IGFyZSBsYXJnZXIgdGhhbiA0NcKwXG4gICAgICogQHBhcmFtIHsqfSBhXG4gICAgICogQHBhcmFtIHsqfSBiXG4gICAgICogQHJldHVybnMgZGVsdGFcbiAgICAgKi9cbiAgICBkaWZmQW5nbGUoYSwgYikge1xuICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4yKE1hdGguc2luKGEgLSBiKSwgTWF0aC5jb3MoYSAtIGIpKVxuICAgICAgICBpZiAoTWF0aC5hYnMoYWxwaGEpID4gTWF0aC5QSSAvIDQpIHtcbiAgICAgICAgICAgIGFscGhhIC09IE1hdGguUElcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWxwaGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgZGVsdGEgYmV0d2VlbiBpbnRlcmFjdGlvbiBwb2ludHMgYXQgdCBhbmQgdCsxLlxuICAgICAqXG4gICAgICogQHJldHVybnMgSW50ZXJhY3Rpb25EZWx0YVxuICAgICAqIEBtZW1iZXJvZiBJbnRlcmFjdGlvblBvaW50c1xuICAgICAqL1xuICAgIGRlbHRhKCkge1xuICAgICAgICBsZXQgY3NpemUgPSB0aGlzLmN1cnJlbnQuc2l6ZVxuICAgICAgICBsZXQgcHNpemUgPSB0aGlzLnByZXZpb3VzLnNpemVcbiAgICAgICAgaWYgKGNzaXplID49IDIgJiYgY3NpemUgPT0gcHNpemUpIHtcbiAgICAgICAgICAgIC8vIFJlZHVjZSB0byB0aGUgdHdvIGZhcnRoZXN0cyBwb2ludHNcbiAgICAgICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jdXJyZW50LmZhcnRoZXN0cygpXG5cbiAgICAgICAgICAgIGxldCBjMSA9IGN1cnJlbnRbMF1cbiAgICAgICAgICAgIGxldCBjMiA9IGN1cnJlbnRbMV1cblxuICAgICAgICAgICAgbGV0IHAxID0gdGhpcy5wcmV2aW91cy5nZXQoYzEua2V5KVxuICAgICAgICAgICAgbGV0IHAyID0gdGhpcy5wcmV2aW91cy5nZXQoYzIua2V5KVxuXG4gICAgICAgICAgICAvL2xldCBwMSA9IHByZXZpb3VzWzBdXG4gICAgICAgICAgICAvL2xldCBwMiA9IHByZXZpb3VzWzFdXG5cbiAgICAgICAgICAgIGxldCBkMSA9IFBvaW50cy5zdWJ0cmFjdChjMSwgcDEpXG4gICAgICAgICAgICBsZXQgZDIgPSBQb2ludHMuc3VidHJhY3QoYzIsIHAyKVxuICAgICAgICAgICAgbGV0IGNtID0gUG9pbnRzLm1lYW4oYzEsIGMyKVxuICAgICAgICAgICAgLy9sZXQgcG0gPSBQb2ludHMubWVhbihwMSwgcDIpXG4gICAgICAgICAgICAvLyBVTzogVXNpbmcgdGhlIG1lYW4gbGVhZCB0byBqdW1wcyBiZXR3ZWVuIHRpbWUgc2xpY2VzIHdpdGggMyBhbmQgMiBmaW5nZXJzXG4gICAgICAgICAgICAvLyBXZSB1c2UgdGhlIG1lYW4gb2YgZGVsdGFzIGluc3RlYWRcbiAgICAgICAgICAgIGxldCBkZWx0YSA9IFBvaW50cy5tZWFuKGQxLCBkMikgLy9Qb2ludHMuc3VidHJhY3QoY20sIHBtKVxuICAgICAgICAgICAgbGV0IHpvb20gPSAxLjBcbiAgICAgICAgICAgIGxldCBkaXN0YW5jZTEgPSBQb2ludHMuZGlzdGFuY2UocDEsIHAyKVxuICAgICAgICAgICAgbGV0IGRpc3RhbmNlMiA9IFBvaW50cy5kaXN0YW5jZShjMSwgYzIpXG4gICAgICAgICAgICBpZiAoZGlzdGFuY2UxICE9IDAgJiYgZGlzdGFuY2UyICE9IDApIHtcbiAgICAgICAgICAgICAgICB6b29tID0gZGlzdGFuY2UyIC8gZGlzdGFuY2UxXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgY3VycmVudEFuZ2xlID0gUG9pbnRzLmFuZ2xlKGMxLCBjMilcbiAgICAgICAgICAgIGxldCBwcmV2aW91c0FuZ2xlID0gUG9pbnRzLmFuZ2xlKHAxLCBwMilcbiAgICAgICAgICAgIGxldCBhbHBoYSA9IHRoaXMuZGlmZkFuZ2xlKGN1cnJlbnRBbmdsZSwgcHJldmlvdXNBbmdsZSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50ZXJhY3Rpb25EZWx0YShkZWx0YS54LCBkZWx0YS55LCB6b29tLCBhbHBoYSwgY20pXG4gICAgICAgIH0gZWxzZSBpZiAoY3NpemUgPT0gMSAmJiBwc2l6ZSA9PSAxICYmIHRoaXMuY3VycmVudC5maXJzdEtleSgpID09IHRoaXMucHJldmlvdXMuZmlyc3RLZXkoKSkge1xuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBlbnN1cmUgdGhhdCB0aGUga2V5cyBhcmUgdGhlIHNhbWVcbiAgICAgICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jdXJyZW50LmZpcnN0KClcbiAgICAgICAgICAgIGxldCBwcmV2aW91cyA9IHRoaXMucHJldmlvdXMuZmlyc3QoKVxuICAgICAgICAgICAgbGV0IGRlbHRhID0gUG9pbnRzLnN1YnRyYWN0KGN1cnJlbnQsIHByZXZpb3VzKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnRlcmFjdGlvbkRlbHRhKGRlbHRhLngsIGRlbHRhLnksIDEuMCwgMC4wLCBjdXJyZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgc3RhcnRlZChrZXksIHBvaW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudC5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgdGhpcy5zdGFydC5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgdGhpcy5wcmV2aW91cy5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgdGhpcy50aW1lc3RhbXBzLnNldChrZXksIHBlcmZvcm1hbmNlLm5vdygpKVxuICAgIH1cblxuICAgIHVwZGF0ZShrZXksIHBvaW50KSB7XG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZmYgdGhlIGtleSBpcyBuZXdcbiAgICAgICAgdGhpcy5jdXJyZW50LnNldChrZXksIHBvaW50KVxuICAgICAgICBpZiAoIXRoaXMuc3RhcnQuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnQuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzLnNldChrZXksIHBvaW50KVxuICAgICAgICAgICAgdGhpcy50aW1lc3RhbXBzLnNldChrZXksIHBlcmZvcm1hbmNlLm5vdygpKVxuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICB1cGRhdGVQcmV2aW91cygpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMuY3VycmVudC5rZXlzKCkpIHtcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXMuc2V0KGtleSwgdGhpcy5jdXJyZW50LmdldChrZXkpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RvcChrZXksIHBvaW50KSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnQuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudC5kZWxldGUoa2V5KVxuICAgICAgICAgICAgdGhpcy5wcmV2aW91cy5kZWxldGUoa2V5KVxuICAgICAgICAgICAgdGhpcy5lbmRlZC5zZXQoa2V5LCBwb2ludClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZpbmlzaChrZXksIHBvaW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudC5kZWxldGUoa2V5KVxuICAgICAgICB0aGlzLnByZXZpb3VzLmRlbGV0ZShrZXkpXG4gICAgICAgIHRoaXMuc3RhcnQuZGVsZXRlKGtleSlcbiAgICAgICAgdGhpcy50aW1lc3RhbXBzLmRlbGV0ZShrZXkpXG4gICAgICAgIHRoaXMuZW5kZWQuZGVsZXRlKGtleSlcbiAgICB9XG5cbiAgICBpc0ZpbmlzaGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50LnNpemUgPT0gMFxuICAgIH1cblxuICAgIGlzTm9Mb25nZXJUd29GaW5nZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByZXZpb3VzLnNpemUgPiAxICYmIHRoaXMuY3VycmVudC5zaXplIDwgMlxuICAgIH1cblxuICAgIGlzVGFwKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuaXNUYXAoa2V5KVxuICAgIH1cblxuICAgIGlzRG91YmxlVGFwKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuaXNEb3VibGVUYXAoa2V5KVxuICAgIH1cblxuICAgIGlzTG9uZ1ByZXNzKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuaXNMb25nUHJlc3Moa2V5KVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEludGVyYWN0aW9uIGV4dGVuZHMgSW50ZXJhY3Rpb25Qb2ludHMge1xuICAgIGNvbnN0cnVjdG9yKHRhcERpc3RhbmNlID0gMTAsIHRhcER1cmF0aW9uID0gMjUwLjAsIGxvbmdQcmVzc1RpbWUgPSA1MDAuMCkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMudGFwRGlzdGFuY2UgPSB0YXBEaXN0YW5jZVxuICAgICAgICB0aGlzLnRhcENvdW50cyA9IG5ldyBNYXAoKVxuICAgICAgICB0aGlzLnRhcFBvc2l0aW9ucyA9IG5ldyBNYXAoKVxuICAgICAgICB0aGlzLnRhcFRpbWVzdGFtcHMgPSBuZXcgTWFwKClcbiAgICAgICAgdGhpcy50YXBEdXJhdGlvbiA9IHRhcER1cmF0aW9uXG4gICAgICAgIHRoaXMubG9uZ1ByZXNzVGltZSA9IGxvbmdQcmVzc1RpbWVcbiAgICAgICAgdGhpcy50YXJnZXRzID0gbmV3IE1hcCgpXG4gICAgICAgIHRoaXMuc3ViSW50ZXJhY3Rpb25zID0gbmV3IE1hcCgpIC8vIHRhcmdldDpPYmplY3QgOiBJbnRlcmFjdGlvblBvaW50c1xuICAgIH1cblxuICAgIHN0b3Aoa2V5LCBwb2ludCkge1xuICAgICAgICBzdXBlci5zdG9wKGtleSwgcG9pbnQpXG4gICAgICAgIGZvciAobGV0IHBvaW50cyBvZiB0aGlzLnN1YkludGVyYWN0aW9ucy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgcG9pbnRzLnN0b3Aoa2V5LCBwb2ludClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZFRhcmdldChrZXksIHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldHMuc2V0KGtleSwgdGFyZ2V0KVxuICAgICAgICB0aGlzLnN1YkludGVyYWN0aW9ucy5zZXQodGFyZ2V0LCBuZXcgSW50ZXJhY3Rpb25Qb2ludHModGhpcykpXG4gICAgfVxuXG4gICAgcmVtb3ZlVGFyZ2V0KGtleSkge1xuICAgICAgICBsZXQgdGFyZ2V0ID0gdGhpcy50YXJnZXRzLmdldChrZXkpXG4gICAgICAgIHRoaXMudGFyZ2V0cy5kZWxldGUoa2V5KVxuICAgICAgICAvLyBPbmx5IHJlbW92ZSB0YXJnZXQgaWYgbm8ga2V5cyBhcmUgcmVmZXJpbmcgdG8gdGhlIHRhcmdldFxuICAgICAgICBsZXQgcmVtb3ZlID0gdHJ1ZVxuICAgICAgICBmb3IgKGxldCB0IG9mIHRoaXMudGFyZ2V0cy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKHRhcmdldCA9PT0gdCkge1xuICAgICAgICAgICAgICAgIHJlbW92ZSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgdGhpcy5zdWJJbnRlcmFjdGlvbnMuZGVsZXRlKHRhcmdldClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZpbmlzaChrZXksIHBvaW50KSB7XG4gICAgICAgIHN1cGVyLmZpbmlzaChrZXksIHBvaW50KVxuICAgICAgICB0aGlzLnJlbW92ZVRhcmdldChrZXkpXG4gICAgfVxuXG4gICAgbWFwSW50ZXJhY3Rpb24ocG9pbnRzLCBhc3BlY3RzLCBtYXBwaW5nRnVuYykge1xuICAgICAgICAvLyBNYXAgY2VudHJhbGx5IHJlZ2lzdGVyZWQgcG9pbnRzIHRvIHRhcmdldCBpbnRlcmFjdGlvbnNcbiAgICAgICAgLy8gUmV0dXJucyBhbiBhcnJheSBvZiBbdGFyZ2V0LCB1cGRhdGVkIHN1YkludGVyYWN0aW9uXSBwYWlyc1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3IE1hcCgpXG4gICAgICAgIGZvciAobGV0IGtleSBpbiBwb2ludHMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgdGFyZ2V0ID0gdGhpcy50YXJnZXRzLmdldChrZXkpXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3ViSW50ZXJhY3Rpb25zLmhhcyh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcmFjdGlvbiA9IHRoaXMuc3ViSW50ZXJhY3Rpb25zLmdldCh0YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGFzcGVjdCBvZiBhc3BlY3RzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcG9pbnRNYXAgPSB0aGlzW2FzcGVjdF1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwb2ludCA9IHBvaW50TWFwLmdldChrZXkpXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWFwcGVkID0gbWFwcGluZ0Z1bmMocG9pbnQsIHRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uW2FzcGVjdF0uc2V0KGtleSwgbWFwcGVkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5zZXQodGFyZ2V0LCBpbnRlcmFjdGlvbilcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIHJlZ2lzdGVyVGFwKGtleSwgcG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMudGFwQ291bnRzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBsZXQgY291bnQgPSB0aGlzLnRhcENvdW50cy5nZXQoa2V5KVxuICAgICAgICAgICAgdGhpcy50YXBDb3VudHMuc2V0KGtleSwgY291bnQrMSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudGFwQ291bnRzLnNldChrZXksIDEpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50YXBQb3NpdGlvbnMuc2V0KGtleSwgcG9pbnQpXG4gICAgICAgIHRoaXMudGFwVGltZXN0YW1wcy5zZXQoa2V5LCBwZXJmb3JtYW5jZS5ub3coKSlcbiAgICB9XG5cbiAgICB1bnJlZ2lzdGVyVGFwKGtleSkge1xuICAgICAgICB0aGlzLnRhcENvdW50cy5kZWxldGUoa2V5KVxuICAgICAgICB0aGlzLnRhcFBvc2l0aW9ucy5kZWxldGUoa2V5KVxuICAgICAgICB0aGlzLnRhcFRpbWVzdGFtcHMuZGVsZXRlKGtleSlcbiAgICB9XG5cbiAgICBpc1RhcChrZXkpIHtcbiAgICAgICAgbGV0IGVuZGVkID0gdGhpcy5lbmRlZC5nZXQoa2V5KVxuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnN0YXJ0LmdldChrZXkpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHN0YXJ0ICYmXG4gICAgICAgICAgICBlbmRlZCAmJlxuICAgICAgICAgICAgUG9pbnRzLmRpc3RhbmNlKGVuZGVkLCBzdGFydCkgPCB0aGlzLnRhcERpc3RhbmNlXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IHQxID0gdGhpcy50aW1lc3RhbXBzLmdldChrZXkpXG4gICAgICAgICAgICBsZXQgdG9va0xvbmcgPSBwZXJmb3JtYW5jZS5ub3coKSA+IHQxICsgdGhpcy5sb25nUHJlc3NUaW1lXG4gICAgICAgICAgICBpZiAodG9va0xvbmcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaXNEb3VibGVUYXAoa2V5KSB7XG4gICAgICAgIGxldCBlbmRlZCA9IHRoaXMuZW5kZWQuZ2V0KGtleSlcbiAgICAgICAgaWYgKHRoaXMudGFwQ291bnRzLmhhcyhrZXkpICYmIHRoaXMudGFwQ291bnRzLmdldChrZXkpID4gMikge1xuICAgICAgICAgICAgdGhpcy51bnJlZ2lzdGVyVGFwKGtleSlcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50YXBQb3NpdGlvbnMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIGxldCBwb3MgPSB0aGlzLnRhcFBvc2l0aW9ucy5nZXQoa2V5KVxuICAgICAgICAgICAgaWYgKFBvaW50cy5kaXN0YW5jZShlbmRlZCwgcG9zKSA+IHRoaXMudGFwRGlzdGFuY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVucmVnaXN0ZXJUYXAoa2V5KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRhcFRpbWVzdGFtcHMuaGFzKGtleSkgJiYgcGVyZm9ybWFuY2Uubm93KCkgPiB0aGlzLnRhcFRpbWVzdGFtcHMuZ2V0KGtleSkgKyB0aGlzLnRhcER1cmF0aW9uKSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwidGFwIHRvbyBsb25nXCIpXG4gICAgICAgICAgICB0aGlzLnVucmVnaXN0ZXJUYXAoa2V5KVxuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSBmYWxzZVxuICAgICAgICBpZiAodGhpcy5pc1RhcChrZXkpKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMucmVnaXN0ZXJUYXAoa2V5LCBlbmRlZClcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMudGFwQ291bnRzLmdldChrZXkpID09IDJcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudW5yZWdpc3RlclRhcChrZXkpXG4gICAgICAgIH1cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcImlzRG91YmxlVGFwXCIsIHRoaXMudGFwQ291bnRzLmdldChrZXkpLCByZXN1bHQpXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBpc0FueVRhcCgpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMuZW5kZWQua2V5cygpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1RhcChrZXkpKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlzTG9uZ1ByZXNzKGtleSkge1xuICAgICAgICBsZXQgZW5kZWQgPSB0aGlzLmVuZGVkLmdldChrZXkpXG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMuc3RhcnQuZ2V0KGtleSlcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgc3RhcnQgJiZcbiAgICAgICAgICAgIGVuZGVkICYmXG4gICAgICAgICAgICBQb2ludHMuZGlzdGFuY2UoZW5kZWQsIHN0YXJ0KSA8IHRoaXMudGFwRGlzdGFuY2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgdDEgPSB0aGlzLnRpbWVzdGFtcHMuZ2V0KGtleSlcbiAgICAgICAgICAgIGxldCB0b29rTG9uZyA9IHBlcmZvcm1hbmNlLm5vdygpID4gdDEgKyB0aGlzLmxvbmdQcmVzc1RpbWVcbiAgICAgICAgICAgIGlmICh0b29rTG9uZykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpc0FueUxvbmdQcmVzcygpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMuZW5kZWQua2V5cygpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvbmdQcmVzcyhrZXkpKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlzU3R5bHVzKGtleSkge1xuICAgICAgICByZXR1cm4ga2V5ID09PSAnc3R5bHVzJ1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIG1haW4gZGVsZWdhdGUgZnVuY3Rpb25hbGl0eTogQWxsIG5lY2Vzc2FyeSBldmVudCBoYW5kbGVycyBhcmUgcmVnaXN0ZXJlZCBmb3IgdGhlXG4gKiBnaXZlbiBlbGVtZW50LiBVc2VzIFBvaW50ZXJFdmVudHMgaWYgYXZhaWxhYmxlIG9yIFRvdWNoRXZlbnRzIG9uIGlPUy4gVGhlIGZhbGxiYWNrIGlzIG9uIG1vdXNlIGV2ZW50cy5cbiAqIENvbGxlY3RzIHRoZSBldmVudHMgaWYgdGhlIGludGVyYWN0aW9uIHRhcmdldCBjYXB0dXJlcyB0aGUgc3RhcnQgZXZlbnQgKGkuZS4gZGVjbGFyZXMgdGhhdFxuICogdGhlIHRhcmdldCB3YW50cyB0aGUgc3RhcnQgZXZlbnQgYXMgd2VsbCBhcyBhbGwgZm9sbG93aW5nIG1vdmUgYW5kIGVuZCBldmNlbnRzLilcbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgSW50ZXJhY3Rpb25EZWxlZ2F0ZVxuICovXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpb25EZWxlZ2F0ZSB7XG4gICAgLy8gTG9uZyBwcmVzczogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xOTMwODk1L2hvdy1sb25nLWlzLXRoZS1ldmVudC1vbmxvbmdwcmVzcy1pbi10aGUtYW5kcm9pZFxuICAgIC8vIFN0eWx1cyBzdXBwb3J0OiBodHRwczovL3czYy5naXRodWIuaW8vdG91Y2gtZXZlbnRzL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBJbnRlcmFjdGlvbkRlbGVnYXRlLlxuICAgICAqIEBwYXJhbSB7YW55fSBlbGVtZW50XG4gICAgICogQHBhcmFtIHthbnl9IHRhcmdldFxuICAgICAqIEBwYXJhbSB7YW55fSBbeyBtb3VzZVdoZWVsRWxlbWVudCA9IG51bGwsIHVzZUNhcHR1cmUgPSB0cnVlLCBjYXB0dXJlUG9pbnRlckV2ZW50cyA9IHRydWUsIGRlYnVnID0gZmFsc2UgfT17fV1cbiAgICAgKiBAbWVtYmVyb2YgSW50ZXJhY3Rpb25EZWxlZ2F0ZVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHsgbW91c2VXaGVlbEVsZW1lbnQgPSBudWxsLCB1c2VDYXB0dXJlID0gdHJ1ZSwgY2FwdHVyZVBvaW50ZXJFdmVudHMgPSB0cnVlLCBjYW5jZWxPbldpbmRvd091dCA9IHRydWUsIGRlYnVnID0gZmFsc2UgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHRoaXMuZGVidWcgPSBkZWJ1Z1xuICAgICAgICB0aGlzLmludGVyYWN0aW9uID0gbmV3IEludGVyYWN0aW9uKClcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudFxuICAgICAgICB0aGlzLm1vdXNlV2hlZWxFbGVtZW50ID0gbW91c2VXaGVlbEVsZW1lbnQgfHwgZWxlbWVudFxuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldFxuICAgICAgICB0aGlzLnVzZUNhcHR1cmUgPSB1c2VDYXB0dXJlXG4gICAgICAgIHRoaXMuY2FwdHVyZVBvaW50ZXJFdmVudHMgPSBjYXB0dXJlUG9pbnRlckV2ZW50c1xuICAgICAgICB0aGlzLmNhbmNlbE9uV2luZG93T3V0ID0gY2FuY2VsT25XaW5kb3dPdXRcbiAgICAgICAgdGhpcy5zZXR1cEludGVyYWN0aW9uKClcbiAgICB9XG5cbiAgICBzZXR1cEludGVyYWN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICAgICAgbGV0IGVycm9yID0gdGhpcy50YXJnZXRJbnRlcmZhY2UuaW1wbGVtZW50YXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5jb25zdHJ1Y3RvclxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgaWYgKGVycm9yICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIElJbnRlcmFjdGlvblRhcmdldDogJyArIGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0dXBUb3VjaEludGVyYWN0aW9uKClcbiAgICAgICAgdGhpcy5zZXR1cE1vdXNlV2hlZWxJbnRlcmFjdGlvbigpXG4gICAgfVxuXG4gICAgZ2V0IHRhcmdldEludGVyZmFjZSgpIHtcbiAgICAgICAgcmV0dXJuIElJbnRlcmFjdGlvblRhcmdldFxuICAgIH1cblxuICAgIHNldHVwVG91Y2hJbnRlcmFjdGlvbigpIHtcbiAgICAgICAgbGV0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRcbiAgICAgICAgbGV0IHVzZUNhcHR1cmUgPSB0aGlzLnVzZUNhcHR1cmVcbiAgICAgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnUG9pbnRlciBBUEknICsgd2luZG93LlBvaW50ZXJFdmVudClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAncG9pbnRlcmRvd24nLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ3BvaW50ZXJkb3duJywgZS5wb2ludGVySWQpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmUoZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25TdGFydChlKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3BvaW50ZXJtb3ZlJyxcbiAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdwb2ludGVybW92ZScsIGUucG9pbnRlcklkKVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucG9pbnRlclR5cGUgPT0gJ3RvdWNoJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgKGUucG9pbnRlclR5cGUgPT0gJ21vdXNlJyAmJiBFdmVudHMuaXNNb3VzZURvd24oZSkpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5jYXB0dXJlKGUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygncG9pbnRlcm1vdmUgY2FwdHVyZWQnLCBlLnBvaW50ZXJJZClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlKGUpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAncG9pbnRlcnVwJyxcbiAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdwb2ludGVydXAnKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRW5kKGUpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAncG9pbnRlcmNhbmNlbCcsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygncG9pbnRlcmNhbmNlbCcpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FwdHVyZVBvaW50ZXJFdmVudHMpXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAncG9pbnRlcmxlYXZlJyxcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ3BvaW50ZXJsZWF2ZScpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gZWxlbWVudCkgdGhpcy5vbkVuZChlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMuY2FwdHVyZVBvaW50ZXJFdmVudHMpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdwb2ludGVyb3V0JyxcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ3BvaW50ZXJvdXQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0ID09IGVsZW1lbnQpIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY2FuY2VsT25XaW5kb3dPdXQpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ3BvaW50ZXJvdXQnLFxuICAgICAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCA9PSBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVuZChlKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VDYXB0dXJlKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSBpZiAod2luZG93LlRvdWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnVG91Y2ggQVBJJylcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAndG91Y2hzdGFydCcsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3RvdWNoc3RhcnQnLCB0aGlzLnRvdWNoUG9pbnRzKGUpKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jYXB0dXJlKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB0b3VjaCBvZiBlLmNoYW5nZWRUb3VjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vblN0YXJ0KHRvdWNoKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ3RvdWNobW92ZScsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3RvdWNobW92ZScsIHRoaXMudG91Y2hQb2ludHMoZSksIGUpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHRvdWNoIG9mIGUuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlKHRvdWNoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHRvdWNoIG9mIGUudGFyZ2V0VG91Y2hlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk1vdmUodG91Y2gpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAndG91Y2hlbmQnLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ3RvdWNoZW5kJywgdGhpcy50b3VjaFBvaW50cyhlKSlcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgdG91Y2ggb2YgZS5jaGFuZ2VkVG91Y2hlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVuZCh0b3VjaClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdXNlQ2FwdHVyZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICd0b3VjaGNhbmNlbCcsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RvdWNoY2FuY2VsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRhcmdldFRvdWNoZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuY2hhbmdlZFRvdWNoZXMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHRvdWNoIG9mIGUuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQodG91Y2gpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnTW91c2UgQVBJJylcblxuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICdtb3VzZWRvd24nLFxuICAgICAgICAgICAgICAgIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ21vdXNlZG93bicsIGUpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmUoZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25TdGFydChlKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ21vdXNlbW92ZScsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERvdyB3ZSBvbmx5IHVzZSBtb3ZlIGV2ZW50cyBpZiB0aGUgbW91c2UgaXMgZG93bj9cbiAgICAgICAgICAgICAgICAgICAgLy8gSE92ZXIgZWZmZWN0cyBoYXZlIHRvIGJlIGltcGxlbWVudGVkIGJ5IG90aGVyIG1lYW5zXG4gICAgICAgICAgICAgICAgICAgIC8vICYmIEV2ZW50cy5pc01vdXNlRG93bihlKSlcblxuICAgICAgICAgICAgICAgICAgICBpZiAoRXZlbnRzLmlzTW91c2VEb3duKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnbW91c2Vtb3ZlJywgZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlKGUpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHVzZUNhcHR1cmVcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAnbW91c2V1cCcsXG4gICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnbW91c2V1cCcsIGUpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgIClcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNhcHR1cmVQb2ludGVyRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAnbW91c2VvdXQnLFxuICAgICAgICAgICAgICAgICAgICBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCA9PSBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVuZChlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlNob3VsZG4ndCBoYXBwZW46IG1vdXNlb3V0IGVuZHMgaW50ZXJhY3Rpb25cIilcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VDYXB0dXJlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY2FuY2VsT25XaW5kb3dPdXQpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ21vdXNlb3V0JyxcbiAgICAgICAgICAgICAgICAgICAgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25FbmQoZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlQ2FwdHVyZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzRGVzY2VuZGFudChwYXJlbnQsIGNoaWxkKSB7XG4gICAgICAgIGlmIChwYXJlbnQgPT0gY2hpbGQpIHJldHVybiB0cnVlXG4gICAgICAgIGxldCBub2RlID0gY2hpbGQucGFyZW50Tm9kZVxuICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAobm9kZSA9PSBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHRvdWNoUG9pbnRzKGV2ZW50KSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBbXVxuICAgICAgICBmb3IgKGxldCB0b3VjaCBvZiBldmVudC5jaGFuZ2VkVG91Y2hlcykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2godGhpcy5leHRyYWN0UG9pbnQodG91Y2gpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBzZXR1cE1vdXNlV2hlZWxJbnRlcmFjdGlvbigpIHtcbiAgICAgICAgdGhpcy5tb3VzZVdoZWVsRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ21vdXNld2hlZWwnLFxuICAgICAgICAgICAgdGhpcy5vbk1vdXNlV2hlZWwuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgICAgICB0aGlzLm1vdXNlV2hlZWxFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnRE9NTW91c2VTY3JvbGwnLFxuICAgICAgICAgICAgdGhpcy5vbk1vdXNlV2hlZWwuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH1cblxuICAgIG9uTW91c2VXaGVlbChldmVudCkge1xuICAgICAgICBpZiAodGhpcy5jYXB0dXJlKGV2ZW50KSAmJiB0aGlzLnRhcmdldC5vbk1vdXNlV2hlZWwpIHtcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0Lm9uTW91c2VXaGVlbChldmVudClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vY29uc29sZS53YXJuKCdUYXJnZXQgaGFzIG5vIG9uTW91c2VXaGVlbCBjYWxsYmFjaycpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblN0YXJ0KGV2ZW50KSB7XG4gICAgICAgIGxldCBleHRyYWN0ZWQgPSB0aGlzLmV4dHJhY3RQb2ludChldmVudClcbiAgICAgICAgdGhpcy5zdGFydEludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgICAgIHRoaXMudGFyZ2V0Lm9uU3RhcnQoZXZlbnQsIHRoaXMuaW50ZXJhY3Rpb24pXG4gICAgfVxuXG4gICAgb25Nb3ZlKGV2ZW50KSB7XG4gICAgICAgIGxldCBleHRyYWN0ZWQgPSB0aGlzLmV4dHJhY3RQb2ludChldmVudCwgJ2FsbCcpXG4gICAgICAgIHRoaXMudXBkYXRlSW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZClcbiAgICAgICAgdGhpcy50YXJnZXQub25Nb3ZlKGV2ZW50LCB0aGlzLmludGVyYWN0aW9uKVxuICAgICAgICB0aGlzLmludGVyYWN0aW9uLnVwZGF0ZVByZXZpb3VzKClcbiAgICB9XG5cbiAgICBvbkVuZChldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQsICdjaGFuZ2VkVG91Y2hlcycpXG4gICAgICAgIHRoaXMuZW5kSW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZClcbiAgICAgICAgdGhpcy50YXJnZXQub25FbmQoZXZlbnQsIHRoaXMuaW50ZXJhY3Rpb24pXG4gICAgICAgIHRoaXMuZmluaXNoSW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc2tzIHRoZSB0YXJnZXQgd2hldGhlciB0aGUgZXZlbnQgc2hvdWxkIGJlIGNhcHR1cmVkXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2FueX0gZXZlbnRcbiAgICAgKiBAcmV0dXJucyB7Ym9vbH1cbiAgICAgKiBAbWVtYmVyb2YgSW50ZXJhY3Rpb25EZWxlZ2F0ZVxuICAgICAqL1xuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgaWYgKEV2ZW50cy5pc0NhcHR1cmVkKGV2ZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNhcHR1cmVkID0gdGhpcy50YXJnZXQuY2FwdHVyZShldmVudClcbiAgICAgICAgcmV0dXJuIGNhcHR1cmVkXG4gICAgfVxuXG4gICAgZ2V0UG9zaXRpb24oZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHsgeDogZXZlbnQuY2xpZW50WCwgeTogZXZlbnQuY2xpZW50WSB9XG4gICAgfVxuXG4gICAgZXh0cmFjdFBvaW50KGV2ZW50LCB0b3VjaEV2ZW50S2V5ID0gJ2FsbCcpIHtcbiAgICAgICAgLy8gJ3RhcmdldFRvdWNoZXMnXG4gICAgICAgIGxldCByZXN1bHQgPSB7fVxuICAgICAgICBzd2l0Y2ggKGV2ZW50LmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgICAgICAgIGNhc2UgJ01vdXNlRXZlbnQnOlxuICAgICAgICAgICAgICAgIGxldCBidXR0b25zID0gZXZlbnQuYnV0dG9ucyB8fCBldmVudC53aGljaFxuICAgICAgICAgICAgICAgIGlmIChidXR0b25zKSByZXN1bHRbJ21vdXNlJ10gPSB0aGlzLmdldFBvc2l0aW9uKGV2ZW50KVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdQb2ludGVyRXZlbnQnOlxuICAgICAgICAgICAgICAgIHJlc3VsdFtldmVudC5wb2ludGVySWQudG9TdHJpbmcoKV0gPSB0aGlzLmdldFBvc2l0aW9uKGV2ZW50KVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdUb3VjaCc6XG4gICAgICAgICAgICAgICAgbGV0IGlkID1cbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudG91Y2hUeXBlID09PSAnc3R5bHVzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyAnc3R5bHVzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgOiBldmVudC5pZGVudGlmaWVyLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgICByZXN1bHRbaWRdID0gdGhpcy5nZXRQb3NpdGlvbihldmVudClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgY2FzZSAnVG91Y2hFdmVudCc6XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgLy8gTmVlZHMgdG8gYmUgb2JzZXJ2ZWQ6IFBlcmhhcHMgY2hhbmdlZFRvdWNoZXMgYXJlIGFsbCB3ZSBuZWVkLiBJZiBzb1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIC8vIHdlIGNhbiByZW1vdmUgdGhlIHRvdWNoRXZlbnRLZXkgZGVmYXVsdCBwYXJhbWV0ZXJcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICBpZiAodG91Y2hFdmVudEtleSA9PSAnYWxsJykge1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICBmb3IobGV0IHQgb2YgZXZlbnQudGFyZ2V0VG91Y2hlcykge1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3QuaWRlbnRpZmllci50b1N0cmluZygpXSA9IHRoaXMuZ2V0UG9zaXRpb24odClcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICBmb3IobGV0IHQgb2YgZXZlbnQuY2hhbmdlZFRvdWNoZXMpIHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFt0LmlkZW50aWZpZXIudG9TdHJpbmcoKV0gPSB0aGlzLmdldFBvc2l0aW9uKHQpXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgIGZvcihsZXQgdCBvZiBldmVudC5jaGFuZ2VkVG91Y2hlcykge1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3QuaWRlbnRpZmllci50b1N0cmluZygpXSA9IHRoaXMuZ2V0UG9zaXRpb24odClcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBpbnRlcmFjdGlvblN0YXJ0ZWQoZXZlbnQsIGtleSwgcG9pbnQpIHtcbiAgICAgICAgLy8gQ2FsbGJhY2s6IGNhbiBiZSBvdmVyd3JpdHRlblxuICAgIH1cblxuICAgIGludGVyYWN0aW9uRW5kZWQoZXZlbnQsIGtleSwgcG9pbnQpIHtcbiAgICAgICAgLy8gQ2FsbGJhY2s6IGNhbiBiZSBvdmVyd3JpdHRlblxuICAgIH1cblxuICAgIGludGVyYWN0aW9uRmluaXNoZWQoZXZlbnQsIGtleSwgcG9pbnQpIHsgfVxuXG4gICAgc3RhcnRJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBleHRyYWN0ZWQpIHtcbiAgICAgICAgICAgIGxldCBwb2ludCA9IGV4dHJhY3RlZFtrZXldXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uLnN0YXJ0ZWQoa2V5LCBwb2ludClcbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25TdGFydGVkKGV2ZW50LCBrZXksIHBvaW50KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlSW50ZXJhY3Rpb24oZXZlbnQsIGV4dHJhY3RlZCkge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gZXh0cmFjdGVkKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBleHRyYWN0ZWRba2V5XVxuICAgICAgICAgICAgbGV0IHVwZGF0ZWQgPSB0aGlzLmludGVyYWN0aW9uLnVwZGF0ZShrZXksIHBvaW50KVxuICAgICAgICAgICAgaWYgKHVwZGF0ZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJuZXcgcG9pbnRlciBpbiB1cGRhdGVJbnRlcmFjdGlvbiBzaG91bGRuJ3QgaGFwcGVuXCIpXG4gICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvblN0YXJ0ZWQoZXZlbnQsIGtleSwgcG9pbnQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmRJbnRlcmFjdGlvbihldmVudCwgZW5kZWQpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIGVuZGVkKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBlbmRlZFtrZXldXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uLnN0b3Aoa2V5LCBwb2ludClcbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25FbmRlZChldmVudCwga2V5LCBwb2ludClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZpbmlzaEludGVyYWN0aW9uKGV2ZW50LCBlbmRlZCkge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gZW5kZWQpIHtcbiAgICAgICAgICAgIGxldCBwb2ludCA9IGVuZGVkW2tleV1cbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb24uZmluaXNoKGtleSwgcG9pbnQpXG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uRmluaXNoZWQoZXZlbnQsIGtleSwgcG9pbnQpXG4gICAgICAgIH1cbiAgICB9XG59XG4vKipcbiAqIEEgc3BlY2lhbCBJbnRlcmFjdGlvbkRlbGVnYXRlIHRoYXQgbWFwcyBldmVudHMgdG8gc3BlY2lmaWMgcGFydHMgb2ZcbiAqIHRoZSBpbnRlcmFjdGlvbiB0YXJnZXQuIFRoZSBJbnRlcmFjdGlvblRhcmdldCBtdXN0IGltcGxlbWVudCBhIGZpbmRUYXJnZXRcbiAqIG1ldGhvZCB0aGF0IHJldHVybnMgYW4gb2JqZWN0IGltcGxlbWVudGluZyB0aGUgSUludGVyYWN0aW9uVGFyZ2V0IGludGVyZmFjZS5cbiAqXG4gKiBJZiB0aGUgSW50ZXJhY3Rpb25UYXJnZXQgYWxzbyBpbXBsZW1lbnRzIGEgbWFwUG9zaXRpb25Ub1BvaW50IG1ldGhvZCB0aGlzXG4gKiBpcyB1c2VkIHRvIG1hcCB0aGUgcG9pbnRzIHRvIHRoZSBsb2NhbCBjb29yZGluYXRlIHNwYWNlIG9mIHRoZSB0aGUgdGFyZ2V0LlxuICpcbiAqIFRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIGxvb2t1cCBlbGVtZW50cyBhbmQgcmVsYXRlIGV2ZW50cyB0byBsb2NhbFxuICogcG9zaXRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBJbnRlcmFjdGlvbk1hcHBlclxuICogQGV4dGVuZHMge0ludGVyYWN0aW9uRGVsZWdhdGV9XG4gKi9cbmV4cG9ydCBjbGFzcyBJbnRlcmFjdGlvbk1hcHBlciBleHRlbmRzIEludGVyYWN0aW9uRGVsZWdhdGUge1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAgeyB0YXBEaXN0YW5jZSA9IDEwLCBsb25nUHJlc3NUaW1lID0gNTAwLjAsIHVzZUNhcHR1cmUgPSB0cnVlLCBtb3VzZVdoZWVsRWxlbWVudCA9IG51bGwgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGVsZW1lbnQsIHRhcmdldCwgeyB0YXBEaXN0YW5jZSwgdXNlQ2FwdHVyZSwgbG9uZ1ByZXNzVGltZSwgbW91c2VXaGVlbEVsZW1lbnQgfSlcbiAgICB9XG5cbiAgICBnZXQgdGFyZ2V0SW50ZXJmYWNlKCkge1xuICAgICAgICByZXR1cm4gSUludGVyYWN0aW9uTWFwcGVyVGFyZ2V0XG4gICAgfVxuXG4gICAgbWFwUG9zaXRpb25Ub1BvaW50KHBvaW50LCBlbGVtZW50ID0gbnVsbCkge1xuICAgICAgICBpZiAodGhpcy50YXJnZXQubWFwUG9zaXRpb25Ub1BvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQubWFwUG9zaXRpb25Ub1BvaW50KHBvaW50LCBlbGVtZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb2ludFxuICAgIH1cblxuICAgIGludGVyYWN0aW9uU3RhcnRlZChldmVudCwga2V5LCBwb2ludCkge1xuICAgICAgICBpZiAodGhpcy50YXJnZXQuZmluZFRhcmdldCkge1xuICAgICAgICAgICAgbGV0IGxvY2FsID0gdGhpcy5tYXBQb3NpdGlvblRvUG9pbnQocG9pbnQpXG4gICAgICAgICAgICBsZXQgZm91bmQgPSB0aGlzLnRhcmdldC5maW5kVGFyZ2V0KGV2ZW50LCBsb2NhbCwgcG9pbnQpXG4gICAgICAgICAgICBpZiAoZm91bmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb24uYWRkVGFyZ2V0KGtleSwgZm91bmQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbk1vdXNlV2hlZWwoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyZShldmVudCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldC5maW5kVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgbGV0IHBvaW50ID0gdGhpcy5nZXRQb3NpdGlvbihldmVudClcbiAgICAgICAgICAgICAgICBsZXQgbG9jYWwgPSB0aGlzLm1hcFBvc2l0aW9uVG9Qb2ludChwb2ludClcbiAgICAgICAgICAgICAgICBsZXQgZm91bmQgPSB0aGlzLnRhcmdldC5maW5kVGFyZ2V0KGV2ZW50LCBsb2NhbCwgcG9pbnQpXG4gICAgICAgICAgICAgICAgaWYgKGZvdW5kICE9IG51bGwgJiYgZm91bmQub25Nb3VzZVdoZWVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kLm9uTW91c2VXaGVlbChldmVudClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0Lm9uTW91c2VXaGVlbCkge1xuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0Lm9uTW91c2VXaGVlbChldmVudClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLndhcm4oJ1RhcmdldCBoYXMgbm8gb25Nb3VzZVdoZWVsIGNhbGxiYWNrJywgdGhpcy50YXJnZXQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblN0YXJ0KGV2ZW50KSB7XG4gICAgICAgIGxldCBleHRyYWN0ZWQgPSB0aGlzLmV4dHJhY3RQb2ludChldmVudClcbiAgICAgICAgdGhpcy5zdGFydEludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgICAgIGxldCBtYXBwZWQgPSB0aGlzLmludGVyYWN0aW9uLm1hcEludGVyYWN0aW9uKFxuICAgICAgICAgICAgZXh0cmFjdGVkLFxuICAgICAgICAgICAgWydjdXJyZW50JywgJ3N0YXJ0J10sXG4gICAgICAgICAgICB0aGlzLm1hcFBvc2l0aW9uVG9Qb2ludC5iaW5kKHRoaXMpXG4gICAgICAgIClcbiAgICAgICAgZm9yIChsZXQgW3RhcmdldCwgaW50ZXJhY3Rpb25dIG9mIG1hcHBlZC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5vblN0YXJ0KGV2ZW50LCBpbnRlcmFjdGlvbilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW92ZShldmVudCkge1xuICAgICAgICBsZXQgZXh0cmFjdGVkID0gdGhpcy5leHRyYWN0UG9pbnQoZXZlbnQsICdhbGwnKVxuICAgICAgICB0aGlzLnVwZGF0ZUludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgICAgIGxldCBtYXBwZWQgPSB0aGlzLmludGVyYWN0aW9uLm1hcEludGVyYWN0aW9uKFxuICAgICAgICAgICAgZXh0cmFjdGVkLFxuICAgICAgICAgICAgWydjdXJyZW50JywgJ3ByZXZpb3VzJ10sXG4gICAgICAgICAgICB0aGlzLm1hcFBvc2l0aW9uVG9Qb2ludC5iaW5kKHRoaXMpXG4gICAgICAgIClcbiAgICAgICAgZm9yIChsZXQgW3RhcmdldCwgaW50ZXJhY3Rpb25dIG9mIG1hcHBlZC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIHRhcmdldC5vbk1vdmUoZXZlbnQsIGludGVyYWN0aW9uKVxuICAgICAgICAgICAgaW50ZXJhY3Rpb24udXBkYXRlUHJldmlvdXMoKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW50ZXJhY3Rpb24udXBkYXRlUHJldmlvdXMoKVxuICAgIH1cblxuICAgIG9uRW5kKGV2ZW50KSB7XG4gICAgICAgIGxldCBleHRyYWN0ZWQgPSB0aGlzLmV4dHJhY3RQb2ludChldmVudCwgJ2NoYW5nZWRUb3VjaGVzJylcbiAgICAgICAgdGhpcy5lbmRJbnRlcmFjdGlvbihldmVudCwgZXh0cmFjdGVkKVxuICAgICAgICBsZXQgbWFwcGVkID0gdGhpcy5pbnRlcmFjdGlvbi5tYXBJbnRlcmFjdGlvbihcbiAgICAgICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgICAgIFsnZW5kZWQnXSxcbiAgICAgICAgICAgIHRoaXMubWFwUG9zaXRpb25Ub1BvaW50LmJpbmQodGhpcylcbiAgICAgICAgKVxuICAgICAgICBmb3IgKGxldCBbdGFyZ2V0LCBpbnRlcmFjdGlvbl0gb2YgbWFwcGVkLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgdGFyZ2V0Lm9uRW5kKGV2ZW50LCBpbnRlcmFjdGlvbilcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZpbmlzaEludGVyYWN0aW9uKGV2ZW50LCBleHRyYWN0ZWQpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gdHlwZXMgLSBBbiBldmVudCB0eXBlLCBhbiBhcnJheSBvZiBldmVudCB0eXBlcyBvciBldmVudCB0eXBlcyBzZXBlcmF0ZWQgYnkgYSBzcGFjZSBzaWduLiBUaGUgZm9sbG93aW5nXG4gICAgICogICAgIGV2ZW50cyBhcmUgcG9zc2libGU6XG4gICAgICogICAgICAgICBwYW4sIHBhbnN0YXJ0LCBwYW5tb3ZlLCBwYW5lbmQsIHBhbmNhbmNlbCwgcGFubGVmdCwgcGFucmlnaHQsIHBhbnVwLCBwYW5kb3duXG4gICAgICogICAgICAgICBwaW5jaCwgcGluY2hzdGFydCwgcGluY2htb3ZlLCBwaW5jaGVuZCwgcGluY2hjYW5jZWwsIHBpbmNoaW4sIHBpbmNob3V0XG4gICAgICogICAgICAgICBwcmVzcywgcHJlc3N1cFxuICAgICAqICAgICAgICAgcm90YXRlLCByb3RhdGVzdGFydCwgcm90YXRlbW92ZSwgcm90YXRlZW5kLCByb3RhdGVjYW5jZWxcbiAgICAgKiAgICAgICAgIHN3aXBlLCBzd2lwZWxlZnQsIHN3aXBlcmlnaHQsIHN3aXBldXAsIHN3aXBlZG93blxuICAgICAqICAgICAgICAgdGFwXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudHxIVE1MRWxlbWVudFtdfSBlbGVtZW50cyAtIEFuIEhUTUwgZWxlbWVudCBvciBhbiBhcnJheSBvZiBIVE1MIGVsZW1lbnRzLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtjYl0gLSBUaGUgY2FsbGJhY2suIEEgZnVuY3Rpb24gd2hpY2ggaXMgZXhlY3V0ZWQgYWZ0ZXIgdGhlIGV2ZW50IG9jY3Vycy4gUmVjZWl2ZXMgdGhlIGV2ZW50IG9iamVjdCBhcyB0aGVcbiAgICAgKiAgICAgZmlyc3QgcGFyYW10ZXJcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QuIFNlZSB0aGUgaGFtbWVyIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKi9cbiAgICBzdGF0aWMgb24odHlwZXMsIGVsZW1lbnRzLCBjYiwgb3B0cyA9IHt9KSB7XG4gICAgICAgIG9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG5cbiAgICAgICAgfSwgb3B0cylcblxuICAgICAgICBpZiAodHlwZW9mIEhhbW1lciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0hhbW1lci5qcyBub3QgZm91bmQhJylcbiAgICAgICAgICAgIHJldHVybiB0aGlzXG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb252ZXJ0IHRvIGFycmF5XG4gICAgICAgIHR5cGVzID0gQXJyYXkuaXNBcnJheSh0eXBlcykgPyB0eXBlcyA6IHR5cGVzLnNwbGl0KC9cXHMvKVxuICAgICAgICBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBOb2RlTGlzdCB8fCBlbGVtZW50cyBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICBlbGVtZW50cyA9IEFycmF5LmZyb20oZWxlbWVudHMpXG4gICAgICAgIH1cbiAgICAgICAgZWxlbWVudHMgPSBBcnJheS5pc0FycmF5KGVsZW1lbnRzKSA/IGVsZW1lbnRzIDogW2VsZW1lbnRzXVxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgY29uc3QgdHlwZSA9IHR5cGVzW2ldLnRvTG93ZXJDYXNlKClcblxuICAgICAgICAgICAgLy8gbGlzdCBvZiBoYW1tZXIgZXZlbnRzXG4gICAgICAgICAgICBjb25zdCB1c2VIYW1tZXIgPSAvXih0YXB8ZG91YmxldGFwfHByZXNzfHBhbnxzd2lwZXxwaW5jaHxyb3RhdGUpLiokLy50ZXN0KHR5cGUpXG5cbiAgICAgICAgICAgIC8vIGlmIGl0IGlzIGEgaGFtbWVyIGV2ZW50XG4gICAgICAgICAgICBpZiAodXNlSGFtbWVyKSB7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsZW1lbnRzLmxlbmd0aDsgaisrKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYoZWxlbWVudHNbal0udGFnTmFtZSA9PSBcInN2Z1wiKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGhhbW1lciA9IG5ldyBIYW1tZXIoZWxlbWVudHNbal0sIG9wdHMpXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpbmRvdy5wcm9wYWdhdGluZyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbW1lciA9IHByb3BhZ2F0aW5nKGhhbW1lcilcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlY29nbml6ZXJzXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3BhbicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIuZ2V0KCdwYW4nKS5zZXQoT2JqZWN0LmFzc2lnbih7IGRpcmVjdGlvbjogSGFtbWVyLkRJUkVDVElPTl9BTEwgfSwgb3B0cykpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZS5zdGFydHNXaXRoKCdwaW5jaCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIuZ2V0KCdwaW5jaCcpLnNldChPYmplY3QuYXNzaWduKHsgZW5hYmxlOiB0cnVlIH0sIG9wdHMpKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUuc3RhcnRzV2l0aCgncHJlc3MnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFtbWVyLmdldCgncHJlc3MnKS5zZXQob3B0cylcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3JvdGF0ZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW1tZXIuZ2V0KCdyb3RhdGUnKS5zZXQoT2JqZWN0LmFzc2lnbih7IGVuYWJsZTogdHJ1ZSB9LCBvcHRzKSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3N3aXBlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbW1lci5nZXQoJ3N3aXBlJykuc2V0KE9iamVjdC5hc3NpZ24oeyBkaXJlY3Rpb246IEhhbW1lci5ESVJFQ1RJT05fQUxMIH0sIG9wdHMpKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUuc3RhcnRzV2l0aCgndGFwJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbW1lci5nZXQoJ3RhcCcpLnNldChvcHRzKVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaGFtbWVyLm9uKHR5cGUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiKGV2ZW50KVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZWxlbWVudHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgSGFtbWVyLm9uKGVsZW1lbnRzW2pdLCB0eXBlLCBldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYihldmVudClcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cblxud2luZG93LkludGVyYWN0aW9uTWFwcGVyID0gSW50ZXJhY3Rpb25NYXBwZXJcbiIsIi8qKiBSZXBvcnQgY2FwYWJpbGl0aWVzIHdpdGggZ3VhcmFudGVlZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYXBhYmlsaXRpZXMge1xuXG4gICAgLyoqIFJldHVybnMgdGhlIGJyb3dzZXIgdXNlckFnZW50LlxuICAgIEByZXR1cm4ge3N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgdXNlckFnZW50KCkge1xuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnVW5rbm93biBBZ2VudCdcbiAgICB9XG5cbiAgICAvKiogVGVzdHMgd2hldGhlciB0aGUgYXBwIGlzIHJ1bm5pbmcgb24gYSBtb2JpbGUgZGV2aWNlLlxuICAgIEltcGxlbWVudGVkIGFzIGEgcmVhZG9ubHkgYXR0cmlidXRlLlxuICAgIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IGlzTW9iaWxlKCkge1xuICAgICAgICByZXR1cm4gKC9Nb2JpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKVxuICAgIH1cblxuICAgIC8qKiBUZXN0cyB3aGV0aGVyIHRoZSBhcHAgaXMgcnVubmluZyBvbiBhIGlPUyBkZXZpY2UuXG4gICAgSW1wbGVtZW50ZWQgYXMgYSByZWFkb25seSBhdHRyaWJ1dGUuXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgaXNJT1MoKSB7XG4gICAgICAgIHJldHVybiAoL2lQYWR8aVBob25lfGlQb2QvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpICYmICF3aW5kb3cuTVNTdHJlYW1cbiAgICB9XG5cbiAgICAvKiogVGVzdHMgd2hldGhlciB0aGUgYXBwIGlzIHJ1bm5pbmcgaW4gYSBTYWZhcmkgZW52aXJvbm1lbnQuXG4gICAgU2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzc5NDQ0NjAvZGV0ZWN0LXNhZmFyaS1icm93c2VyXG4gICAgSW1wbGVtZW50ZWQgYXMgYSByZWFkb25seSBhdHRyaWJ1dGUuXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgaXNTYWZhcmkoKSB7XG4gICAgICAgIHJldHVybiBuYXZpZ2F0b3IudmVuZG9yICYmIG5hdmlnYXRvci52ZW5kb3IuaW5kZXhPZignQXBwbGUnKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQgJiYgIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goJ0NyaU9TJylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEaXN0aW5jdHMgaWYgdGhlIGFwcCBpcyBydW5uaW5nIGluc2lkZSBlbGVjdHJvbiBvciBub3QuXG4gICAgICogXG4gICAgICogc291cmNlOiBodHRwczovL2Rpc2N1c3MuYXRvbS5pby90L2RldGVjdC1lbGVjdHJvbi1vci13ZWItcGFnZS1ydW5uaW5nLzMzMTgwLzNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGlzRWxlY3Ryb24oKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcHJvY2VzcyAhPSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMuZWxlY3Ryb24gIT09IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRoZSBkaXNwbGF5IHJlc29sdXRpb24uIE5lY2Vzc2FyeSBmb3IgcmV0aW5hIGRpc3BsYXlzLlxuICAgIEByZXR1cm4ge251bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgZGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDFcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBkZXZpY2UgaXMgYSBtdWx0aS10b3VjaCB0YWJsZS4gVGhpcyBtZXRob2QgaXMgY3VycmVudGx5IG5vdCB1bml2ZXJzYWwgdXNhYmxlIGFuZCBub3Qgc3VyZSFcbiAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG4gICAgc3RhdGljIGdldCBpc011bHRpVG91Y2hUYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIENhcGFiaWxpdGllcy5kZXZpY2VQaXhlbFJhdGlvID4gMiAmJiBDYXBhYmlsaXRpZXMuaXNNb2JpbGUgPT09IGZhbHNlICYmIC9XaW5kb3dzL2kudGVzdChDYXBhYmlsaXRpZXMudXNlckFnZW50KVxuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgbW91c2UgZXZlbnRzIGFyZSBzdXBwb3J0ZWRcbiAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG4gICAgc3RhdGljIHN1cHBvcnRzTW91c2VFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2Yod2luZG93Lk1vdXNlRXZlbnQpICE9ICd1bmRlZmluZWQnXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0b3VjaCBldmVudHMgYXJlIHN1cHBvcnRlZFxuICAgIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgKi9cbiAgICBzdGF0aWMgc3VwcG9ydHNUb3VjaEV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZih3aW5kb3cuVG91Y2hFdmVudCkgIT0gJ3VuZGVmaW5lZCdcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHBvaW50ZXIgZXZlbnRzIGFyZSBzdXBwb3J0ZWRcbiAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG4gICAgc3RhdGljIHN1cHBvcnRzUG9pbnRlckV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZih3aW5kb3cuUG9pbnRlckV2ZW50KSAhPSAndW5kZWZpbmVkJ1xuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgRE9NIHRlbXBsYXRlcyBhcmUgc3VwcG9ydGVkXG4gICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuICAgIHN0YXRpYyBzdXBwb3J0c1RlbXBsYXRlKCkge1xuICAgICAgICByZXR1cm4gJ2NvbnRlbnQnIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJyk7XG4gICAgfVxufVxuXG4vKiogQmFzaWMgdGVzdHMgZm9yIENhcGFiaWxpdGllcy5cbiAqL1xuZXhwb3J0IGNsYXNzIENhcGFiaWxpdGllc1Rlc3RzIHtcblxuICAgIHN0YXRpYyB0ZXN0Q29uZmlybSgpIHtcbiAgICAgICAgbGV0IGJvb2wgPSBjb25maXJtKCdQbGVhc2UgY29uZmlybScpXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkZW1vJykuaW5uZXJIVE1MID0gKGJvb2wpID8gJ0NvbmZpcm1lZCcgOiAnTm90IGNvbmZpcm1lZCdcbiAgICB9XG5cbiAgICBzdGF0aWMgdGVzdFByb21wdCgpIHtcbiAgICAgICAgbGV0IHBlcnNvbiA9IHByb21wdCgnUGxlYXNlIGVudGVyIHlvdXIgbmFtZScsICdIYXJyeSBQb3R0ZXInKVxuICAgICAgICBpZiAocGVyc29uICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRlbW8uaW5uZXJIVE1MID1cbiAgICAgICAgICAgICdIZWxsbyAnICsgcGVyc29uICsgJyEgSG93IGFyZSB5b3UgdG9kYXk/J1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3RVc2VyQWdlbnQoKSB7XG4gICAgICAgIGxldCBhZ2VudCA9ICdVc2VyLWFnZW50OiAnICsgQ2FwYWJpbGl0aWVzLnVzZXJBZ2VudFxuICAgICAgICB1c2VyX2FnZW50LmlubmVySFRNTCA9IGFnZW50XG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3REZXZpY2VQaXhlbFJhdGlvKCkge1xuICAgICAgICBsZXQgdmFsdWUgPSAnRGV2aWNlIFBpeGVsIFJhdGlvOiAnICsgQ2FwYWJpbGl0aWVzLmRldmljZVBpeGVsUmF0aW9cbiAgICAgICAgZGV2aWNlX3BpeGVsX3JhdGlvLmlubmVySFRNTCA9IHZhbHVlXG4gICAgfVxuXG4gICAgc3RhdGljIHRlc3RNdWx0aVRvdWNoVGFibGUoKSB7XG4gICAgICAgIGxldCB2YWx1ZSA9ICdJcyB0aGUgZGV2aWNlIGEgbXVsdGktdG91Y2ggdGFibGU/ICcgKyBDYXBhYmlsaXRpZXMuaXNNdWx0aVRvdWNoVGFibGVcbiAgICAgICAgbXVsdGlfdG91Y2hfdGFibGUuaW5uZXJIVE1MID0gdmFsdWVcbiAgICB9XG5cbiAgICBzdGF0aWMgdGVzdFN1cHBvcnRlZEV2ZW50cygpIHtcbiAgICAgICAgbGV0IGV2ZW50cyA9IFtdXG4gICAgICAgIGlmIChDYXBhYmlsaXRpZXMuc3VwcG9ydHNNb3VzZUV2ZW50cygpKSB7XG4gICAgICAgICAgICBldmVudHMucHVzaCgnTW91c2VFdmVudHMnKVxuICAgICAgICB9XG4gICAgICAgIGlmIChDYXBhYmlsaXRpZXMuc3VwcG9ydHNUb3VjaEV2ZW50cygpKSB7XG4gICAgICAgICAgICBldmVudHMucHVzaCgnVG91Y2hFdmVudHMnKVxuICAgICAgICB9XG4gICAgICAgIGlmIChDYXBhYmlsaXRpZXMuc3VwcG9ydHNQb2ludGVyRXZlbnRzKCkpIHtcbiAgICAgICAgICAgIGV2ZW50cy5wdXNoKCdQb2ludGVyRXZlbnRzJylcbiAgICAgICAgfVxuICAgICAgICBzdXBwb3J0ZWRfZXZlbnRzLmlubmVySFRNTCA9ICdTdXBwb3J0ZWQgRXZlbnRzOiAnICsgZXZlbnRzLmpvaW4oJywgJylcbiAgICB9XG5cbiAgICBzdGF0aWMgdGVzdEFsbCgpIHtcbiAgICAgICAgdGhpcy50ZXN0VXNlckFnZW50KClcbiAgICAgICAgdGhpcy50ZXN0RGV2aWNlUGl4ZWxSYXRpbygpXG4gICAgICAgIHRoaXMudGVzdE11bHRpVG91Y2hUYWJsZSgpXG4gICAgICAgIHRoaXMudGVzdFN1cHBvcnRlZEV2ZW50cygpXG4gICAgfVxufVxuXG4vKiBPcHRpb25hbCBnbG9iYWwgdmFyaWFibGVzLCBuZWVkZWQgaW4gRG9jVGVzdHMuICovXG53aW5kb3cuQ2FwYWJpbGl0aWVzID0gQ2FwYWJpbGl0aWVzXG53aW5kb3cuQ2FwYWJpbGl0aWVzVGVzdHMgPSBDYXBhYmlsaXRpZXNUZXN0c1xuIiwiaW1wb3J0IHsgUG9pbnRzLCBQb2x5Z29uLCBBbmdsZSwgRWxlbWVudHMgfSBmcm9tICcuL3V0aWxzLmpzJ1xuaW1wb3J0IEV2ZW50cyBmcm9tICcuL2V2ZW50cy5qcydcbmltcG9ydCB7IEludGVyYWN0aW9uTWFwcGVyIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi5qcydcbmltcG9ydCB7IENhcGFiaWxpdGllcyB9IGZyb20gJy4vY2FwYWJpbGl0aWVzLmpzJ1xuXG4vKipcbiAqIEEgYmFzZSBjbGFzcyBmb3Igc2NhdHRlciBzcGVjaWZpYyBldmVudHMuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge25hbWV9IFN0cmluZyAtIFRoZSBuYW1lIG9mIHRoZSBldmVudFxuICogQHBhcmFtIHt0YXJnZXR9IE9iamVjdCAtIFRoZSB0YXJnZXQgb2YgdGhlIGV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBCYXNlRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHRhcmdldCkge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0XG4gICAgfVxufVxuXG4vLyBFdmVudCB0eXBlc1xuY29uc3QgU1RBUlQgPSAnb25TdGFydCdcbmNvbnN0IFVQREFURSA9ICdvblVwZGF0ZSdcbmNvbnN0IEVORCA9ICdvbkVuZCdcbmNvbnN0IFpPT00gPSAnb25ab29tJ1xuY29uc3QgTU9WRSA9ICdvbk1vdmUnXG5cbi8qKlxuICogQSBzY2F0dGVyIGV2ZW50IHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgc2NhdHRlciBoYXMgY2hhbmdlZC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7dGFyZ2V0fSBPYmplY3QgLSBUaGUgdGFyZ2V0IHNjYXR0ZXIgb2YgdGhlIGV2ZW50XG4gKiBAcGFyYW0ge29wdGlvbmFsfSBPYmplY3QgLSBPcHRpb25hbCBwYXJhbWV0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFNjYXR0ZXJFdmVudCBleHRlbmRzIEJhc2VFdmVudCB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAge1xuICAgICAgICAgICAgdHJhbnNsYXRlID0geyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICBzY2FsZSA9IG51bGwsXG4gICAgICAgICAgICByb3RhdGUgPSAwLFxuICAgICAgICAgICAgYWJvdXQgPSBudWxsLFxuICAgICAgICAgICAgZmFzdCA9IGZhbHNlLFxuICAgICAgICAgICAgdHlwZSA9IG51bGxcbiAgICAgICAgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKCdzY2F0dGVyVHJhbnNmb3JtZWQnLCB7IHRhcmdldDogdGFyZ2V0IH0pXG4gICAgICAgIHRoaXMudHJhbnNsYXRlID0gdHJhbnNsYXRlXG4gICAgICAgIHRoaXMuc2NhbGUgPSBzY2FsZVxuICAgICAgICB0aGlzLnJvdGF0ZSA9IHJvdGF0ZVxuICAgICAgICB0aGlzLmFib3V0ID0gYWJvdXRcbiAgICAgICAgdGhpcy5mYXN0ID0gZmFzdFxuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlXG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBcIkV2ZW50KCdzY2F0dGVyVHJhbnNmb3JtZWQnLCBzY2FsZTogXCIgK1xuICAgICAgICAgICAgdGhpcy5zY2FsZSArXG4gICAgICAgICAgICAnIGFib3V0OiAnICtcbiAgICAgICAgICAgIHRoaXMuYWJvdXQueCArXG4gICAgICAgICAgICAnLCAnICtcbiAgICAgICAgICAgIHRoaXMuYWJvdXQueSArXG4gICAgICAgICAgICAnKSdcbiAgICAgICAgKVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIHNjYXR0ZXIgcmVzaXplIGV2ZW50IHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgc2NhdHRlciBoYXMgY2hhbmdlZC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7dGFyZ2V0fSBPYmplY3QgLSBUaGUgdGFyZ2V0IHNjYXR0ZXIgb2YgdGhlIGV2ZW50XG4gKiBAcGFyYW0ge29wdGlvbmFsfSBPYmplY3QgLSBPcHRpb25hbCBwYXJhbWV0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFJlc2l6ZUV2ZW50IGV4dGVuZHMgQmFzZUV2ZW50IHtcbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQsIHsgd2lkdGggPSAwLCBoZWlnaHQgPSAwIH0gPSB7fSkge1xuICAgICAgICBzdXBlcignc2NhdHRlclJlc2l6ZWQnLCB7IHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfSlcbiAgICAgICAgdGhpcy53aWR0aCA9IHdpZHRoXG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0XG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAnRXZlbnQoc2NhdHRlclJlc2l6ZWQgd2lkdGg6ICcgK1xuICAgICAgICAgICAgdGhpcy53aWR0aCArXG4gICAgICAgICAgICAnaGVpZ2h0OiAnICtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ICtcbiAgICAgICAgICAgICcpJ1xuICAgICAgICApXG4gICAgfVxufVxuXG4vKipcbiAqIEEgYWJzdHJhY3QgYmFzZSBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhlIHRocm93YWJsZSBiZWhhdmlvciBvZiBhIHNjYXR0ZXJcbiAqIG9iamVjdC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuY2xhc3MgVGhyb3dhYmxlIHtcbiAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgIG1vdmFibGVYID0gdHJ1ZSxcbiAgICAgICAgbW92YWJsZVkgPSB0cnVlLFxuICAgICAgICB0aHJvd1Zpc2liaWxpdHkgPSA0NCxcbiAgICAgICAgdGhyb3dEYW1waW5nID0gMC45NSxcbiAgICAgICAgYXV0b1Rocm93ID0gdHJ1ZSxcbiAgICAgICAgb25UaHJvd0ZpbmlzaGVkID0gbnVsbFxuICAgIH0gPSB7fSkge1xuICAgICAgICB0aGlzLm1vdmFibGVYID0gbW92YWJsZVhcbiAgICAgICAgdGhpcy5tb3ZhYmxlWSA9IG1vdmFibGVZXG4gICAgICAgIHRoaXMudGhyb3dWaXNpYmlsaXR5ID0gdGhyb3dWaXNpYmlsaXR5XG4gICAgICAgIHRoaXMudGhyb3dEYW1waW5nID0gdGhyb3dEYW1waW5nXG4gICAgICAgIHRoaXMuYXV0b1Rocm93ID0gYXV0b1Rocm93XG4gICAgICAgIHRoaXMudmVsb2NpdGllcyA9IFtdXG4gICAgICAgIHRoaXMudmVsb2NpdHkgPSBudWxsXG4gICAgICAgIHRoaXMudGltZXN0YW1wID0gbnVsbFxuICAgICAgICB0aGlzLm9uVGhyb3dGaW5pc2hlZCA9IG9uVGhyb3dGaW5pc2hlZFxuICAgICAgICAvL2NvbnNvbGUubG9nKFwib25UaHJvd0ZpbmlzaGVkXCIsIG9uVGhyb3dGaW5pc2hlZClcbiAgICB9XG5cbiAgICBvYnNlcnZlVmVsb2NpdHkoKSB7XG4gICAgICAgIHRoaXMubGFzdGZyYW1lID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICB9XG5cbiAgICBhZGRWZWxvY2l0eShkZWx0YSwgYnVmZmVyID0gNSkge1xuICAgICAgICBsZXQgdCA9IHBlcmZvcm1hbmNlLm5vdygpXG4gICAgICAgIGxldCBkdCA9IHQgLSB0aGlzLmxhc3RmcmFtZVxuICAgICAgICB0aGlzLmxhc3RmcmFtZSA9IHRcbiAgICAgICAgaWYgKGR0ID4gMCkge1xuICAgICAgICAgICAgLy8gQXZvaWQgZGl2aXNpb24gYnkgemVybyBlcnJvcnMgbGF0ZXIgb25cbiAgICAgICAgICAgIGxldCB2ZWxvY2l0eSA9IHsgdDogdCwgZHQ6IGR0LCBkeDogZGVsdGEueCwgZHk6IGRlbHRhLnkgfVxuICAgICAgICAgICAgdGhpcy52ZWxvY2l0aWVzLnB1c2godmVsb2NpdHkpXG4gICAgICAgICAgICB3aGlsZSAodGhpcy52ZWxvY2l0aWVzLmxlbmd0aCA+IGJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMudmVsb2NpdGllcy5zaGlmdCgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtZWFuVmVsb2NpdHkobWlsbGlzZWNvbmRzID0gMzApIHtcbiAgICAgICAgdGhpcy5hZGRWZWxvY2l0eSh7IHg6IDAsIHk6IDAgfSlcbiAgICAgICAgbGV0IHN1bSA9IHsgeDogMCwgeTogMCB9XG4gICAgICAgIGxldCBjb3VudCA9IDBcbiAgICAgICAgbGV0IHQgPSAwXG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnZlbG9jaXRpZXMubGVuZ3RoIC0gMTsgaSA+IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHYgPSB0aGlzLnZlbG9jaXRpZXNbaV1cbiAgICAgICAgICAgIHQgKz0gdi5kdFxuICAgICAgICAgICAgbGV0IG52ID0geyB4OiB2LmR4IC8gdi5kdCwgeTogdi5keSAvIHYuZHQgfVxuICAgICAgICAgICAgc3VtID0gUG9pbnRzLmFkZChzdW0sIG52KVxuICAgICAgICAgICAgY291bnQgKz0gMVxuICAgICAgICAgICAgaWYgKHQgPiBtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIHN1bSAvLyBlbXB0eSB2ZWN0b3JcbiAgICAgICAgcmV0dXJuIFBvaW50cy5tdWx0aXBseVNjYWxhcihzdW0sIDEgLyBjb3VudClcbiAgICB9XG5cbiAgICBraWxsQW5pbWF0aW9uKCkge1xuICAgICAgICB0aGlzLnZlbG9jaXR5ID0gbnVsbFxuICAgICAgICB0aGlzLnZlbG9jaXRpZXMgPSBbXVxuICAgIH1cblxuICAgIHN0YXJ0VGhyb3coKSB7XG4gICAgICAgIHRoaXMudmVsb2NpdHkgPSB0aGlzLm1lYW5WZWxvY2l0eSgpXG4gICAgICAgIGlmICh0aGlzLnZlbG9jaXR5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIENhbGwgbmV4dCB2ZWxvY2l0eSB0byBhbnN1cmUgdGhhdCBzcGVjaWFsaXphdGlvbnNcbiAgICAgICAgICAgIC8vIHRoYXQgdXNlIGtlZXBPblN0YWdlIGFyZSBjYWxsZWRcbiAgICAgICAgICAgIHRoaXMudmVsb2NpdHkgPSB0aGlzLm5leHRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KVxuICAgICAgICAgICAgaWYgKHRoaXMuYXV0b1Rocm93KSB0aGlzLmFuaW1hdGVUaHJvdyhwZXJmb3JtYW5jZS5ub3coKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub25EcmFnQ29tcGxldGUoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYW5pbWF0ZVRocm93KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMudmVsb2NpdHkgIT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IHQgPSBwZXJmb3JtYW5jZS5ub3coKVxuICAgICAgICAgICAgbGV0IGR0ID0gdCAtIHRoaXMubGFzdGZyYW1lXG4gICAgICAgICAgICB0aGlzLmxhc3RmcmFtZSA9IHRcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiYW5pbWF0ZVRocm93XCIsIGR0KVxuICAgICAgICAgICAgbGV0IG5leHQgPSB0aGlzLm5leHRWZWxvY2l0eSh0aGlzLnZlbG9jaXR5KVxuICAgICAgICAgICAgbGV0IHByZXZMZW5ndGggPSBQb2ludHMubGVuZ3RoKHRoaXMudmVsb2NpdHkpXG4gICAgICAgICAgICBsZXQgbmV4dExlbmd0aCA9IFBvaW50cy5sZW5ndGgobmV4dClcbiAgICAgICAgICAgIGlmIChuZXh0TGVuZ3RoID4gcHJldkxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCBmYWN0b3IgPSBuZXh0TGVuZ3RoIC8gcHJldkxlbmd0aFxuICAgICAgICAgICAgICAgIG5leHQgPSBQb2ludHMubXVsdGlwbHlTY2FsYXIobmV4dCwgMSAvIGZhY3RvcilcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnUHJldmVudCBhY2NlbGVyYXRpb24nLCBmYWN0b3IsIHRoaXMudmVsb2NpdHksIG5leHQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnZlbG9jaXR5ID0gbmV4dFxuICAgICAgICAgICAgbGV0IGQgPSBQb2ludHMubXVsdGlwbHlTY2FsYXIodGhpcy52ZWxvY2l0eSwgZHQpXG4gICAgICAgICAgICB0aGlzLl9tb3ZlKGQpXG5cbiAgICAgICAgICAgIHRoaXMub25EcmFnVXBkYXRlKGQpXG4gICAgICAgICAgICBpZiAoZHQgPT0gMCB8fCB0aGlzLm5lZWRzQW5pbWF0aW9uKCkpIHtcbiAgICAgICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRlVGhyb3cuYmluZCh0aGlzKSlcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNPdXRzaWRlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0ZVRocm93LmJpbmQodGhpcykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uRHJhZ0NvbXBsZXRlKClcbiAgICAgICAgaWYgKHRoaXMub25UaHJvd0ZpbmlzaGVkICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMub25UaHJvd0ZpbmlzaGVkKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5lZWRzQW5pbWF0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy52ZWxvY2l0eSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUG9pbnRzLmxlbmd0aCh0aGlzLnZlbG9jaXR5KSA+IDAuMDFcbiAgICB9XG5cbiAgICBuZXh0VmVsb2NpdHkodmVsb2NpdHkpIHtcbiAgICAgICAgLy8gTXVzdCBiZSBvdmVyd3JpdHRlbjogY29tcHV0ZXMgdGhlIGNoYW5nZWQgdmVsb2NpdHkuIEltcGxlbWVudFxuICAgICAgICAvLyBkYW1waW5nLCBjb2xsaXNvbiBkZXRlY3Rpb24sIGV0Yy4gaGVyZVxuICAgICAgICBsZXQgbmV4dCA9IFBvaW50cy5tdWx0aXBseVNjYWxhcih2ZWxvY2l0eSwgdGhpcy50aHJvd0RhbXBpbmcpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAodGhpcy5tb3ZhYmxlWCkgPyBuZXh0LnggOiAwLFxuICAgICAgICAgICAgeTogKHRoaXMubW92YWJsZVkpID8gbmV4dC55IDogMFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX21vdmUoZGVsdGEpIHtcbiAgICAgICAgLy8gT3ZlcndyaXRlIGlmIG5lY2Vzc2FyeVxuICAgIH1cblxuICAgIG9uRHJhZ0NvbXBsZXRlKCkge1xuICAgICAgICAvLyBPdmVyd3JpdGUgaWYgbmVjZXNzYXJ5XG4gICAgfVxuXG4gICAgb25EcmFnVXBkYXRlKGRlbHRhKSB7XG4gICAgICAgIC8vIE92ZXJ3cml0ZSBpZiBuZWNlc3NhcnlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBYnN0cmFjdFNjYXR0ZXIgZXh0ZW5kcyBUaHJvd2FibGUge1xuICAgIGNvbnN0cnVjdG9yKHtcbiAgICAgICAgbWluU2NhbGUgPSAwLjEsXG4gICAgICAgIG1heFNjYWxlID0gMS4wLFxuICAgICAgICBzdGFydFNjYWxlID0gMS4wLFxuICAgICAgICBhdXRvQnJpbmdUb0Zyb250ID0gdHJ1ZSxcbiAgICAgICAgYXV0b1Rocm93ID0gdHJ1ZSxcbiAgICAgICAgdHJhbnNsYXRhYmxlID0gdHJ1ZSxcbiAgICAgICAgc2NhbGFibGUgPSB0cnVlLFxuICAgICAgICByb3RhdGFibGUgPSB0cnVlLFxuICAgICAgICByZXNpemFibGUgPSBmYWxzZSxcbiAgICAgICAgbW92YWJsZVggPSB0cnVlLFxuICAgICAgICBtb3ZhYmxlWSA9IHRydWUsXG4gICAgICAgIHRocm93VmlzaWJpbGl0eSA9IDQ0LFxuICAgICAgICB0aHJvd0RhbXBpbmcgPSAwLjk1LFxuICAgICAgICBvdmVyZG9TY2FsaW5nID0gMSxcbiAgICAgICAgbW91c2Vab29tRmFjdG9yID0gMS4xLFxuICAgICAgICByb3RhdGlvbkRlZ3JlZXMgPSBudWxsLFxuICAgICAgICByb3RhdGlvbiA9IG51bGwsXG4gICAgICAgIG9uVHJhbnNmb3JtID0gbnVsbCxcbiAgICAgICAgaW50ZXJhY3RpdmUgPSB0cnVlLFxuICAgICAgICBvbkNsb3NlID0gbnVsbCxcbiAgICAgICAgb25UaHJvd0ZpbmlzaGVkID0gbnVsbCxcbiAgICAgICAgc2NhbGVBdXRvQ2xvc2UgPSBmYWxzZSxcbiAgICAgICAgc2NhbGVDbG9zZVRocmVzaG9sZCA9IDAuMTAsXG4gICAgICAgIHNjYWxlQ2xvc2VCdWZmZXIgPSAwLjA1XG4gICAgfSA9IHt9KSB7XG4gICAgICAgIGlmIChyb3RhdGlvbkRlZ3JlZXMgIT0gbnVsbCAmJiByb3RhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSByb3RhdGlvbkRlZ3JlZXMgb3Igcm90YXRpb24gYnV0IG5vdCBib3RoJylcbiAgICAgICAgfSBlbHNlIGlmIChyb3RhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICByb3RhdGlvbkRlZ3JlZXMgPSBBbmdsZS5yYWRpYW4yZGVncmVlKHJvdGF0aW9uKVxuICAgICAgICB9IGVsc2UgaWYgKHJvdGF0aW9uRGVncmVlcyA9PSBudWxsKSB7XG4gICAgICAgICAgICByb3RhdGlvbkRlZ3JlZXMgPSAwXG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIoe1xuICAgICAgICAgICAgbW92YWJsZVgsXG4gICAgICAgICAgICBtb3ZhYmxlWSxcbiAgICAgICAgICAgIHRocm93VmlzaWJpbGl0eSxcbiAgICAgICAgICAgIHRocm93RGFtcGluZyxcbiAgICAgICAgICAgIGF1dG9UaHJvdyxcbiAgICAgICAgICAgIG9uVGhyb3dGaW5pc2hlZFxuICAgICAgICB9KVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDbG9zZXMgdGhlIGNhcmQgd2hlbiB0aGUgbWluU2NhbGUgaXMgcmVhY2hlZCBhbmQgdGhlIFxuICAgICAgICAgKiBjYXJkIGlzIHJlbGVhc2VkLiBDYXJkIGNhbiBiZSBzYXZlZCBieSBzY2FsaW5nIGl0IHVwIGFnYWluLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zY2FsZUF1dG9DbG9zZSA9IHNjYWxlQXV0b0Nsb3NlXG4gICAgICAgIHRoaXMuc2NhbGVDbG9zZVRocmVzaG9sZCA9IHNjYWxlQ2xvc2VUaHJlc2hvbGRcbiAgICAgICAgdGhpcy5zY2FsZUNsb3NlQnVmZmVyID0gc2NhbGVDbG9zZUJ1ZmZlclxuICAgICAgICB0aGlzLnNjYWxlQXV0b0Nsb3NlVGltZW91dCA9IG51bGxcblxuICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gaW50ZXJhY3RpdmVcbiAgICAgICAgdGhpcy5zdGFydFJvdGF0aW9uRGVncmVlcyA9IHJvdGF0aW9uRGVncmVlc1xuICAgICAgICB0aGlzLnN0YXJ0U2NhbGUgPSBzdGFydFNjYWxlIC8vIE5lZWRlZCB0byByZXNldCBvYmplY3RcbiAgICAgICAgdGhpcy5taW5TY2FsZSA9IG1pblNjYWxlXG4gICAgICAgIHRoaXMubWF4U2NhbGUgPSBtYXhTY2FsZVxuICAgICAgICB0aGlzLm92ZXJkb1NjYWxpbmcgPSBvdmVyZG9TY2FsaW5nXG4gICAgICAgIHRoaXMudHJhbnNsYXRhYmxlID0gdHJhbnNsYXRhYmxlXG4gICAgICAgIGlmICghdHJhbnNsYXRhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLm1vdmFibGVYID0gZmFsc2VcbiAgICAgICAgICAgIHRoaXMubW92YWJsZVkgPSBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2NhbGFibGUgPSBzY2FsYWJsZVxuICAgICAgICB0aGlzLnJvdGF0YWJsZSA9IHJvdGF0YWJsZVxuICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHJlc2l6YWJsZVxuICAgICAgICB0aGlzLm1vdXNlWm9vbUZhY3RvciA9IG1vdXNlWm9vbUZhY3RvclxuICAgICAgICB0aGlzLmF1dG9CcmluZ1RvRnJvbnQgPSBhdXRvQnJpbmdUb0Zyb250XG4gICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZVxuICAgICAgICB0aGlzLm9uVHJhbnNmb3JtID0gb25UcmFuc2Zvcm0gIT0gbnVsbCA/IFtvblRyYW5zZm9ybV0gOiBudWxsXG4gICAgICAgIHRoaXMub25DbG9zZSA9IG9uQ2xvc2UgIT0gbnVsbCA/IFtvbkNsb3NlXSA6IG51bGxcbiAgICB9XG5cbiAgICBhZGRDbG9zZUV2ZW50Q2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMub25DbG9zZSA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xvc2UgPSBbXVxuICAgICAgICB9XG4gICAgICAgIHRoaXMub25DbG9zZS5wdXNoKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIGFkZFRyYW5zZm9ybUV2ZW50Q2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5vblRyYW5zZm9ybSA9IFtdXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vblRyYW5zZm9ybS5wdXNoKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIHN0YXJ0R2VzdHVyZShpbnRlcmFjdGlvbikge1xuICAgICAgICB0aGlzLmJyaW5nVG9Gcm9udCgpXG4gICAgICAgIHRoaXMua2lsbEFuaW1hdGlvbigpXG4gICAgICAgIHRoaXMub2JzZXJ2ZVZlbG9jaXR5KClcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMub25DbG9zZSkge1xuICAgICAgICAgICAgdGhpcy5vbkNsb3NlLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2sodGhpcykpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXN0dXJlKGludGVyYWN0aW9uKSB7XG4gICAgICAgIGxldCBkZWx0YSA9IGludGVyYWN0aW9uLmRlbHRhKClcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcImdlc3R1cmVcIiwgZGVsdGEpXG4gICAgICAgIGlmIChkZWx0YSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFZlbG9jaXR5KGRlbHRhKVxuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0oZGVsdGEsIGRlbHRhLnpvb20sIGRlbHRhLnJvdGF0ZSwgZGVsdGEuYWJvdXQpXG4gICAgICAgICAgICBpZiAoZGVsdGEuem9vbSAhPSAxKSB0aGlzLmludGVyYWN0aW9uQW5jaG9yID0gZGVsdGEuYWJvdXRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBwb2x5Z29uKCkge1xuICAgICAgICBsZXQgdzIgPSB0aGlzLndpZHRoICogdGhpcy5zY2FsZSAvIDJcbiAgICAgICAgbGV0IGgyID0gdGhpcy5oZWlnaHQgKiB0aGlzLnNjYWxlIC8gMlxuICAgICAgICBsZXQgY2VudGVyID0gdGhpcy5jZW50ZXJcbiAgICAgICAgbGV0IHBvbHlnb24gPSBuZXcgUG9seWdvbihjZW50ZXIpXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiAtdzIsIHk6IC1oMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogdzIsIHk6IC1oMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogdzIsIHk6IGgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiAtdzIsIHk6IGgyIH0pXG4gICAgICAgIHBvbHlnb24ucm90YXRlKHRoaXMucm90YXRpb24pXG4gICAgICAgIHJldHVybiBwb2x5Z29uXG4gICAgfVxuXG4gICAgaXNPdXRzaWRlKCkge1xuICAgICAgICBsZXQgc3RhZ2VQb2x5Z29uID0gdGhpcy5jb250YWluZXJQb2x5Z29uXG4gICAgICAgIGlmIChzdGFnZVBvbHlnb24gPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICBsZXQgcG9seWdvbiA9IHRoaXMucG9seWdvblxuICAgICAgICBpZiAocG9seWdvbiA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIGxldCByZXN1bHQgPSBzdGFnZVBvbHlnb24uaW50ZXJzZWN0c1dpdGgocG9seWdvbilcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gZmFsc2UgfHwgcmVzdWx0Lm92ZXJsYXAgPCB0aGlzLnRocm93VmlzaWJpbGl0eVxuICAgIH1cblxuICAgIHJlY2VudGVyKCkge1xuICAgICAgICAvLyBSZXR1cm4gYSBzbWFsbCB2ZWN0b3IgdGhhdCBndWFyYW50ZWVzIHRoYXQgdGhlIHNjYXR0ZXIgaXMgbW92aW5nXG4gICAgICAgIC8vIHRvd2FyZHMgdGhlIGNlbnRlciBvZiB0aGUgc3RhZ2VcbiAgICAgICAgbGV0IGNlbnRlciA9IHRoaXMuY2VudGVyXG4gICAgICAgIGxldCB0YXJnZXQgPSB0aGlzLmNvbnRhaW5lci5jZW50ZXJcbiAgICAgICAgbGV0IGRlbHRhID0gUG9pbnRzLnN1YnRyYWN0KHRhcmdldCwgY2VudGVyKVxuICAgICAgICByZXR1cm4gUG9pbnRzLm5vcm1hbGl6ZShkZWx0YSlcbiAgICB9XG5cbiAgICBuZXh0VmVsb2NpdHkodmVsb2NpdHkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMua2VlcE9uU3RhZ2UodmVsb2NpdHkpXG4gICAgfVxuXG4gICAgYm91bmNpbmcoKSB7XG4gICAgICAgIC8vIEltcGxlbWVudHMgdGhlIGJvdW5jaW5nIGJlaGF2aW9yIG9mIHRoZSBzY2F0dGVyLiBNb3ZlcyB0aGUgc2NhdHRlclxuICAgICAgICAvLyB0byB0aGUgY2VudGVyIG9mIHRoZSBzdGFnZSBpZiB0aGUgc2NhdHRlciBpcyBvdXRzaWRlIHRoZSBzdGFnZSBvclxuICAgICAgICAvLyBub3Qgd2l0aGluIHRoZSBsaW1pdHMgb2YgdGhlIHRocm93VmlzaWJpbGl0eS5cblxuICAgICAgICBsZXQgc3RhZ2VQb2x5Z29uID0gdGhpcy5jb250YWluZXJQb2x5Z29uXG4gICAgICAgIGxldCBwb2x5Z29uID0gdGhpcy5wb2x5Z29uXG4gICAgICAgIGxldCByZXN1bHQgPSBzdGFnZVBvbHlnb24uaW50ZXJzZWN0c1dpdGgocG9seWdvbilcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UgfHwgcmVzdWx0Lm92ZXJsYXAgPCB0aGlzLnRocm93VmlzaWJpbGl0eSkge1xuICAgICAgICAgICAgbGV0IGN2ID0gdGhpcy5yZWNlbnRlcigpXG4gICAgICAgICAgICBsZXQgcmVjZW50ZXJlZCA9IGZhbHNlXG4gICAgICAgICAgICB3aGlsZSAocmVzdWx0ID09PSBmYWxzZSB8fCByZXN1bHQub3ZlcmxhcCA8IHRoaXMudGhyb3dWaXNpYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgcG9seWdvbi5jZW50ZXIueCArPSBjdi54XG4gICAgICAgICAgICAgICAgcG9seWdvbi5jZW50ZXIueSArPSBjdi55XG4gICAgICAgICAgICAgICAgdGhpcy5fbW92ZShjdilcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBzdGFnZVBvbHlnb24uaW50ZXJzZWN0c1dpdGgocG9seWdvbilcbiAgICAgICAgICAgICAgICByZWNlbnRlcmVkID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlY2VudGVyZWRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBrZWVwT25TdGFnZSh2ZWxvY2l0eSwgY29sbGlzaW9uID0gMC41KSB7XG4gICAgICAgIGxldCBzdGFnZVBvbHlnb24gPSB0aGlzLmNvbnRhaW5lclBvbHlnb25cbiAgICAgICAgaWYgKCFzdGFnZVBvbHlnb24pIHJldHVyblxuICAgICAgICBsZXQgcG9seWdvbiA9IHRoaXMucG9seWdvblxuICAgICAgICBsZXQgYm91bmNlZCA9IHRoaXMuYm91bmNpbmcoKVxuICAgICAgICBpZiAoYm91bmNlZCkge1xuICAgICAgICAgICAgbGV0IHN0YWdlID0gdGhpcy5jb250YWluZXJCb3VuZHNcbiAgICAgICAgICAgIGxldCB4ID0gdGhpcy5jZW50ZXIueFxuICAgICAgICAgICAgbGV0IHkgPSB0aGlzLmNlbnRlci55XG4gICAgICAgICAgICBsZXQgZHggPSB0aGlzLm1vdmFibGVYID8gdmVsb2NpdHkueCA6IDBcbiAgICAgICAgICAgIGxldCBkeSA9IHRoaXMubW92YWJsZVkgPyB2ZWxvY2l0eS55IDogMFxuICAgICAgICAgICAgbGV0IGZhY3RvciA9IHRoaXMudGhyb3dEYW1waW5nXG4gICAgICAgICAgICAvLyBpZiAocmVjZW50ZXJlZCkge1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgZHggPSAtZHhcbiAgICAgICAgICAgICAgICBmYWN0b3IgPSBjb2xsaXNpb25cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh4ID4gc3RhZ2Uud2lkdGgpIHtcbiAgICAgICAgICAgICAgICBkeCA9IC1keFxuICAgICAgICAgICAgICAgIGZhY3RvciA9IGNvbGxpc2lvblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHkgPCAwKSB7XG4gICAgICAgICAgICAgICAgZHkgPSAtZHlcbiAgICAgICAgICAgICAgICBmYWN0b3IgPSBjb2xsaXNpb25cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh5ID4gc3RhZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgZHkgPSAtZHlcbiAgICAgICAgICAgICAgICBmYWN0b3IgPSBjb2xsaXNpb25cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgIHJldHVybiBQb2ludHMubXVsdGlwbHlTY2FsYXIoeyB4OiBkeCwgeTogZHkgfSwgZmFjdG9yKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdXBlci5uZXh0VmVsb2NpdHkodmVsb2NpdHkpXG4gICAgfVxuXG4gICAgZW5kR2VzdHVyZShpbnRlcmFjdGlvbikge1xuICAgICAgICB0aGlzLnN0YXJ0VGhyb3coKVxuICAgICAgICB0aGlzLl9jaGVja0F1dG9DbG9zZSgpXG4gICAgfVxuXG4gICAgX2NoZWNrQXV0b0Nsb3NlKCkge1xuICAgICAgICBpZiAodGhpcy5zY2FsZUF1dG9DbG9zZSlcbiAgICAgICAgICAgIGlmICh0aGlzLnNjYWxlIDwgdGhpcy5taW5TY2FsZSArIHRoaXMuc2NhbGVDbG9zZVRocmVzaG9sZCAtIHRoaXMuc2NhbGVDbG9zZUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuem9vbSh0aGlzLm1pblNjYWxlLCB7IGFuaW1hdGU6IDAuMiwgb25Db21wbGV0ZTogdGhpcy5jbG9zZS5iaW5kKHRoaXMpIH0pXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2NhbGUgPCB0aGlzLm1pblNjYWxlICsgdGhpcy5zY2FsZUNsb3NlVGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy56b29tKHRoaXMubWluU2NhbGUgKyB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGQsIHsgYW5pbWF0ZTogMC40IH0pXG4gICAgICAgICAgICB9XG4gICAgfVxuXG4gICAgcm90YXRlRGVncmVlcyhkZWdyZWVzLCBhbmNob3IpIHtcbiAgICAgICAgbGV0IHJhZCA9IEFuZ2xlLmRlZ3JlZTJyYWRpYW4oZGVncmVlcylcbiAgICAgICAgdGhpcy5yb3RhdGUocmFkLCBhbmNob3IpXG4gICAgfVxuXG4gICAgcm90YXRlKHJhZCwgYW5jaG9yKSB7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtKHsgeDogMCwgeTogMCB9LCAxLjAsIHJhZCwgYW5jaG9yKVxuICAgIH1cblxuICAgIG1vdmUoZCwgeyBhbmltYXRlID0gMCB9ID0ge30pIHtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNsYXRhYmxlKSB7XG4gICAgICAgICAgICBpZiAoYW5pbWF0ZSA+IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnRQb3MgPSB0aGlzLnBvc2l0aW9uXG4gICAgICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIGFuaW1hdGUsIHtcbiAgICAgICAgICAgICAgICAgICAgeDogJys9JyArIGQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogJys9JyArIGQueSxcbiAgICAgICAgICAgICAgICAgICAgLyogc2NhbGU6IHNjYWxlLCB1bzogbm90IGRlZmluZWQsIHdoeSB3YXMgdGhpcyBoZXJlPyAqL1xuICAgICAgICAgICAgICAgICAgICBvblVwZGF0ZTogZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcCA9IHRoaXMucG9zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkeCA9IHAueCAtIHN0YXJ0UG9zLnhcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkeSA9IHAueCAtIHN0YXJ0UG9zLnlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Nb3ZlZChkeCwgZHkpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb3ZlKGQpXG4gICAgICAgICAgICAgICAgdGhpcy5vbk1vdmVkKGQueCwgZC55KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbW92ZVRvKHAsIHsgYW5pbWF0ZSA9IDAgfSA9IHt9KSB7XG4gICAgICAgIGxldCBjID0gdGhpcy5vcmlnaW5cbiAgICAgICAgbGV0IGRlbHRhID0gUG9pbnRzLnN1YnRyYWN0KHAsIGMpXG4gICAgICAgIHRoaXMubW92ZShkZWx0YSwgeyBhbmltYXRlOiBhbmltYXRlIH0pXG4gICAgfVxuXG4gICAgY2VudGVyQXQocCwgeyBhbmltYXRlID0gMCB9ID0ge30pIHtcbiAgICAgICAgbGV0IGMgPSB0aGlzLmNlbnRlclxuICAgICAgICBsZXQgZGVsdGEgPSBQb2ludHMuc3VidHJhY3QocCwgYylcbiAgICAgICAgdGhpcy5tb3ZlKGRlbHRhLCB7IGFuaW1hdGU6IGFuaW1hdGUgfSlcbiAgICB9XG5cbiAgICB6b29tKFxuICAgICAgICBzY2FsZSxcbiAgICAgICAge1xuICAgICAgICAgICAgYW5pbWF0ZSA9IDAsXG4gICAgICAgICAgICBhYm91dCA9IG51bGwsXG4gICAgICAgICAgICBkZWxheSA9IDAsXG4gICAgICAgICAgICB4ID0gbnVsbCxcbiAgICAgICAgICAgIHkgPSBudWxsLFxuICAgICAgICAgICAgb25Db21wbGV0ZSA9IG51bGxcbiAgICAgICAgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIGxldCBhbmNob3IgPSBhYm91dCB8fCB0aGlzLmNlbnRlclxuICAgICAgICBpZiAoc2NhbGUgIT0gdGhpcy5zY2FsZSkge1xuICAgICAgICAgICAgaWYgKGFuaW1hdGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIGFuaW1hdGUsIHtcbiAgICAgICAgICAgICAgICAgICAgc2NhbGU6IHNjYWxlLFxuICAgICAgICAgICAgICAgICAgICBkZWxheTogZGVsYXksXG4gICAgICAgICAgICAgICAgICAgIG9uQ29tcGxldGU6IG9uQ29tcGxldGUsXG4gICAgICAgICAgICAgICAgICAgIG9uVXBkYXRlOiB0aGlzLm9uWm9vbWVkLmJpbmQodGhpcylcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGVcbiAgICAgICAgICAgICAgICB0aGlzLm9uWm9vbWVkKGFuY2hvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9tb3ZlKGRlbHRhKSB7XG4gICAgICAgIHRoaXMueCArPSB0aGlzLm1vdmFibGVYID8gZGVsdGEueCA6IDBcbiAgICAgICAgdGhpcy55ICs9IHRoaXMubW92YWJsZVggPyBkZWx0YS55IDogMFxuICAgIH1cblxuICAgIHRyYW5zZm9ybSh0cmFuc2xhdGUsIHpvb20sIHJvdGF0ZSwgYW5jaG9yKSB7XG4gICAgICAgIGxldCBkZWx0YSA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMubW92YWJsZVggPyB0cmFuc2xhdGUueCA6IDAsXG4gICAgICAgICAgICB5OiB0aGlzLm1vdmFibGVZID8gdHJhbnNsYXRlLnkgOiAwXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmVzaXphYmxlKSB2YXIgdnpvb20gPSB6b29tXG4gICAgICAgIGlmICghdGhpcy50cmFuc2xhdGFibGUpIGRlbHRhID0geyB4OiAwLCB5OiAwIH1cbiAgICAgICAgaWYgKCF0aGlzLnJvdGF0YWJsZSkgcm90YXRlID0gMFxuICAgICAgICBpZiAoIXRoaXMuc2NhbGFibGUpIHpvb20gPSAxLjBcbiAgICAgICAgaWYgKHpvb20gPT0gMS4wICYmIHJvdGF0ZSA9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9tb3ZlKGRlbHRhKVxuICAgICAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCBldmVudCA9IG5ldyBTY2F0dGVyRXZlbnQodGhpcywge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IGRlbHRhLFxuICAgICAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgcm90YXRlOiAwLFxuICAgICAgICAgICAgICAgICAgICBhYm91dDogYW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBmYXN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogVVBEQVRFXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgZihldmVudClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9yaWdpbiA9IHRoaXMucm90YXRpb25PcmlnaW5cbiAgICAgICAgbGV0IGJldGEgPSBQb2ludHMuYW5nbGUob3JpZ2luLCBhbmNob3IpXG4gICAgICAgIGxldCBkaXN0YW5jZSA9IFBvaW50cy5kaXN0YW5jZShvcmlnaW4sIGFuY2hvcilcbiAgICAgICAgbGV0IHsgc2NhbGU6IG5ld1NjYWxlLCB6b29tOiB0aHJlc2hvbGRlZFpvb20gfSA9IHRoaXMuY2FsY3VsYXRlU2NhbGUoem9vbSlcblxuICAgICAgICBsZXQgbmV3T3JpZ2luID0gUG9pbnRzLmFyYyhhbmNob3IsIGJldGEgKyByb3RhdGUsIGRpc3RhbmNlICogdGhyZXNob2xkZWRab29tKVxuICAgICAgICBsZXQgZXh0cmEgPSBQb2ludHMuc3VidHJhY3QobmV3T3JpZ2luLCBvcmlnaW4pXG4gICAgICAgIGxldCBvZmZzZXQgPSBQb2ludHMuc3VidHJhY3QoYW5jaG9yLCBvcmlnaW4pXG4gICAgICAgIHRoaXMuX21vdmUob2Zmc2V0KVxuICAgICAgICB0aGlzLnNjYWxlID0gbmV3U2NhbGVcbiAgICAgICAgdGhpcy5yb3RhdGlvbiArPSByb3RhdGVcbiAgICAgICAgb2Zmc2V0ID0gUG9pbnRzLm5lZ2F0ZShvZmZzZXQpXG4gICAgICAgIG9mZnNldCA9IFBvaW50cy5hZGQob2Zmc2V0LCBleHRyYSlcbiAgICAgICAgb2Zmc2V0ID0gUG9pbnRzLmFkZChvZmZzZXQsIHRyYW5zbGF0ZSlcbiAgICAgICAgdGhpcy5fbW92ZShvZmZzZXQpXG5cbiAgICAgICAgZGVsdGEueCArPSBleHRyYS54XG4gICAgICAgIGRlbHRhLnkgKz0gZXh0cmEueVxuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IGRlbHRhLFxuICAgICAgICAgICAgICAgIHNjYWxlOiBuZXdTY2FsZSxcbiAgICAgICAgICAgICAgICByb3RhdGU6IHJvdGF0ZSxcbiAgICAgICAgICAgICAgICBhYm91dDogYW5jaG9yXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5vblRyYW5zZm9ybS5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgZihldmVudClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmVzaXphYmxlKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2l6ZUFmdGVyVHJhbnNmb3JtKHZ6b29tKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIGEgZ2l2ZW4gem9vbSwgYSBuZXcgc2NhbGUgaXMgY2FsY3VsYXRlZCwgdGFraW5nXG4gICAgICogbWluIGFuZCBtYXggc2NhbGUgaW50byBhY2NvdW50LlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIC0gVGhlIHpvb20gZmFjdG9yLCB0byBzY2FsZSB0aGUgb2JqZWN0IHdpdGguXG4gICAgICogQHJldHVybnMge29iamVjdH0gLSBSZXR1cm5zIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBhIHZhbHVlIGZvciBhIHZhbGlkIHNjYWxlIGFuZCB0aGUgY29ycmVjdGVkIHpvb20gZmFjdG9yLlxuICAgICAqL1xuICAgIGNhbGN1bGF0ZVNjYWxlKHpvb20pIHtcbiAgICAgICAgbGV0IHNjYWxlID0gdGhpcy5zY2FsZSAqIHpvb21cblxuICAgICAgICBsZXQgbWluU2NhbGUgPSB0aGlzLm1pblNjYWxlIC8gdGhpcy5vdmVyZG9TY2FsaW5nXG4gICAgICAgIGxldCBtYXhTY2FsZSA9IHRoaXMubWF4U2NhbGUgKiB0aGlzLm92ZXJkb1NjYWxpbmdcbiAgICAgICAgaWYgKHNjYWxlIDwgbWluU2NhbGUpIHtcbiAgICAgICAgICAgIHNjYWxlID0gbWluU2NhbGVcbiAgICAgICAgICAgIHpvb20gPSBzY2FsZSAvIHRoaXMuc2NhbGVcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NhbGUgPiBtYXhTY2FsZSkge1xuICAgICAgICAgICAgc2NhbGUgPSBtYXhTY2FsZVxuICAgICAgICAgICAgem9vbSA9IHNjYWxlIC8gdGhpcy5zY2FsZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc2NhbGVBdXRvQ2xvc2UpXG4gICAgICAgICAgICB0aGlzLl91cGRhdGVUcmFuc3BhcmVuY3koKVxuXG4gICAgICAgIHJldHVybiB7IHpvb20sIHNjYWxlIH1cbiAgICB9XG5cbiAgICBfdXBkYXRlVHJhbnNwYXJlbmN5KCkge1xuICAgICAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMubWluU2NhbGUgKyB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGQpIHtcbiAgICAgICAgICAgIGxldCB0cmFuc3BhcmVuY3kgPSB0aGlzLmNhbGN1bGF0ZVNjYWxlVHJhbnNwYXJlbmN5KClcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gdHJhbnNwYXJlbmN5XG4gICAgICAgIH0gZWxzZSB0aGlzLmVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IDFcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVTY2FsZVRyYW5zcGFyZW5jeSgpIHtcbiAgICAgICAgbGV0IHRyYW5zcGFyZW5jeSA9ICh0aGlzLnNjYWxlIC0gdGhpcy5taW5TY2FsZSkgLyB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGRcbiAgICAgICAgdHJhbnNwYXJlbmN5ID0gKHRyYW5zcGFyZW5jeSA+IDEpID8gMSA6ICh0cmFuc3BhcmVuY3kgPCAwKSA/IDAgOiB0cmFuc3BhcmVuY3lcbiAgICAgICAgcmV0dXJuIHRyYW5zcGFyZW5jeVxuICAgIH1cblxuICAgIHJlc2l6ZUFmdGVyVHJhbnNmb3JtKHpvb20pIHtcbiAgICAgICAgLy8gT3ZlcndyaXRlIHRoaXMgaW4gc3ViY2xhc3Nlcy5cbiAgICB9XG5cbiAgICB2YWxpZFNjYWxlKHNjYWxlKSB7XG4gICAgICAgIHNjYWxlID0gTWF0aC5tYXgoc2NhbGUsIHRoaXMubWluU2NhbGUpXG4gICAgICAgIHNjYWxlID0gTWF0aC5taW4oc2NhbGUsIHRoaXMubWF4U2NhbGUpXG4gICAgICAgIHJldHVybiBzY2FsZVxuICAgIH1cblxuICAgIGFuaW1hdGVab29tQm91bmNlKGR0ID0gMSkge1xuICAgICAgICBpZiAodGhpcy56b29tQW5jaG9yICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxldCB6b29tID0gMVxuICAgICAgICAgICAgbGV0IGFtb3VudCA9IE1hdGgubWluKDAuMDEsIDAuMyAqIGR0IC8gMTAwMDAwLjApXG4gICAgICAgICAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMubWluU2NhbGUpIHpvb20gPSAxICsgYW1vdW50XG4gICAgICAgICAgICBpZiAodGhpcy5zY2FsZSA+IHRoaXMubWF4U2NhbGUpIHpvb20gPSAxIC0gYW1vdW50XG4gICAgICAgICAgICBpZiAoem9vbSAhPSAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm0oeyB4OiAwLCB5OiAwIH0sIHpvb20sIDAsIHRoaXMuem9vbUFuY2hvcilcbiAgICAgICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFuaW1hdGVab29tQm91bmNlKGR0KVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnpvb21BbmNob3IgPSBudWxsXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjaGVja1NjYWxpbmcoYWJvdXQsIGRlbGF5ID0gMCkge1xuICAgICAgICB0aGlzLnpvb21BbmNob3IgPSBhYm91dFxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5hbmltYXRlWm9vbUJvdW5jZS5iaW5kKHRoaXMpKVxuICAgICAgICBzZXRUaW1lb3V0KHRoaXMuYW5pbWF0ZVpvb21Cb3VuY2UuYmluZCh0aGlzKSwgZGVsYXkpXG4gICAgfVxuXG4gICAgb25Nb3VzZVdoZWVsKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5jbGFpbWVkQnlTY2F0dGVyKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuY2xhaW1lZEJ5U2NhdHRlciAhPSB0aGlzKSByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmtpbGxBbmltYXRpb24oKVxuICAgICAgICB0aGlzLnRhcmdldFNjYWxlID0gbnVsbFxuICAgICAgICBsZXQgZGlyZWN0aW9uID0gZXZlbnQuZGV0YWlsIDwgMCB8fCBldmVudC53aGVlbERlbHRhID4gMFxuICAgICAgICBsZXQgZ2xvYmFsUG9pbnQgPSB7IHg6IGV2ZW50LmNsaWVudFgsIHk6IGV2ZW50LmNsaWVudFkgfVxuICAgICAgICBsZXQgY2VudGVyUG9pbnQgPSB0aGlzLm1hcFBvc2l0aW9uVG9Db250YWluZXJQb2ludChnbG9iYWxQb2ludClcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICBsZXQgZGVncmVlcyA9IGRpcmVjdGlvbiA/IDUgOiAtNVxuICAgICAgICAgICAgbGV0IHJhZCA9IEFuZ2xlLmRlZ3JlZTJyYWRpYW4oZGVncmVlcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh7IHg6IDAsIHk6IDAgfSwgMS4wLCByYWQsIGNlbnRlclBvaW50KVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHpvb21GYWN0b3IgPSB0aGlzLm1vdXNlWm9vbUZhY3RvclxuICAgICAgICBsZXQgem9vbSA9IGRpcmVjdGlvbiA/IHpvb21GYWN0b3IgOiAxIC8gem9vbUZhY3RvclxuICAgICAgICB0aGlzLnRyYW5zZm9ybSh7IHg6IDAsIHk6IDAgfSwgem9vbSwgMCwgY2VudGVyUG9pbnQpXG4gICAgICAgIHRoaXMuY2hlY2tTY2FsaW5nKGNlbnRlclBvaW50LCAyMDApXG5cbiAgICAgICAgaWYgKHRoaXMuc2NhbGVBdXRvQ2xvc2UpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNjYWxlIDw9IHRoaXMubWluU2NhbGUgKyB0aGlzLnNjYWxlQ2xvc2VUaHJlc2hvbGQpIHtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNjYWxlQXV0b0Nsb3NlVGltZW91dCkgY2xlYXJUaW1lb3V0KHRoaXMuc2NhbGVBdXRvQ2xvc2VUaW1lb3V0KVxuICAgICAgICAgICAgICAgIHRoaXMuc2NhbGVBdXRvQ2xvc2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrQXV0b0Nsb3NlKClcbiAgICAgICAgICAgICAgICB9LCA2MDApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVUcmFuc3BhcmVuY3koKVxuICAgICAgICB9XG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgICAgICAgaWYgKHRoaXMub25UcmFuc2Zvcm0gIT0gbnVsbCkge1xuICAgICAgICAvLyAgICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIHRyYW5zbGF0ZToge3g6IDAsIHk6IDB9LFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgIC8vICAgICAgICAgICAgICAgICByb3RhdGU6IDAsXG4gICAgICAgIC8vICAgICAgICAgICAgICAgICBhYm91dDogbnVsbCxcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIGZhc3Q6IGZhbHNlLFxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgdHlwZTogWk9PTVxuICAgICAgICAvLyAgICAgICAgICAgICB9KVxuICAgICAgICAvLyAgICAgICAgICAgICB0aGlzLm9uVHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24oZikge1xuICAgICAgICAvLyAgICAgICAgICAgICAgICAgZihldmVudClcbiAgICAgICAgLy8gICAgICAgICAgICAgfSlcbiAgICAgICAgLy8gICAgICAgICB9XG4gICAgfVxuXG4gICAgb25TdGFydChldmVudCwgaW50ZXJhY3Rpb24pIHtcblxuICAgICAgICBpZiAodGhpcy5zdGFydEdlc3R1cmUoaW50ZXJhY3Rpb24pKSB7XG4gICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZVxuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbkFuY2hvciA9IG51bGxcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlLFxuICAgICAgICAgICAgICAgIHJvdGF0ZTogMCxcbiAgICAgICAgICAgICAgICBhYm91dDogbnVsbCxcbiAgICAgICAgICAgICAgICBmYXN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBTVEFSVFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3ZlKGV2ZW50LCBpbnRlcmFjdGlvbikge1xuICAgICAgICAvKiogQXMgbG9uZyBhcyBtb3VzZW91dCAmJiBtb3VzZWxlYXZlIGludGVycnVwdCB3ZSBjYW5ub3QgYmUgc3VyZSB0aGF0XG4gICAgICAgICAqIGRyYWdnaW5nIHJlbWFpbnMgY29ycmVjdC5cbiAgICAgICAgICovXG4gICAgICAgIGlmICh0aGlzLmRyYWdnaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmdlc3R1cmUoaW50ZXJhY3Rpb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkVuZChldmVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIlNjYXR0ZXIub25FbmRcIiwgdGhpcy5kcmFnZ2luZylcbiAgICAgICAgaWYgKGludGVyYWN0aW9uLmlzRmluaXNoZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5lbmRHZXN0dXJlKGludGVyYWN0aW9uKVxuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgb2YgaW50ZXJhY3Rpb24uZW5kZWQua2V5cygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uLmlzVGFwKGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBvaW50ID0gaW50ZXJhY3Rpb24uZW5kZWQuZ2V0KGtleSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vblRhcChldmVudCwgaW50ZXJhY3Rpb24sIHBvaW50KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlOiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICAgICAgICAgIHJvdGF0ZTogMCxcbiAgICAgICAgICAgICAgICAgICAgYWJvdXQ6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGZhc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBFTkRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgICAgICBmKGV2ZW50KVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFib3V0ID0gdGhpcy5pbnRlcmFjdGlvbkFuY2hvclxuICAgICAgICBpZiAoYWJvdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jaGVja1NjYWxpbmcoYWJvdXQsIDEwMClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVGFwKGV2ZW50LCBpbnRlcmFjdGlvbiwgcG9pbnQpIHsgfVxuXG4gICAgb25EcmFnVXBkYXRlKGRlbHRhKSB7XG4gICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBldmVudCA9IG5ldyBTY2F0dGVyRXZlbnQodGhpcywge1xuICAgICAgICAgICAgICAgIGZhc3Q6IHRydWUsXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlOiBkZWx0YSxcbiAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICBhYm91dDogdGhpcy5jdXJyZW50QWJvdXQsXG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25EcmFnQ29tcGxldGUoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICBhYm91dDogdGhpcy5jdXJyZW50QWJvdXQsXG4gICAgICAgICAgICAgICAgZmFzdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3ZlZChkeCwgZHksIGFib3V0KSB7XG4gICAgICAgIGlmICh0aGlzLm9uVHJhbnNmb3JtICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBldmVudCA9IG5ldyBTY2F0dGVyRXZlbnQodGhpcywge1xuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZTogeyB4OiBkeCwgeTogZHkgfSxcbiAgICAgICAgICAgICAgICBhYm91dDogYWJvdXQsXG4gICAgICAgICAgICAgICAgZmFzdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBudWxsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5vblRyYW5zZm9ybS5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgZihldmVudClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblJlc2l6aW5nKCkge1xuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICBmYXN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBudWxsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblpvb21lZChhYm91dCkge1xuXG4gICAgICAgIGlmICh0aGlzLnNjYWxlQXV0b0Nsb3NlKVxuICAgICAgICAgICAgdGhpcy5fdXBkYXRlVHJhbnNwYXJlbmN5KClcblxuICAgICAgICBpZiAodGhpcy5vblRyYW5zZm9ybSAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZXZlbnQgPSBuZXcgU2NhdHRlckV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICBzY2FsZTogdGhpcy5zY2FsZSxcbiAgICAgICAgICAgICAgICBhYm91dDogYWJvdXQsXG4gICAgICAgICAgICAgICAgZmFzdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMub25UcmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGYoZXZlbnQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKiogQSBjb250YWluZXIgZm9yIHNjYXR0ZXIgb2JqZWN0cywgd2hpY2ggdXNlcyBhIHNpbmdsZSBJbnRlcmFjdGlvbk1hcHBlclxuICogZm9yIGFsbCBjaGlsZHJlbi4gVGhpcyByZWR1Y2VzIHRoZSBudW1iZXIgb2YgcmVnaXN0ZXJlZCBldmVudCBoYW5kbGVyc1xuICogYW5kIGNvdmVycyB0aGUgY29tbW9uIHVzZSBjYXNlIHRoYXQgbXVsdGlwbGUgb2JqZWN0cyBhcmUgc2NhdHRlcmVkXG4gKiBvbiB0aGUgc2FtZSBsZXZlbC5cbiAqL1xuZXhwb3J0IGNsYXNzIERPTVNjYXR0ZXJDb250YWluZXIge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7RE9NIG5vZGV9IGVsZW1lbnQgLSBET00gZWxlbWVudCB0aGF0IHJlY2VpdmVzIGV2ZW50c1xuICAgICAqIEBwYXJhbSB7Qm9vbH0gc3RvcEV2ZW50cyAtICBXaGV0aGVyIGV2ZW50cyBzaG91bGQgYmUgc3RvcHBlZCBvciBwcm9wYWdhdGVkXG4gICAgICogQHBhcmFtIHtCb29sfSBjbGFpbUV2ZW50cyAtIFdoZXRoZXIgZXZlbnRzIHNob3VsZCBiZSBtYXJrZWQgYXMgY2xhaW1lZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBmaW5kVGFyZ2V0IHJldHVybiBhcyBub24tbnVsbCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gW3RvdWNoQWN0aW9uPW5vbmVdIC0gQ1NTIHRvIHNldCB0b3VjaCBhY3Rpb24gc3R5bGUsIG5lZWRlZCB0byBwcmV2ZW50XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyIGNhbmNlbCBldmVudHMuIFVzZSBudWxsIGlmIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHRvdWNoIGFjdGlvbiBzaG91bGQgbm90IGJlIHNldC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgZWxlbWVudCxcbiAgICAgICAgeyBzdG9wRXZlbnRzID0gJ2F1dG8nLCBjbGFpbUV2ZW50cyA9IHRydWUsIHVzZUNhcHR1cmUgPSB0cnVlLCB0b3VjaEFjdGlvbiA9ICdub25lJyB9ID0ge31cbiAgICApIHtcbiAgICAgICAgdGhpcy5vbkNhcHR1cmUgPSBudWxsXG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnRcbiAgICAgICAgaWYgKHN0b3BFdmVudHMgPT09ICdhdXRvJykge1xuICAgICAgICAgICAgaWYgKENhcGFiaWxpdGllcy5pc1NhZmFyaSkge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICd0b3VjaG1vdmUnLFxuICAgICAgICAgICAgICAgICAgICBldmVudCA9PiB0aGlzLnByZXZlbnRQaW5jaChldmVudCksXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHN0b3BFdmVudHMgPSBmYWxzZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdG9wRXZlbnRzID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RvcEV2ZW50cyA9IHN0b3BFdmVudHNcbiAgICAgICAgdGhpcy5jbGFpbUV2ZW50cyA9IGNsYWltRXZlbnRzXG4gICAgICAgIGlmICh0b3VjaEFjdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgRWxlbWVudHMuc2V0U3R5bGUoZWxlbWVudCwgeyB0b3VjaEFjdGlvbiB9KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2NhdHRlciA9IG5ldyBNYXAoKVxuICAgICAgICB0aGlzLmRlbGVnYXRlID0gbmV3IEludGVyYWN0aW9uTWFwcGVyKGVsZW1lbnQsIHRoaXMsIHtcbiAgICAgICAgICAgIHVzZUNhcHR1cmUsXG4gICAgICAgICAgICBtb3VzZVdoZWVsRWxlbWVudDogd2luZG93XG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYgKHR5cGVvZiBkZWJ1Z0NhbnZhcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShkdCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93VG91Y2hlcyhkdClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG93VG91Y2hlcyhkdCkge1xuICAgICAgICBsZXQgcmVzb2x1dGlvbiA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvXG4gICAgICAgIGxldCBjYW52YXMgPSBkZWJ1Z0NhbnZhc1xuICAgICAgICBsZXQgY3VycmVudCA9IHRoaXMuZGVsZWdhdGUuaW50ZXJhY3Rpb24uY3VycmVudFxuICAgICAgICBsZXQgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpXG4gICAgICAgIGxldCByYWRpdXMgPSAyMCAqIHJlc29sdXRpb25cbiAgICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KVxuICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDAsIDAsIDAsIDAuMyknXG4gICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gMlxuICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gJyMwMDMzMDAnXG4gICAgICAgIGZvciAobGV0IFtrZXksIHBvaW50XSBvZiBjdXJyZW50LmVudHJpZXMoKSkge1xuICAgICAgICAgICAgbGV0IGxvY2FsID0gcG9pbnRcbiAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKClcbiAgICAgICAgICAgIGNvbnRleHQuYXJjKFxuICAgICAgICAgICAgICAgIGxvY2FsLnggKiByZXNvbHV0aW9uLFxuICAgICAgICAgICAgICAgIGxvY2FsLnkgKiByZXNvbHV0aW9uLFxuICAgICAgICAgICAgICAgIHJhZGl1cyxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIDIgKiBNYXRoLlBJLFxuICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBjb250ZXh0LmZpbGwoKVxuICAgICAgICAgICAgY29udGV4dC5zdHJva2UoKVxuICAgICAgICB9XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShkdCA9PiB7XG4gICAgICAgICAgICB0aGlzLnNob3dUb3VjaGVzKGR0KVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHByZXZlbnRQaW5jaChldmVudCkge1xuICAgICAgICBldmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnRcbiAgICAgICAgaWYgKGV2ZW50LnNjYWxlICE9PSAxKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhZGQoc2NhdHRlcikge1xuICAgICAgICB0aGlzLnNjYXR0ZXIuc2V0KHNjYXR0ZXIuZWxlbWVudCwgc2NhdHRlcilcbiAgICB9XG5cbiAgICBjYXB0dXJlKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLm9uQ2FwdHVyZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub25DYXB0dXJlKGV2ZW50KVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC50YXJnZXQgPT0gdGhpcy5lbGVtZW50ICYmIHRoaXMuc3RvcEV2ZW50cykge1xuICAgICAgICAgICAgRXZlbnRzLnN0b3AoZXZlbnQpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBtYXBQb3NpdGlvblRvUG9pbnQocG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIFBvaW50cy5mcm9tUGFnZVRvTm9kZSh0aGlzLmVsZW1lbnQsIHBvaW50KVxuICAgIH1cblxuICAgIGlzRGVzY2VuZGFudChwYXJlbnQsIGNoaWxkLCBjbGlja2FibGUgPSBmYWxzZSkge1xuICAgICAgICBpZiAocGFyZW50ID09IGNoaWxkKSByZXR1cm4gdHJ1ZVxuICAgICAgICBsZXQgbm9kZSA9IGNoaWxkLnBhcmVudE5vZGVcbiAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKCFjbGlja2FibGUgJiYgbm9kZS5vbmNsaWNrKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobm9kZSA9PSBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZpbmRUYXJnZXQoZXZlbnQsIGxvY2FsLCBnbG9iYWwpIHtcbiAgICAgICAgLyoqKiBOb3RlIHRoYXQgZWxlbWVudEZyb21Qb2ludCB3b3JrcyB3aXRoIGNsaWVudFgsIGNsaWVudFksIG5vdCBwYWdlWCwgcGFnZVlcbiAgICAgICAgVGhlIGltcG9ydGFudCBwb2ludCBpcyB0aGF0IGV2ZW50IHNob3VsZCBub3QgYmUgdXNlZCwgc2luY2UgdGhlIFRvdWNoRXZlbnRcbiAgICAgICAgcG9pbnRzIGFyZSBoaWRkZW4gaW4gc3ViIG9iamVjdHMuXG4gICAgICAgICoqKi9cbiAgICAgICAgbGV0IGZvdW5kID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChnbG9iYWwueCwgZ2xvYmFsLnkpXG4gICAgICAgIGZvciAobGV0IHRhcmdldCBvZiB0aGlzLnNjYXR0ZXIudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXQuaW50ZXJhY3RpdmUgJiYgdGhpcy5pc0Rlc2NlbmRhbnQodGFyZ2V0LmVsZW1lbnQsIGZvdW5kKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0b3BFdmVudHMpIEV2ZW50cy5zdG9wKGV2ZW50KVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNsYWltRXZlbnRzKSBldmVudC5jbGFpbWVkQnlTY2F0dGVyID0gdGFyZ2V0XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgZ2V0IGNlbnRlcigpIHtcbiAgICAgICAgbGV0IHIgPSB0aGlzLmJvdW5kc1xuICAgICAgICBsZXQgdzIgPSByLndpZHRoIC8gMlxuICAgICAgICBsZXQgaDIgPSByLmhlaWdodCAvIDJcbiAgICAgICAgcmV0dXJuIHsgeDogdzIsIHk6IGgyIH1cbiAgICB9XG5cbiAgICBnZXQgYm91bmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgfVxuXG4gICAgZ2V0IHBvbHlnb24oKSB7XG4gICAgICAgIGxldCByID0gdGhpcy5ib3VuZHNcbiAgICAgICAgbGV0IHcyID0gci53aWR0aCAvIDJcbiAgICAgICAgbGV0IGgyID0gci5oZWlnaHQgLyAyXG4gICAgICAgIGxldCBjZW50ZXIgPSB7IHg6IHcyLCB5OiBoMiB9XG4gICAgICAgIGxldCBwb2x5Z29uID0gbmV3IFBvbHlnb24oY2VudGVyKVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogLXcyLCB5OiAtaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IHcyLCB5OiAtaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IHcyLCB5OiBoMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogLXcyLCB5OiBoMiB9KVxuICAgICAgICByZXR1cm4gcG9seWdvblxuICAgIH1cbn1cblxuXG5leHBvcnQgY2xhc3MgRE9NU2NhdHRlciBleHRlbmRzIEFic3RyYWN0U2NhdHRlciB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnQsXG4gICAgICAgIGNvbnRhaW5lcixcbiAgICAgICAge1xuICAgICAgICAgICAgc3RhcnRTY2FsZSA9IDEuMCxcbiAgICAgICAgICAgIG1pblNjYWxlID0gMC4xLFxuICAgICAgICAgICAgbWF4U2NhbGUgPSAxLjAsXG4gICAgICAgICAgICBvdmVyZG9TY2FsaW5nID0gMS41LFxuICAgICAgICAgICAgYXV0b0JyaW5nVG9Gcm9udCA9IHRydWUsXG4gICAgICAgICAgICB0cmFuc2xhdGFibGUgPSB0cnVlLFxuICAgICAgICAgICAgc2NhbGFibGUgPSB0cnVlLFxuICAgICAgICAgICAgcm90YXRhYmxlID0gdHJ1ZSxcbiAgICAgICAgICAgIG1vdmFibGVYID0gdHJ1ZSxcbiAgICAgICAgICAgIG1vdmFibGVZID0gdHJ1ZSxcbiAgICAgICAgICAgIHJvdGF0aW9uRGVncmVlcyA9IG51bGwsXG4gICAgICAgICAgICByb3RhdGlvbiA9IG51bGwsXG4gICAgICAgICAgICBvblRyYW5zZm9ybSA9IG51bGwsXG4gICAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW4gPSAnY2VudGVyIGNlbnRlcicsXG4gICAgICAgICAgICAvLyBleHRyYXMgd2hpY2ggYXJlIGluIHBhcnQgbmVlZGVkXG4gICAgICAgICAgICB4ID0gMCxcbiAgICAgICAgICAgIHkgPSAwLFxuICAgICAgICAgICAgd2lkdGggPSBudWxsLCAvLyByZXF1aXJlZFxuICAgICAgICAgICAgaGVpZ2h0ID0gbnVsbCwgIC8vIHJlcXVpcmVkXG4gICAgICAgICAgICByZXNpemFibGUgPSBmYWxzZSxcbiAgICAgICAgICAgIHNpbXVsYXRlQ2xpY2sgPSBmYWxzZSxcbiAgICAgICAgICAgIHZlcmJvc2UgPSB0cnVlLFxuICAgICAgICAgICAgb25SZXNpemUgPSBudWxsLFxuICAgICAgICAgICAgdG91Y2hBY3Rpb24gPSAnbm9uZScsXG4gICAgICAgICAgICB0aHJvd1Zpc2liaWxpdHkgPSA0NCxcbiAgICAgICAgICAgIHRocm93RGFtcGluZyA9IDAuOTUsXG4gICAgICAgICAgICBhdXRvVGhyb3cgPSB0cnVlLFxuICAgICAgICAgICAgc2NhbGVBdXRvQ2xvc2UgPSBmYWxzZSxcbiAgICAgICAgICAgIG9uQ2xvc2UgPSBudWxsLFxuICAgICAgICAgICAgc2NhbGVDbG9zZVRocmVzaG9sZCA9IDAuMTAsXG4gICAgICAgICAgICBzY2FsZUNsb3NlQnVmZmVyID0gMC4wNVxuICAgICAgICB9ID0ge31cbiAgICApIHtcbiAgICAgICAgc3VwZXIoe1xuICAgICAgICAgICAgbWluU2NhbGUsXG4gICAgICAgICAgICBtYXhTY2FsZSxcbiAgICAgICAgICAgIHN0YXJ0U2NhbGUsXG4gICAgICAgICAgICBvdmVyZG9TY2FsaW5nLFxuICAgICAgICAgICAgYXV0b0JyaW5nVG9Gcm9udCxcbiAgICAgICAgICAgIHRyYW5zbGF0YWJsZSxcbiAgICAgICAgICAgIHNjYWxhYmxlLFxuICAgICAgICAgICAgcm90YXRhYmxlLFxuICAgICAgICAgICAgbW92YWJsZVgsXG4gICAgICAgICAgICBtb3ZhYmxlWSxcbiAgICAgICAgICAgIHJlc2l6YWJsZSxcbiAgICAgICAgICAgIHJvdGF0aW9uRGVncmVlcyxcbiAgICAgICAgICAgIHJvdGF0aW9uLFxuICAgICAgICAgICAgb25UcmFuc2Zvcm0sXG4gICAgICAgICAgICB0aHJvd1Zpc2liaWxpdHksXG4gICAgICAgICAgICB0aHJvd0RhbXBpbmcsXG4gICAgICAgICAgICBhdXRvVGhyb3csXG4gICAgICAgICAgICBzY2FsZUF1dG9DbG9zZSxcbiAgICAgICAgICAgIHNjYWxlQ2xvc2VUaHJlc2hvbGQsXG4gICAgICAgICAgICBzY2FsZUNsb3NlQnVmZmVyLFxuICAgICAgICAgICAgb25DbG9zZVxuICAgICAgICB9KVxuICAgICAgICBpZiAoY29udGFpbmVyID09IG51bGwgfHwgd2lkdGggPT0gbnVsbCB8fCBoZWlnaHQgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHZhbHVlOiBudWxsJylcbiAgICAgICAgfVxuICAgICAgICBlbGVtZW50LnNjYXR0ZXIgPSB0aGlzXG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnRcbiAgICAgICAgdGhpcy54ID0geFxuICAgICAgICB0aGlzLnkgPSB5XG4gICAgICAgIHRoaXMub2xkWCA9IDBcbiAgICAgICAgdGhpcy5vbGRZID0gMFxuICAgICAgICB0aGlzLm1lYW5YID0geFxuICAgICAgICB0aGlzLm1lYW5ZID0geVxuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGhcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHRcbiAgICAgICAgdGhpcy50aHJvd1Zpc2liaWxpdHkgPSBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0LCB0aHJvd1Zpc2liaWxpdHkpXG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyXG4gICAgICAgIHRoaXMuc2ltdWxhdGVDbGljayA9IHNpbXVsYXRlQ2xpY2tcbiAgICAgICAgdGhpcy5zY2FsZSA9IHN0YXJ0U2NhbGVcbiAgICAgICAgdGhpcy5yb3RhdGlvbkRlZ3JlZXMgPSB0aGlzLnN0YXJ0Um90YXRpb25EZWdyZWVzXG4gICAgICAgIHRoaXMudHJhbnNmb3JtT3JpZ2luID0gdHJhbnNmb3JtT3JpZ2luXG4gICAgICAgIHRoaXMuaW5pdGlhbFZhbHVlcyA9IHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICAgICAgICBzY2FsZTogc3RhcnRTY2FsZSxcbiAgICAgICAgICAgIHJvdGF0aW9uOiB0aGlzLnN0YXJ0Um90YXRpb25EZWdyZWVzLFxuICAgICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiB0cmFuc2Zvcm1PcmlnaW5cbiAgICAgICAgfVxuXG5cbiAgICAgICAgLy8gRm9yIHR3ZWVubGl0ZSB3ZSBuZWVkIGluaXRpYWwgdmFsdWVzIGluIF9nc1RyYW5zZm9ybVxuICAgICAgICBUd2VlbkxpdGUuc2V0KGVsZW1lbnQsIHRoaXMuaW5pdGlhbFZhbHVlcylcbiAgICAgICAgdGhpcy5vblJlc2l6ZSA9IG9uUmVzaXplXG4gICAgICAgIHRoaXMudmVyYm9zZSA9IHZlcmJvc2VcbiAgICAgICAgaWYgKHRvdWNoQWN0aW9uICE9PSBudWxsKSB7XG4gICAgICAgICAgICBFbGVtZW50cy5zZXRTdHlsZShlbGVtZW50LCB7IHRvdWNoQWN0aW9uIH0pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNpemVCdXR0b24gPSBudWxsXG4gICAgICAgIGlmIChyZXNpemFibGUpIHtcbiAgICAgICAgICAgIGxldCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpXG4gICAgICAgICAgICBidXR0b24uc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCJcbiAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5yaWdodCA9IFwiMHB4XCJcbiAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5ib3R0b20gPSBcIjBweFwiXG4gICAgICAgICAgICBidXR0b24uc3R5bGUud2lkdGggPSBcIjUwcHhcIjtcbiAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5oZWlnaHQgPSBcIjUwcHhcIjtcbiAgICAgICAgICAgIC8vIGJ1dHRvbi5zdHlsZS5ib3JkZXJSYWRpdXMgPSBcIjEwMCUgMHB4IDBweCAwcHhcIjtcbiAgICAgICAgICAgIC8vIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kID0gdGhpcy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvclxuICAgICAgICAgICAgYnV0dG9uLmNsYXNzTmFtZSA9IFwiaW50ZXJhY3RpdmVFbGVtZW50XCJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChidXR0b24pXG5cbiAgICAgICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydFJlc2l6ZShlKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZShlKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdG9wUmVzaXplKGUpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5yZXNpemVCdXR0b24gPSBidXR0b25cbiAgICAgICAgfVxuICAgICAgICBjb250YWluZXIuYWRkKHRoaXMpXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgZ2VvbWV0cnkgZGF0YSBhcyBvYmplY3QuICoqL1xuICAgIGdldFN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2NhbGU6IHRoaXMuc2NhbGUsXG4gICAgICAgICAgICB4OiB0aGlzLngsXG4gICAgICAgICAgICB5OiB0aGlzLnksXG4gICAgICAgICAgICByb3RhdGlvbjogdGhpcy5yb3RhdGlvblxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHN1cGVyLmNsb3NlKClcbiAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMuZWxlbWVudC5wYXJlbnROb2RlXG4gICAgICAgIGlmIChwYXJlbnQpIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpXG4gICAgfVxuXG4gICAgZ2V0IHJvdGF0aW9uT3JpZ2luKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jZW50ZXJcbiAgICB9XG5cbiAgICBnZXQgeCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3hcbiAgICB9XG5cbiAgICBnZXQgeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3lcbiAgICB9XG5cbiAgICBzZXQgeCh2YWx1ZSkge1xuICAgICAgICB0aGlzLl94ID0gdmFsdWVcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgeDogdmFsdWUgfSlcbiAgICB9XG5cbiAgICBzZXQgeSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl95ID0gdmFsdWVcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgeTogdmFsdWUgfSlcbiAgICB9XG5cbiAgICBnZXQgcG9zaXRpb24oKSB7XG4gICAgICAgIGxldCB0cmFuc2Zvcm0gPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtXG4gICAgICAgIGxldCB4ID0gdHJhbnNmb3JtLnhcbiAgICAgICAgbGV0IHkgPSB0cmFuc2Zvcm0ueVxuICAgICAgICByZXR1cm4geyB4LCB5IH1cbiAgICB9XG5cbiAgICBnZXQgb3JpZ2luKCkge1xuICAgICAgICBsZXQgcCA9IHRoaXMuZnJvbU5vZGVUb1BhZ2UoMCwgMClcbiAgICAgICAgcmV0dXJuIFBvaW50cy5mcm9tUGFnZVRvTm9kZSh0aGlzLmNvbnRhaW5lci5lbGVtZW50LCBwKVxuICAgIH1cblxuICAgIGdldCBib3VuZHMoKSB7XG4gICAgICAgIGxldCBzdGFnZSA9IHRoaXMuY29udGFpbmVyLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgbGV0IHJlY3QgPSB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRvcDogcmVjdC50b3AgLSBzdGFnZS50b3AsXG4gICAgICAgICAgICBsZWZ0OiByZWN0LmxlZnQgLSBzdGFnZS5sZWZ0LFxuICAgICAgICAgICAgd2lkdGg6IHJlY3Qud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgY2VudGVyKCkge1xuICAgICAgICBsZXQgciA9IHRoaXMuYm91bmRzXG4gICAgICAgIGxldCB3MiA9IHIud2lkdGggLyAyXG4gICAgICAgIGxldCBoMiA9IHIuaGVpZ2h0IC8gMlxuICAgICAgICAvLyAgIGlmICh0aGlzLnJlc2l6YWJsZSkge1xuICAgICAgICAvLyAgICAgICAgICAgICB3MiAqPSB0aGlzLnNjYWxlXG4gICAgICAgIC8vICAgICAgICAgICAgIGgyICo9IHRoaXMuc2NhbGVcbiAgICAgICAgLy8gICAgICAgICB9XG4gICAgICAgIHZhciB4ID0gci5sZWZ0ICsgdzJcbiAgICAgICAgdmFyIHkgPSByLnRvcCArIGgyXG4gICAgICAgIHJldHVybiB7IHgsIHkgfVxuICAgIH1cblxuICAgIHNldCByb3RhdGlvbihyYWRpYW5zKSB7XG4gICAgICAgIGxldCByYWQgPSByYWRpYW5zIC8vIEFuZ2xlLm5vcm1hbGl6ZShyYWRpYW5zKVxuICAgICAgICBsZXQgZGVncmVlcyA9IEFuZ2xlLnJhZGlhbjJkZWdyZWUocmFkKVxuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwgeyByb3RhdGlvbjogZGVncmVlcyB9KVxuICAgICAgICB0aGlzLl9yb3RhdGlvbiA9IHJhZFxuICAgIH1cblxuICAgIHNldCByb3RhdGlvbkRlZ3JlZXMoZGVncmVlcykge1xuICAgICAgICBsZXQgZGVnID0gZGVncmVlcyAvLyBBbmdsZS5ub3JtYWxpemVEZWdyZWUoZGVncmVlcylcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgcm90YXRpb246IGRlZyB9KVxuICAgICAgICB0aGlzLl9yb3RhdGlvbiA9IEFuZ2xlLmRlZ3JlZTJyYWRpYW4oZGVnKVxuICAgIH1cblxuICAgIGdldCByb3RhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JvdGF0aW9uXG4gICAgfVxuXG4gICAgZ2V0IHJvdGF0aW9uRGVncmVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JvdGF0aW9uXG4gICAgfVxuXG4gICAgc2V0IHNjYWxlKHNjYWxlKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7XG4gICAgICAgICAgICBzY2FsZTogc2NhbGUsXG4gICAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW46IHRoaXMudHJhbnNmb3JtT3JpZ2luXG4gICAgICAgIH0pXG4gICAgICAgIHRoaXMuX3NjYWxlID0gc2NhbGVcbiAgICB9XG5cbiAgICBnZXQgc2NhbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY2FsZVxuICAgIH1cblxuICAgIGdldCBjb250YWluZXJCb3VuZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5ib3VuZHNcbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyUG9seWdvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyLnBvbHlnb25cbiAgICB9XG5cbiAgICBtYXBQb3NpdGlvblRvQ29udGFpbmVyUG9pbnQocG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyLm1hcFBvc2l0aW9uVG9Qb2ludChwb2ludClcbiAgICB9XG5cbiAgICBjYXB0dXJlKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB0aGlzLmluaXRpYWxWYWx1ZXMpXG4gICAgfVxuXG4gICAgaGlkZSgpIHtcbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuZWxlbWVudCwgMC4xLCB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnbm9uZScsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiBlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgc2hvdygpIHtcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgZGlzcGxheTogJ2Jsb2NrJyB9KVxuICAgIH1cblxuICAgIHNob3dBdChwLCByb3RhdGlvbkRlZ3JlZXMpIHtcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgICB4OiBwLngsXG4gICAgICAgICAgICB5OiBwLnksXG4gICAgICAgICAgICByb3RhdGlvbjogcm90YXRpb25EZWdyZWVzLFxuICAgICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiB0aGlzLnRyYW5zZm9ybU9yaWdpblxuICAgICAgICB9KVxuICAgIH1cblxuICAgIGJyaW5nVG9Gcm9udCgpIHtcbiAgICAgICAgLy8gdGhpcy5lbGVtZW50LnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KVxuICAgICAgICAvLyB1bzogT24gQ2hvbWUgYW5kIEVsZWN0b24gYXBwZW5kQ2hpbGQgbGVhZHMgdG8gZmxpY2tlclxuICAgICAgICBUd2VlbkxpdGUuc2V0KHRoaXMuZWxlbWVudCwgeyB6SW5kZXg6IERPTVNjYXR0ZXIuekluZGV4KysgfSlcbiAgICB9XG5cbiAgICB0b2dnbGVWaWRlbyhlbGVtZW50KSB7XG4gICAgICAgIGlmIChlbGVtZW50LnBhdXNlZCkge1xuICAgICAgICAgICAgZWxlbWVudC5wbGF5KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnQucGF1c2UoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25UYXAoZXZlbnQsIGludGVyYWN0aW9uLCBwb2ludCkge1xuICAgICAgICBpZiAodGhpcy5zaW11bGF0ZUNsaWNrKSB7XG4gICAgICAgICAgICBsZXQgcCA9IFBvaW50cy5mcm9tUGFnZVRvTm9kZSh0aGlzLmVsZW1lbnQsIHBvaW50KVxuICAgICAgICAgICAgbGV0IGlmcmFtZSA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdpZnJhbWUnKVxuICAgICAgICAgICAgaWYgKGlmcmFtZSkge1xuICAgICAgICAgICAgICAgIGxldCBkb2MgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudFxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gZG9jLmVsZW1lbnRGcm9tUG9pbnQocC54LCBwLnkpXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlbGVtZW50LnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnVklERU8nOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZWxlbWVudC5jdXJyZW50U3JjKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFBvcHVwTWVudSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvcHVwTWVudS5vcGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGdWxsc2NyZWVuOiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5vcGVuKGVsZW1lbnQuY3VycmVudFNyYyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQbGF5OiAoKSA9PiBlbGVtZW50LnBsYXkoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHgsIHkgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2dnbGVWaWRlbyhlbGVtZW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xpY2soKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzRGVzY2VuZGFudChwYXJlbnQsIGNoaWxkKSB7XG4gICAgICAgIGxldCBub2RlID0gY2hpbGQucGFyZW50Tm9kZVxuICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAobm9kZSA9PSBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZyb21QYWdlVG9Ob2RlKHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIFBvaW50cy5mcm9tUGFnZVRvTm9kZSh0aGlzLmVsZW1lbnQsIHsgeCwgeSB9KVxuICAgIH1cblxuICAgIGZyb21Ob2RlVG9QYWdlKHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIFBvaW50cy5mcm9tTm9kZVRvUGFnZSh0aGlzLmVsZW1lbnQsIHsgeCwgeSB9KVxuICAgIH1cblxuICAgIF9tb3ZlKGRlbHRhKSB7XG4gICAgICAgIC8vIFVPOiBXZSBuZWVkIHRvIGtlZXAgVHdlZW5MaXRlJ3MgX2dzVHJhbnNmb3JtIGFuZCB0aGUgcHJpdmF0ZVxuICAgICAgICAvLyBfeCBhbmQgX3kgYXR0cmlidXRlcyBhbGlnbmVkXG4gICAgICAgIGxldCB4ID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybS54XG4gICAgICAgIGxldCB5ID0gdGhpcy5lbGVtZW50Ll9nc1RyYW5zZm9ybS55XG4gICAgICAgIGlmICh0aGlzLm1vdmFibGVYKSB7XG4gICAgICAgICAgICB4ICs9IGRlbHRhLnhcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5tb3ZhYmxlWSkge1xuICAgICAgICAgICAgeSArPSBkZWx0YS55XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5feCA9IHhcbiAgICAgICAgdGhpcy5feSA9IHlcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgeDogeCwgeTogeSB9KVxuICAgIH1cblxuICAgIHJlc2l6ZUFmdGVyVHJhbnNmb3JtKHpvb20pIHtcbiAgICAgICAgLy8gIGxldCB3ID0gdGhpcy53aWR0aCAqIHRoaXMuc2NhbGVcbiAgICAgICAgLy8gICAgICAgICBsZXQgaCA9IHRoaXMuaGVpZ2h0ICogdGhpcy5zY2FsZVxuICAgICAgICAvLyAgICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHdpZHRoOiB3LCBoZWlnaHQ6IGggfSlcbiAgICAgICAgaWYgKHRoaXMub25SZXNpemUpIHtcbiAgICAgICAgICAgIGxldCBldmVudCA9IG5ldyBSZXNpemVFdmVudCh0aGlzLCB7IHdpZHRoOiB3LCBoZWlnaHQ6IGggfSlcbiAgICAgICAgICAgIHRoaXMub25SZXNpemUoZXZlbnQpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmVzaXplQnV0dG9uICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMucmVzaXplQnV0dG9uLnN0eWxlLndpZHRoID0gNTAvdGhpcy5zY2FsZStcInB4XCJcbiAgICAgICAgICAgIC8vIHRoaXMucmVzaXplQnV0dG9uLnN0eWxlLmhlaWdodCA9IDUwL3RoaXMuc2NhbGUrXCJweFwiXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFydFJlc2l6ZShlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ3Jlc2l6ZVN0YXJ0ZWQnKVxuXG4gICAgICAgIGxldCBvbGRQb3N0aXRpb24gPSB7IHg6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLmxlZnQsIHk6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLnRvcCB9XG4gICAgICAgIHRoaXMuYnJpbmdUb0Zyb250KClcblxuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gXCIwJSAwJVwiXG5cbiAgICAgICAgbGV0IG5ld1Bvc3RpdGlvbiA9IHsgeDogJCh0aGlzLmVsZW1lbnQpLnBvc2l0aW9uKCkubGVmdCwgeTogJCh0aGlzLmVsZW1lbnQpLnBvc2l0aW9uKCkudG9wIH1cblxuICAgICAgICBsZXQgb2Zmc2V0ID0gUG9pbnRzLnN1YnRyYWN0KG9sZFBvc3RpdGlvbiwgbmV3UG9zdGl0aW9uKVxuXG4gICAgICAgIHRoaXMub2xkWCA9IGUuY2xpZW50WFxuICAgICAgICB0aGlzLm9sZFkgPSBlLmNsaWVudFlcblxuICAgICAgICBlLnRhcmdldC5zZXRBdHRyaWJ1dGUoJ3Jlc2l6aW5nJywgXCJ0cnVlXCIpXG4gICAgICAgIGUudGFyZ2V0LnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKVxuXG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmVsZW1lbnQsIDAsIHsgY3NzOiB7IGxlZnQ6IFwiKz1cIiArIG9mZnNldC54ICsgXCJweFwiIH0gfSlcbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuZWxlbWVudCwgMCwgeyBjc3M6IHsgdG9wOiBcIis9XCIgKyBvZmZzZXQueSArIFwicHhcIiB9IH0pXG5cbiAgICAgICAgdGhpcy5lbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIH1cblxuICAgIHJlc2l6ZShlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuXG4gICAgICAgIGxldCByb3RhdGlvbiA9IEFuZ2xlLnJhZGlhbjJkZWdyZWUodGhpcy5yb3RhdGlvbilcbiAgICAgICAgcm90YXRpb24gPSAocm90YXRpb24gKyAzNjApICUgMzYwXG4gICAgICAgIGxldCBldmVudCA9IG5ldyBDdXN0b21FdmVudCgncmVzaXplZCcpXG4gICAgICAgIGlmIChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ3Jlc2l6aW5nJykgPT0gXCJ0cnVlXCIpIHtcblxuICAgICAgICAgICAgbGV0IGRlbHRhWCA9IChlLmNsaWVudFggLSB0aGlzLm9sZFgpXG4gICAgICAgICAgICBsZXQgZGVsdGFZID0gKGUuY2xpZW50WSAtIHRoaXMub2xkWSlcblxuICAgICAgICAgICAgbGV0IHIgPSBNYXRoLnNxcnQoTWF0aC5wb3coZGVsdGFYLCAyKSArIE1hdGgucG93KGRlbHRhWSwgMikpXG4gICAgICAgICAgICBsZXQgcGhpID0gQW5nbGUucmFkaWFuMmRlZ3JlZShNYXRoLmF0YW4yKGRlbHRhWCwgZGVsdGFZKSlcblxuICAgICAgICAgICAgcGhpID0gKChwaGkpICsgNjMwKSAlIDM2MFxuICAgICAgICAgICAgbGV0IHJvdCA9ICgocm90YXRpb24gKyA5MCkgKyA2MzApICUgMzYwXG5cbiAgICAgICAgICAgIGxldCBkaWZmQW5nbGUgPSAoKDAgKyByb3QpICsgMzYwKSAlIDM2MFxuICAgICAgICAgICAgbGV0IHBoaUNvcnJlY3RlZCA9IChwaGkgKyBkaWZmQW5nbGUgKyAzNjApICUgMzYwXG5cbiAgICAgICAgICAgIGxldCByZXNpemVXID0gciAqIE1hdGguY29zKEFuZ2xlLmRlZ3JlZTJyYWRpYW4ocGhpQ29ycmVjdGVkKSlcbiAgICAgICAgICAgIGxldCByZXNpemVIID0gLXIgKiBNYXRoLnNpbihBbmdsZS5kZWdyZWUycmFkaWFuKHBoaUNvcnJlY3RlZCkpXG5cbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGggKyByZXNpemVXIC8gdGhpcy5zY2FsZSA+IHRoaXMud2lkdGggKiAwLjMgJiYgdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodCArIHJlc2l6ZUggLyB0aGlzLnNjYWxlID4gdGhpcy5oZWlnaHQgKiAwLjMpIFR3ZWVuTGl0ZS50byh0aGlzLmVsZW1lbnQsIDAsIHsgd2lkdGg6IHRoaXMuZWxlbWVudC5vZmZzZXRXaWR0aCArIHJlc2l6ZVcgLyB0aGlzLnNjYWxlLCBoZWlnaHQ6IHRoaXMuZWxlbWVudC5vZmZzZXRIZWlnaHQgKyByZXNpemVIIC8gdGhpcy5zY2FsZSB9KTtcblxuICAgICAgICAgICAgdGhpcy5vbGRYID0gZS5jbGllbnRYXG4gICAgICAgICAgICB0aGlzLm9sZFkgPSBlLmNsaWVudFlcbiAgICAgICAgICAgIHRoaXMub25SZXNpemluZygpXG5cbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0b3BSZXNpemUoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcblxuICAgICAgICBsZXQgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ3Jlc2l6ZUVuZGVkJylcbiAgICAgICAgbGV0IG9sZFBvc3RpdGlvbiA9IHsgeDogJCh0aGlzLmVsZW1lbnQpLnBvc2l0aW9uKCkubGVmdCwgeTogJCh0aGlzLmVsZW1lbnQpLnBvc2l0aW9uKCkudG9wIH1cbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IFwiNTAlIDUwJVwiXG4gICAgICAgIGxldCBuZXdQb3N0aXRpb24gPSB7IHg6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLmxlZnQsIHk6ICQodGhpcy5lbGVtZW50KS5wb3NpdGlvbigpLnRvcCB9XG4gICAgICAgIGxldCBvZmZzZXQgPSBQb2ludHMuc3VidHJhY3Qob2xkUG9zdGl0aW9uLCBuZXdQb3N0aXRpb24pXG5cbiAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuZWxlbWVudCwgMCwgeyBjc3M6IHsgbGVmdDogXCIrPVwiICsgb2Zmc2V0LnggKyBcInB4XCIgfSB9KVxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5lbGVtZW50LCAwLCB7IGNzczogeyB0b3A6IFwiKz1cIiArIG9mZnNldC55ICsgXCJweFwiIH0gfSlcblxuICAgICAgICBlLnRhcmdldC5zZXRBdHRyaWJ1dGUoJ3Jlc2l6aW5nJywgXCJmYWxzZVwiKVxuXG4gICAgICAgIHRoaXMuZWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICB9XG59XG5cbkRPTVNjYXR0ZXIuekluZGV4ID0gMTAwMFxuIiwiaW1wb3J0IHsgZ2V0SWQgfSBmcm9tICcuL3V0aWxzLmpzJ1xuaW1wb3J0IHsgRE9NU2NhdHRlciB9IGZyb20gJy4vc2NhdHRlci5qcydcbmltcG9ydCB7IEludGVyYWN0aW9uTWFwcGVyIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi5qcydcblxuZXhwb3J0IGNsYXNzIENhcmRMb2FkZXIge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBzcmMsXG4gICAgICAgIHtcbiAgICAgICAgICAgIHggPSAwLFxuICAgICAgICAgICAgeSA9IDAsXG4gICAgICAgICAgICB3aWR0aCA9IDEwMDAsXG4gICAgICAgICAgICBoZWlnaHQgPSA4MDAsXG4gICAgICAgICAgICBtYXhXaWR0aCA9IG51bGwsXG4gICAgICAgICAgICBtYXhIZWlnaHQgPSBudWxsLFxuICAgICAgICAgICAgc2NhbGUgPSAxLFxuICAgICAgICAgICAgbWluU2NhbGUgPSAwLjUsXG4gICAgICAgICAgICBtYXhTY2FsZSA9IDEuNSxcbiAgICAgICAgICAgIHJvdGF0aW9uID0gMFxuICAgICAgICB9ID0ge31cbiAgICApIHtcbiAgICAgICAgdGhpcy5zcmMgPSBzcmNcbiAgICAgICAgdGhpcy54ID0geFxuICAgICAgICB0aGlzLnkgPSB5XG4gICAgICAgIHRoaXMuc2NhbGUgPSBzY2FsZVxuICAgICAgICB0aGlzLnJvdGF0aW9uID0gMFxuICAgICAgICB0aGlzLm1heFNjYWxlID0gbWF4U2NhbGVcbiAgICAgICAgdGhpcy5taW5TY2FsZSA9IG1pblNjYWxlXG4gICAgICAgIHRoaXMud2FudGVkV2lkdGggPSB3aWR0aFxuICAgICAgICB0aGlzLndhbnRlZEhlaWdodCA9IGhlaWdodFxuICAgICAgICB0aGlzLm1heFdpZHRoID0gbWF4V2lkdGggIT0gbnVsbCA/IG1heFdpZHRoIDogd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgdGhpcy5tYXhIZWlnaHQgPSBtYXhIZWlnaHQgIT0gbnVsbCA/IG1heEhlaWdodCA6IHdpbmRvdy5pbm5lckhlaWdodFxuICAgICAgICB0aGlzLmFkZGVkTm9kZSA9IG51bGxcbiAgICAgICAgY29uc29sZS5sb2coe1xuICAgICAgICAgXG4gICAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgIG1heFdpZHRoLFxuICAgICAgICAgICAgbWF4SGVpZ2h0LFxuICAgICAgICAgICBcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICB1bmxvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFkZGVkTm9kZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRlZE5vZGUucmVtb3ZlKClcbiAgICAgICAgICAgIHRoaXMuYWRkZWROb2RlID0gbnVsbFxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgUERGTG9hZGVyIGV4dGVuZHMgQ2FyZExvYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3JjLCB7IHdpZHRoID0gMTY0MCwgaGVpZ2h0ID0gODAwLCBzY2FsZSA9IDEgfSA9IHt9KSB7XG4gICAgICAgIHN1cGVyKHNyYywgeyB3aWR0aCwgaGVpZ2h0LCBzY2FsZSB9KVxuICAgICAgICBpZiAodHlwZW9mIFBERkpTID09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBhbGVydCgnUERGLmpzIG5lZWRlZCcpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsb2FkKGRvbU5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIFBERkpTLmdldERvY3VtZW50KHRoaXMuc3JjKS50aGVuKHBkZiA9PiB7XG4gICAgICAgICAgICAgICAgcGRmLmdldFBhZ2UoMSkudGhlbihwYWdlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHNjYWxlID0gdGhpcy5zY2FsZSAqIGFwcC5yZW5kZXJlci5yZXNvbHV0aW9uXG4gICAgICAgICAgICAgICAgICAgIGxldCBpbnZTY2FsZSA9IDEgLyBzY2FsZVxuICAgICAgICAgICAgICAgICAgICBsZXQgdmlld3BvcnQgPSBwYWdlLmdldFZpZXdwb3J0KHNjYWxlKVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFByZXBhcmUgY2FudmFzIHVzaW5nIFBERiBwYWdlIGRpbWVuc2lvbnMuXG4gICAgICAgICAgICAgICAgICAgIGxldCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKVxuICAgICAgICAgICAgICAgICAgICBsZXQgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpXG4gICAgICAgICAgICAgICAgICAgIGNhbnZhcy5oZWlnaHQgPSB2aWV3cG9ydC5oZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgY2FudmFzLndpZHRoID0gdmlld3BvcnQud2lkdGhcblxuICAgICAgICAgICAgICAgICAgICAvLyBSZW5kZXIgUERGIHBhZ2UgaW50byBjYW52YXMgY29udGV4dC5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlbmRlckNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYW52YXNDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnQ6IHZpZXdwb3J0XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFnZS5yZW5kZXIocmVuZGVyQ29udGV4dClcbiAgICAgICAgICAgICAgICAgICAgZG9tTm9kZS5hcHBlbmRDaGlsZChjYW52YXMpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FudGVkV2lkdGggPSBjYW52YXMud2lkdGhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSBjYW52YXMuaGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NhbGUgPSBpbnZTY2FsZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZGVkTm9kZSA9IGNhbnZhc1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW1hZ2VMb2FkZXIgZXh0ZW5kcyBDYXJkTG9hZGVyIHtcbiAgICBsb2FkKGRvbU5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBpc0ltYWdlID0gZG9tTm9kZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnRcbiAgICAgICAgICAgIGxldCBpbWFnZSA9IGlzSW1hZ2UgPyBkb21Ob2RlIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJylcbiAgICAgICAgICAgIGltYWdlLm9ubG9hZCA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNJbWFnZSkge1xuICAgICAgICAgICAgICAgICAgICBkb21Ob2RlLmFwcGVuZENoaWxkKGltYWdlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZGVkTm9kZSA9IGltYWdlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMud2FudGVkV2lkdGggPSBpbWFnZS5uYXR1cmFsV2lkdGhcbiAgICAgICAgICAgICAgICB0aGlzLndhbnRlZEhlaWdodCA9IGltYWdlLm5hdHVyYWxIZWlnaHRcblxuICAgICAgICAgICAgICAgIGxldCBzY2FsZVcgPSB0aGlzLm1heFdpZHRoIC8gaW1hZ2UubmF0dXJhbFdpZHRoXG4gICAgICAgICAgICAgICAgbGV0IHNjYWxlSCA9IHRoaXMubWF4SGVpZ2h0IC8gaW1hZ2UubmF0dXJhbEhlaWdodFxuICAgICAgICAgICAgICAgIHRoaXMuc2NhbGUgPSBNYXRoLm1pbih0aGlzLm1heFNjYWxlLCBNYXRoLm1pbihzY2FsZVcsIHNjYWxlSCkpXG4gICAgICAgICAgICAgICAgaW1hZ2Uuc2V0QXR0cmlidXRlKCdkcmFnZ2FibGUnLCBmYWxzZSlcbiAgICAgICAgICAgICAgICBpbWFnZS53aWR0aCA9IGltYWdlLm5hdHVyYWxXaWR0aFxuICAgICAgICAgICAgICAgIGltYWdlLmhlaWdodCA9IGltYWdlLm5hdHVyYWxIZWlnaHRcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbWFnZS5vbmVycm9yID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbWFnZS5zcmMgPSB0aGlzLnNyY1xuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZyYW1lTG9hZGVyIGV4dGVuZHMgQ2FyZExvYWRlciB7XG4gICAgbG9hZChkb21Ob2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgaXNGcmFtZSA9IGRvbU5vZGUgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudFxuICAgICAgICAgICAgbGV0IGlmcmFtZSA9IGlzRnJhbWUgPyBkb21Ob2RlIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJylcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdGcmFtZUxvYWRlci5sb2FkJywgaXNGcmFtZSwgaWZyYW1lLCB0aGlzLnNyYylcbiAgICAgICAgICAgIGlmcmFtZS5mcmFtZUJvcmRlciA9IDBcbiAgICAgICAgICAgIGlmcmFtZS5zdHlsZS5zY3JvbGxpbmcgPSBmYWxzZVxuICAgICAgICAgICAgaWZyYW1lLndpZHRoID0gdGhpcy53YW50ZWRXaWR0aFxuICAgICAgICAgICAgaWZyYW1lLmhlaWdodCA9IHRoaXMud2FudGVkSGVpZ2h0XG4gICAgICAgICAgICBpZiAoIWlzRnJhbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBVbmxpa2UgaW1nIG9ubG9hZCBpcyBvbmx5IHRyaWdnZXJlZCBpZiB0aGUgaWZyYW1lIGlzIHBhcnQgb2YgdGhlIERPTSB0cmVlXG4gICAgICAgICAgICAgICAgZG9tTm9kZS5hcHBlbmRDaGlsZChpZnJhbWUpXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZE5vZGUgPSBpZnJhbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmcmFtZS5vbmxvYWQgPSBlID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZnJhbWUub25lcnJvciA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWZyYW1lLnNyYyA9IHRoaXMuc3JjXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgSFRNTExvYWRlciBleHRlbmRzIENhcmRMb2FkZXIge1xuICAgIGxvYWQoZG9tTm9kZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgICAgICB4aHIub3BlbignR0VUJywgdGhpcy5zcmMsIGZhbHNlKVxuICAgICAgICAgICAgeGhyLm9ubG9hZCA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIGRvbU5vZGUuaW5uZXJIVE1MID0geGhyLnJlc3BvbnNlXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZE5vZGUgPSBkb21Ob2RlLmZpcnN0RWxlbWVudENoaWxkXG4gICAgICAgICAgICAgICAgbGV0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5zaXplKHRoaXMuYWRkZWROb2RlKVxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiSFRNTExvYWRlci5sb2FkXCIsIHsgYWRkZWQ6IHRoaXMuYWRkZWROb2RlLCB3aWR0aCwgaGVpZ2h0IH0pXG4gICAgICAgICAgICAgICAgaWYgKHdpZHRoKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gd2lkdGggfHwgdGhpcy53YW50ZWRXaWR0aFxuICAgICAgICAgICAgICAgIGlmIChoZWlnaHQpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2FudGVkSGVpZ2h0ID0gaGVpZ2h0IHx8IHRoaXMud2FudGVkSGVpZ2h0XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeGhyLm9uZXJyb3IgPSBlID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QodGhpcylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHhoci5zZW5kKClcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmllcyB0byBkZXRlcm1pbmUgdGhlIHNpemUgb2YgdGhlIGFkZGVkTm9kZS5cbiAgICAgKiBDaGVja3MgZm9yIGV4cGxpY2l0IHdpZHRoIGFuZCBoZWlnaHQgc3R5bGUgYXR0cmlidXRlcy5cbiAgICAgKiBcbiAgICAgKiBPdmVyd3JpdGUgdGhpcyBtZXRob2QgaWYgeW91IHdhbnQgdG8gZXh0cmFjdCB2YWx1ZXMgZnJvbSBvdGhlciBpbmZvcy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHsgd2lkdGg6IGludCwgaGVpZ2h0OiBpbnQgfVxuICAgICAqIEBtZW1iZXJvZiBIVE1MTG9hZGVyXG4gICAgICovXG4gICAgc2l6ZShub2RlKSB7XG4gICAgICAgIGxldCB3aWR0aCA9IHBhcnNlSW50KG5vZGUuc3R5bGUud2lkdGgpIHx8IG51bGxcbiAgICAgICAgbGV0IGhlaWdodCA9IHBhcnNlSW50KG5vZGUuc3R5bGUuaGVpZ2h0KSB8fCBudWxsXG4gICAgICAgIHJldHVybiB7IHdpZHRoLCBoZWlnaHQgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIERPTUZsaXAge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBkb21TY2F0dGVyQ29udGFpbmVyLFxuICAgICAgICBmbGlwVGVtcGxhdGUsXG4gICAgICAgIGZyb250TG9hZGVyLFxuICAgICAgICBiYWNrTG9hZGVyLFxuICAgICAgICB7XG4gICAgICAgICAgICBjbG9zZU9uTWluU2NhbGUgPSBmYWxzZSxcbiAgICAgICAgICAgIGZsaXBEdXJhdGlvbiA9IDEsXG4gICAgICAgICAgICBmYWRlRHVyYXRpb24gPSAwLjIsXG4gICAgICAgICAgICBvdmVyZG9TY2FsaW5nID0gMSxcbiAgICAgICAgICAgIGF1dG9Mb2FkID0gZmFsc2UsXG4gICAgICAgICAgICBjZW50ZXIgPSBudWxsLFxuICAgICAgICAgICAgcHJlbG9hZEJhY2sgPSBmYWxzZSxcbiAgICAgICAgICAgIHRyYW5zbGF0YWJsZSA9IHRydWUsXG4gICAgICAgICAgICBzY2FsYWJsZSA9IHRydWUsXG4gICAgICAgICAgICByb3RhdGFibGUgPSB0cnVlLFxuICAgICAgICAgICAgb25Gcm9udCA9IG51bGwsXG4gICAgICAgICAgICBvbkJhY2sgPSBudWxsLFxuICAgICAgICAgICAgb25DbG9zZSA9IG51bGwsXG4gICAgICAgICAgICBvblVwZGF0ZSA9IG51bGwsXG4gICAgICAgICAgICBvblJlbW92ZWQgPSBudWxsLFxuICAgICAgICAgICAgb25Mb2FkZWQgPSBudWxsXG4gICAgICAgIH0gPSB7fVxuICAgICkge1xuICAgICAgICB0aGlzLmRvbVNjYXR0ZXJDb250YWluZXIgPSBkb21TY2F0dGVyQ29udGFpbmVyXG4gICAgICAgIHRoaXMuaWQgPSBnZXRJZCgpXG4gICAgICAgIHRoaXMuZmxpcER1cmF0aW9uID0gZmxpcER1cmF0aW9uXG4gICAgICAgIHRoaXMuZmFkZUR1cmF0aW9uID0gZmFkZUR1cmF0aW9uXG4gICAgICAgIHRoaXMuY2xvc2VPbk1pblNjYWxlID0gY2xvc2VPbk1pblNjYWxlXG4gICAgICAgIHRoaXMuZmxpcFRlbXBsYXRlID0gZmxpcFRlbXBsYXRlXG4gICAgICAgIHRoaXMuZnJvbnRMb2FkZXIgPSBmcm9udExvYWRlclxuICAgICAgICB0aGlzLmJhY2tMb2FkZXIgPSBiYWNrTG9hZGVyXG4gICAgICAgIHRoaXMudHJhbnNsYXRhYmxlID0gdHJhbnNsYXRhYmxlXG4gICAgICAgIHRoaXMuc2NhbGFibGUgPSBzY2FsYWJsZVxuICAgICAgICB0aGlzLnJvdGF0YWJsZSA9IHJvdGF0YWJsZVxuICAgICAgICB0aGlzLm9uRnJvbnRGbGlwcGVkID0gb25Gcm9udFxuICAgICAgICB0aGlzLm9uQmFja0ZsaXBwZWQgPSBvbkJhY2tcbiAgICAgICAgdGhpcy5vbkNsb3NlID0gb25DbG9zZVxuICAgICAgICB0aGlzLm9uUmVtb3ZlZCA9IG9uUmVtb3ZlZFxuICAgICAgICB0aGlzLm9uVXBkYXRlID0gb25VcGRhdGVcbiAgICAgICAgdGhpcy5vbkxvYWRlZCA9IG9uTG9hZGVkXG4gICAgICAgIHRoaXMuY2VudGVyID0gY2VudGVyXG4gICAgICAgIHRoaXMucHJlbG9hZEJhY2sgPSBwcmVsb2FkQmFja1xuICAgICAgICB0aGlzLm92ZXJkb1NjYWxpbmcgPSBvdmVyZG9TY2FsaW5nXG4gICAgICAgIGlmIChhdXRvTG9hZCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxvYWQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgdCA9IHRoaXMuZmxpcFRlbXBsYXRlXG4gICAgICAgICAgICBsZXQgZG9tID0gdGhpcy5kb21TY2F0dGVyQ29udGFpbmVyLmVsZW1lbnRcbiAgICAgICAgICAgIGxldCB3cmFwcGVyID0gdC5jb250ZW50LnF1ZXJ5U2VsZWN0b3IoJy5mbGlwV3JhcHBlcicpXG4gICAgICAgICAgICB3cmFwcGVyLmlkID0gdGhpcy5pZFxuICAgICAgICAgICAgbGV0IGNsb25lID0gZG9jdW1lbnQuaW1wb3J0Tm9kZSh0LmNvbnRlbnQsIHRydWUpXG4gICAgICAgICAgICBkb20uYXBwZW5kQ2hpbGQoY2xvbmUpXG4gICAgICAgICAgICAvLyBXZSBjYW5ub3QgdXNlIHRoZSBkb2N1bWVudCBmcmFnbWVudCBpdHNlbGYgYmVjYXVzZSBpdFxuICAgICAgICAgICAgLy8gaXMgbm90IHBhcnQgb2YgdGhlIG1haW4gZG9tIHRyZWUuIEFmdGVyIHRoZSBhcHBlbmRDaGlsZFxuICAgICAgICAgICAgLy8gY2FsbCB3ZSBjYW4gYWNjZXNzIHRoZSBuZXcgZG9tIGVsZW1lbnQgYnkgaWRcbiAgICAgICAgICAgIHRoaXMuY2FyZFdyYXBwZXIgPSBkb20ucXVlcnlTZWxlY3RvcignIycgKyB0aGlzLmlkKVxuICAgICAgICAgICAgbGV0IGZyb250ID0gdGhpcy5jYXJkV3JhcHBlci5xdWVyeVNlbGVjdG9yKCcuZnJvbnQnKVxuICAgICAgICAgICAgdGhpcy5mcm9udExvYWRlci5sb2FkKGZyb250KS50aGVuKGxvYWRlciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5mcm9udExvYWRlZChsb2FkZXIpLnRoZW4oKG9iaikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vbkxvYWRlZCkgdGhpcy5vbkxvYWRlZCgpXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcylcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBmcm9udExvYWRlZChsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBzY2F0dGVyID0gbmV3IERPTVNjYXR0ZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkV3JhcHBlcixcbiAgICAgICAgICAgICAgICB0aGlzLmRvbVNjYXR0ZXJDb250YWluZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB4OiBsb2FkZXIueCxcbiAgICAgICAgICAgICAgICAgICAgeTogbG9hZGVyLnksXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0U2NhbGU6IGxvYWRlci5zY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgc2NhbGU6IGxvYWRlci5zY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4U2NhbGU6IGxvYWRlci5tYXhTY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgbWluU2NhbGU6IGxvYWRlci5taW5TY2FsZSxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGxvYWRlci53YW50ZWRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBsb2FkZXIud2FudGVkSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICByb3RhdGlvbjogbG9hZGVyLnJvdGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGFibGU6IHRoaXMudHJhbnNsYXRhYmxlLFxuICAgICAgICAgICAgICAgICAgICBzY2FsYWJsZTogdGhpcy5zY2FsYWJsZSxcbiAgICAgICAgICAgICAgICAgICAgcm90YXRhYmxlOiB0aGlzLnJvdGF0YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmRvU2NhbGluZzogdGhpcy5vdmVyZG9TY2FsaW5nXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jZW50ZXIpIHtcbiAgICAgICAgICAgICAgICBzY2F0dGVyLmNlbnRlckF0KHRoaXMuY2VudGVyKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jbG9zZU9uTWluU2NhbGUpIHtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbW92ZU9uTWluU2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY2F0dGVyLnNjYWxlIDw9IHNjYXR0ZXIubWluU2NhbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmxpcHBhYmxlLmNsb3NlKClcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gJ0Rpc2FibGUnIG92ZXJkb3NjYWxpbmcgdG8gYXZvaWQgd2VpcmQganVtcHMgb24gY2xvc2UuXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2F0dGVyLm1pblNjYWxlIC89IHNjYXR0ZXIub3ZlcmRvU2NhbGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NhdHRlci5vdmVyZG9TY2FsaW5nID0gMVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAvL1JlbW92ZSBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjYXR0ZXIub25UcmFuc2Zvcm0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2FsbGJhY2tJZHggPSBzY2F0dGVyLm9uVHJhbnNmb3JtLmluZGV4T2YocmVtb3ZlT25NaW5TY2FsZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2F0dGVyLm9uVHJhbnNmb3JtLnNwbGljZShjYWxsYmFja0lkeCwgMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpXG5cblxuXG4gICAgICAgICAgICAgICAgc2NhdHRlci5hZGRUcmFuc2Zvcm1FdmVudENhbGxiYWNrKHJlbW92ZU9uTWluU2NhbGUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBmbGlwcGFibGUgPSBuZXcgRE9NRmxpcHBhYmxlKHRoaXMuY2FyZFdyYXBwZXIsIHNjYXR0ZXIsIHRoaXMpXG4gICAgICAgICAgICBsZXQgYmFjayA9IHRoaXMuY2FyZFdyYXBwZXIucXVlcnlTZWxlY3RvcignLmJhY2snKVxuXG4gICAgICAgICAgICBpZiAodGhpcy5wcmVsb2FkQmFjaykge1xuICAgICAgICAgICAgICAgIHRoaXMuYmFja0xvYWRlci5sb2FkKGJhY2spLnRoZW4obG9hZGVyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR1cEZsaXBwYWJsZShmbGlwcGFibGUsIGxvYWRlcilcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mbGlwcGFibGUgPSBmbGlwcGFibGVcbiAgICAgICAgICAgIHJlc29sdmUodGhpcylcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBjZW50ZXJBdChwKSB7XG4gICAgICAgIHRoaXMuY2VudGVyID0gcFxuICAgICAgICB0aGlzLmZsaXBwYWJsZS5jZW50ZXJBdChwKVxuICAgIH1cblxuICAgIHpvb20oc2NhbGUpIHtcbiAgICAgICAgdGhpcy5mbGlwcGFibGUuem9vbShzY2FsZSlcbiAgICB9XG5cbiAgICBzZXR1cEZsaXBwYWJsZShmbGlwcGFibGUsIGxvYWRlcikge1xuICAgICAgICBmbGlwcGFibGUud2FudGVkV2lkdGggPSBsb2FkZXIud2FudGVkV2lkdGhcbiAgICAgICAgZmxpcHBhYmxlLndhbnRlZEhlaWdodCA9IGxvYWRlci53YW50ZWRIZWlnaHRcbiAgICAgICAgZmxpcHBhYmxlLndhbnRlZFNjYWxlID0gbG9hZGVyLnNjYWxlXG4gICAgICAgIGZsaXBwYWJsZS5taW5TY2FsZSA9IGxvYWRlci5taW5TY2FsZVxuICAgICAgICBmbGlwcGFibGUubWF4U2NhbGUgPSBsb2FkZXIubWF4U2NhbGVcbiAgICAgICAgZmxpcHBhYmxlLnNjYWxlQnV0dG9ucygpXG4gICAgfVxuXG4gICAgc3RhcnQoeyB0YXJnZXRDZW50ZXIgPSBudWxsIH0gPSB7fSkge1xuICAgICAgICBjb25zb2xlLmxvZygnRE9NRmxpcC5zdGFydCcsIHRhcmdldENlbnRlcilcbiAgICAgICAgaWYgKHRoaXMucHJlbG9hZEJhY2spIHRoaXMuZmxpcHBhYmxlLnN0YXJ0KHsgZHVyYXRpb246IHRoaXMuZmxpcER1cmF0aW9uLCB0YXJnZXRDZW50ZXIgfSlcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgYmFjayA9IHRoaXMuY2FyZFdyYXBwZXIucXVlcnlTZWxlY3RvcignLmJhY2snKVxuICAgICAgICAgICAgbGV0IGZsaXBwYWJsZSA9IHRoaXMuZmxpcHBhYmxlXG4gICAgICAgICAgICB0aGlzLmJhY2tMb2FkZXIubG9hZChiYWNrKS50aGVuKGxvYWRlciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXR1cEZsaXBwYWJsZShmbGlwcGFibGUsIGxvYWRlcilcbiAgICAgICAgICAgICAgICBmbGlwcGFibGUuc3RhcnQoeyBkdXJhdGlvbjogdGhpcy5mbGlwRHVyYXRpb24sIHRhcmdldENlbnRlciB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZhZGVPdXRBbmRSZW1vdmUoKSB7XG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNhcmRXcmFwcGVyLCB0aGlzLmZhZGVEdXJhdGlvbiwge1xuICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhcmRXcmFwcGVyLnJlbW92ZSgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgY2xvc2VkKCkge1xuICAgICAgICB0aGlzLnVubG9hZCgpXG4gICAgfVxuXG4gICAgdW5sb2FkKCkge1xuICAgICAgICBpZiAoIXRoaXMucHJlbG9hZEJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuYmFja0xvYWRlci51bmxvYWQoKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRE9NRmxpcHBhYmxlIHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBzY2F0dGVyLCBmbGlwKSB7XG4gICAgICAgIC8vIFNldCBsb2cgdG8gY29uc29sZS5sb2cgb3IgYSBjdXN0b20gbG9nIGZ1bmN0aW9uXG4gICAgICAgIC8vIGRlZmluZSBkYXRhIHN0cnVjdHVyZXMgdG8gc3RvcmUgb3VyIHRvdWNocG9pbnRzIGluXG5cbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudFxuICAgICAgICB0aGlzLmZsaXAgPSBmbGlwXG4gICAgICAgIHRoaXMuY2FyZCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmZsaXBDYXJkJylcbiAgICAgICAgdGhpcy5mcm9udCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmZyb250JylcbiAgICAgICAgdGhpcy5iYWNrID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuYmFjaycpXG4gICAgICAgIHRoaXMuZmxpcHBlZCA9IGZhbHNlXG4gICAgICAgIHRoaXMuc2NhdHRlciA9IHNjYXR0ZXJcbiAgICAgICAgdGhpcy5vbkZyb250RmxpcHBlZCA9IGZsaXAub25Gcm9udEZsaXBwZWRcbiAgICAgICAgdGhpcy5vbkJhY2tGbGlwcGVkID0gZmxpcC5vbkJhY2tGbGlwcGVkXG4gICAgICAgIHRoaXMub25DbG9zZSA9IGZsaXAub25DbG9zZVxuICAgICAgICB0aGlzLm9uUmVtb3ZlZCA9IGZsaXAub25SZW1vdmVkXG4gICAgICAgIHRoaXMub25VcGRhdGUgPSBmbGlwLm9uVXBkYXRlXG5cbiAgICAgICAgdGhpcy5mbGlwRHVyYXRpb24gPSBmbGlwLmZsaXBEdXJhdGlvblxuICAgICAgICB0aGlzLmZhZGVEdXJhdGlvbiA9IGZsaXAuZmFkZUR1cmF0aW9uXG4gICAgICAgIHNjYXR0ZXIuYWRkVHJhbnNmb3JtRXZlbnRDYWxsYmFjayh0aGlzLnNjYXR0ZXJUcmFuc2Zvcm1lZC5iaW5kKHRoaXMpKVxuICAgICAgICBjb25zb2xlLmxvZygnbGliLkRPTUZsaXBwYWJsZScsIDUwMDApXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5lbGVtZW50LCB7IHBlcnNwZWN0aXZlOiA1MDAwIH0pXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5jYXJkLCB7IHRyYW5zZm9ybVN0eWxlOiAncHJlc2VydmUtM2QnIH0pXG4gICAgICAgIFR3ZWVuTGl0ZS5zZXQodGhpcy5iYWNrLCB7IHJvdGF0aW9uWTogLTE4MCB9KVxuICAgICAgICBUd2VlbkxpdGUuc2V0KFt0aGlzLmJhY2ssIHRoaXMuZnJvbnRdLCB7XG4gICAgICAgICAgICBiYWNrZmFjZVZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICAgICAgcGVyc3BlY3RpdmU6IDUwMDBcbiAgICAgICAgfSlcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmZyb250LCB7IHZpc2liaWxpdHk6ICd2aXNpYmxlJyB9KVxuICAgICAgICB0aGlzLmluZm9CdG4gPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbmZvQnRuJylcbiAgICAgICAgdGhpcy5iYWNrQnRuID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuYmFja0J0bicpXG4gICAgICAgIHRoaXMuY2xvc2VCdG4gPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jbG9zZUJ0bicpXG4gICAgICAgIC8qIEJ1dHRvbnMgYXJlIG5vdCBndWFyYW50ZWVkIHRvIGV4aXN0LiAqL1xuICAgICAgICBpZiAodGhpcy5pbmZvQnRuKSB7XG4gICAgICAgICAgICBJbnRlcmFjdGlvbk1hcHBlci5vbigndGFwJywgdGhpcy5pbmZvQnRuLCBldmVudCA9PiB0aGlzLmZsaXAuc3RhcnQoKSlcblxuICAgICAgICAgICAgdGhpcy5lbmFibGUodGhpcy5pbmZvQnRuKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmJhY2tCdG4pIHtcbiAgICAgICAgICAgIEludGVyYWN0aW9uTWFwcGVyLm9uKCd0YXAnLCB0aGlzLmJhY2tCdG4sIGV2ZW50ID0+IHRoaXMuc3RhcnQoKSlcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jbG9zZUJ0bikge1xuICAgICAgICAgICAgSW50ZXJhY3Rpb25NYXBwZXIub24oJ3RhcCcsIHRoaXMuY2xvc2VCdG4sIGV2ZW50ID0+IHRoaXMuY2xvc2UoKSlcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlKHRoaXMuY2xvc2VCdG4pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zY2FsZUJ1dHRvbnMoKVxuICAgICAgICB0aGlzLmJyaW5nVG9Gcm9udCgpXG4gICAgfVxuXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZSh0aGlzLmluZm9CdG4pXG4gICAgICAgIHRoaXMuZGlzYWJsZSh0aGlzLmNsb3NlQnRuKVxuICAgICAgICBpZiAodGhpcy5vbkNsb3NlKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xvc2UodGhpcylcbiAgICAgICAgICAgIHRoaXMuZmxpcC5jbG9zZWQoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnpvb20oMC4xLCB7XG4gICAgICAgICAgICAgICAgYW5pbWF0ZTogdGhpcy5mYWRlRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mbGlwLmNsb3NlZCgpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9uUmVtb3ZlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vblJlbW92ZWQuY2FsbCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNob3dGcm9udCgpIHtcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmZyb250LCB7IHZpc2liaWxpdHk6ICd2aXNpYmxlJyB9KVxuICAgIH1cblxuICAgIGNlbnRlckF0KHApIHtcbiAgICAgICAgdGhpcy5zY2F0dGVyLmNlbnRlckF0KHApXG4gICAgfVxuXG4gICAgem9vbShzY2FsZSkge1xuICAgICAgICB0aGlzLnNjYXR0ZXIuem9vbShzY2FsZSlcbiAgICB9XG5cbiAgICBnZXQgYnV0dG9uU2NhbGUoKSB7XG4gICAgICAgIGxldCBpc2NhbGUgPSAxLjBcblxuICAgICAgICBpZiAodGhpcy5zY2F0dGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBzY2FsZSA9IHRoaXMuc2NhdHRlci5zY2FsZSB8fCAxXG4gICAgICAgICAgICBpc2NhbGUgPSAxLjAgLyBzY2FsZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc2NhbGVcbiAgICB9XG5cbiAgICBzY2FsZUJ1dHRvbnMoKSB7XG4gICAgICAgIC8vVGhpcyBhbHNvIHdvcmtzIGZvciBzdmdzLlxuICAgICAgICAvLyBpZiAodGhpcy5pbmZvQnRuKVxuICAgICAgICAvLyAgICAgdGhpcy5pbmZvQnRuLnN0eWxlLnRyYW5zZm9ybSA9IFwic2NhbGUoXCIgKyB0aGlzLmJ1dHRvblNjYWxlICsgXCIpXCJcblxuICAgICAgICAvLyBpZiAodGhpcy5iYWNrQnRuKVxuICAgICAgICAvLyAgICAgdGhpcy5iYWNrQnRuLnN0eWxlLnRyYW5zZm9ybSA9IFwic2NhbGUoXCIgKyB0aGlzLmJ1dHRvblNjYWxlICsgXCIpXCJcblxuICAgICAgICAvLyBpZiAodGhpcy5jbG9zZUJ0bilcbiAgICAgICAgLy8gICAgIHRoaXMuY2xvc2VCdG4uc3R5bGUudHJhbnNmb3JtID0gXCJzY2FsZShcIiArIHRoaXMuYnV0dG9uU2NhbGUgKyBcIilcIlxuXG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuYnV0dG9uU2NhbGUpXG4gICAgICAgIC8vLy8gVGhpcyBkaWQgbm90IHdvcmsgd2l0aCBzdmdzIVxuICAgICAgICBUd2VlbkxpdGUuc2V0KFt0aGlzLmluZm9CdG4sIHRoaXMuYmFja0J0biwgdGhpcy5jbG9zZUJ0bl0sIHtcbiAgICAgICAgICAgIHNjYWxlOiB0aGlzLmJ1dHRvblNjYWxlXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgYnJpbmdUb0Zyb250KCkge1xuICAgICAgICB0aGlzLnNjYXR0ZXIuYnJpbmdUb0Zyb250KClcbiAgICAgICAgVHdlZW5MaXRlLnNldCh0aGlzLmVsZW1lbnQsIHsgekluZGV4OiBET01TY2F0dGVyLnpJbmRleCsrIH0pXG4gICAgfVxuXG4gICAgY2xpY2tJbmZvKCkge1xuICAgICAgICB0aGlzLmJyaW5nVG9Gcm9udCgpXG4gICAgICAgIHRoaXMuaW5mb0J0bi5jbGljaygpXG4gICAgfVxuXG4gICAgc2NhdHRlclRyYW5zZm9ybWVkKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2NhbGVCdXR0b25zKClcbiAgICB9XG5cbiAgICB0YXJnZXRSb3RhdGlvbihhbHBoYSkge1xuICAgICAgICBsZXQgb3J0aG8gPSA5MFxuICAgICAgICBsZXQgcmVzdCA9IGFscGhhICUgb3J0aG9cbiAgICAgICAgbGV0IGRlbHRhID0gMC4wXG4gICAgICAgIGlmIChyZXN0ID4gb3J0aG8gLyAyLjApIHtcbiAgICAgICAgICAgIGRlbHRhID0gb3J0aG8gLSByZXN0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWx0YSA9IC1yZXN0XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlbHRhXG4gICAgfVxuXG4gICAgaW5mb1ZhbHVlcyhpbmZvKSB7XG4gICAgICAgIGxldCBzdGFydFggPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnhcbiAgICAgICAgbGV0IHN0YXJ0WSA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ueVxuICAgICAgICBsZXQgc3RhcnRBbmdsZSA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ucm90YXRpb25cbiAgICAgICAgbGV0IHN0YXJ0U2NhbGUgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnNjYWxlWFxuICAgICAgICBsZXQgdyA9IHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aFxuICAgICAgICBsZXQgaCA9IHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHRcbiAgICAgICAgY29uc29sZS5sb2coaW5mbywgc3RhcnRYLCBzdGFydFksIHN0YXJ0QW5nbGUsIHN0YXJ0U2NhbGUsIHcsIGgpXG4gICAgfVxuXG4gICAgc2hvdyhlbGVtZW50LCBkdXJhdGlvbiA9IDAsIGFscGhhID0gMSkge1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKGVsZW1lbnQsIGR1cmF0aW9uLCB7IGF1dG9BbHBoYTogYWxwaGEgfSkgLy8gdmlzaWJpbGl0eTogJ3Zpc2libGUnLCBkaXNwbGF5OiAnaW5pdGlhbCd9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGlkZShlbGVtZW50LCBkdXJhdGlvbiA9IDAsIGFscGhhID0gMCkge1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKGVsZW1lbnQsIGR1cmF0aW9uLCB7IGF1dG9BbHBoYTogYWxwaGEgfSkgLy8ge3Zpc2liaWxpdHk6ICdoaWRkZW4nLCBkaXNwbGF5OiAnbm9uZSd9KVxuICAgICAgICB9XG4gICAgfVxuXG5cblxuICAgIGVuYWJsZShidXR0b24pIHtcbiAgICAgICAgdGhpcy5zaG93KGJ1dHRvbiwgdGhpcy5mYWRlRHVyYXRpb24pXG4gICAgICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS5zZXQoYnV0dG9uLCB7IHBvaW50ZXJFdmVudHM6ICdhdXRvJyB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZShidXR0b24pIHtcbiAgICAgICAgdGhpcy5oaWRlKGJ1dHRvbiwgdGhpcy5mYWRlRHVyYXRpb24pXG4gICAgICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS5zZXQoYnV0dG9uLCB7IHBvaW50ZXJFdmVudHM6ICdub25lJyB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhcnQoeyB0YXJnZXRDZW50ZXIgPSBudWxsIH0gPSB7fSkge1xuICAgICAgICB0aGlzLmJyaW5nVG9Gcm9udCgpXG4gICAgICAgIGlmICghdGhpcy5mbGlwcGVkKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0WCA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ueFxuICAgICAgICAgICAgdGhpcy5zdGFydFkgPSB0aGlzLmVsZW1lbnQuX2dzVHJhbnNmb3JtLnlcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBbmdsZSA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0ucm90YXRpb25cbiAgICAgICAgICAgIHRoaXMuc3RhcnRTY2FsZSA9IHRoaXMuZWxlbWVudC5fZ3NUcmFuc2Zvcm0uc2NhbGVYXG4gICAgICAgICAgICB0aGlzLnN0YXJ0V2lkdGggPSB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGhcbiAgICAgICAgICAgIHRoaXMuc3RhcnRIZWlnaHQgPSB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0XG4gICAgICAgICAgICB0aGlzLnNjYXR0ZXJTdGFydFdpZHRoID0gdGhpcy5zY2F0dGVyLndpZHRoXG4gICAgICAgICAgICB0aGlzLnNjYXR0ZXJTdGFydEhlaWdodCA9IHRoaXMuc2NhdHRlci5oZWlnaHRcbiAgICAgICAgICAgIHRoaXMuc2hvdyh0aGlzLmJhY2spXG4gICAgICAgICAgICB0aGlzLmRpc2FibGUodGhpcy5pbmZvQnRuKVxuICAgICAgICAgICAgdGhpcy5kaXNhYmxlKHRoaXMuY2xvc2VCdG4pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNob3codGhpcy5mcm9udCwgdGhpcy5mYWRlRHVyYXRpb24pXG4gICAgICAgICAgICB0aGlzLmRpc2FibGUodGhpcy5iYWNrQnRuKVxuICAgICAgICB9XG4gICAgICAgIGxldCB7IHNjYWxhYmxlLCB0cmFuc2xhdGFibGUsIHJvdGF0YWJsZSB9ID0gdGhpcy5zY2F0dGVyXG4gICAgICAgIHRoaXMuc2F2ZWQgPSB7IHNjYWxhYmxlLCB0cmFuc2xhdGFibGUsIHJvdGF0YWJsZSB9XG4gICAgICAgIHRoaXMuc2NhdHRlci5zY2FsYWJsZSA9IGZhbHNlXG4gICAgICAgIHRoaXMuc2NhdHRlci50cmFuc2xhdGFibGUgPSBmYWxzZVxuICAgICAgICB0aGlzLnNjYXR0ZXIucm90YXRhYmxlID0gZmFsc2VcbiAgICAgICAgdGhpcy5zY2F0dGVyLmtpbGxBbmltYXRpb24oKVxuXG4gICAgICAgIHRoaXMuZmxpcHBlZCA9ICF0aGlzLmZsaXBwZWRcbiAgICAgICAgbGV0IHRhcmdldFkgPSB0aGlzLmZsaXBwZWQgPyAxODAgOiAwXG4gICAgICAgIGxldCB0YXJnZXRaID0gdGhpcy5mbGlwcGVkXG4gICAgICAgICAgICA/IHRoaXMuc3RhcnRBbmdsZSArIHRoaXMudGFyZ2V0Um90YXRpb24odGhpcy5zdGFydEFuZ2xlKVxuICAgICAgICAgICAgOiB0aGlzLnN0YXJ0QW5nbGVcbiAgICAgICAgbGV0IHRhcmdldFNjYWxlID0gdGhpcy5mbGlwcGVkID8gdGhpcy53YW50ZWRTY2FsZSA6IHRoaXMuc3RhcnRTY2FsZVxuICAgICAgICBsZXQgdyA9IHRoaXMuZmxpcHBlZCA/IHRoaXMud2FudGVkV2lkdGggOiB0aGlzLnN0YXJ0V2lkdGhcbiAgICAgICAgbGV0IGggPSB0aGlzLmZsaXBwZWQgPyB0aGlzLndhbnRlZEhlaWdodCA6IHRoaXMuc3RhcnRIZWlnaHRcbiAgICAgICAgbGV0IGR3ID0gdGhpcy53YW50ZWRXaWR0aCAtIHRoaXMuc2NhdHRlci53aWR0aFxuICAgICAgICBsZXQgZGggPSB0aGlzLndhbnRlZEhlaWdodCAtIHRoaXMuc2NhdHRlci5oZWlnaHRcbiAgICAgICAgbGV0IHRjID0gdGFyZ2V0Q2VudGVyXG4gICAgICAgIGxldCB4eCA9IHRjICE9IG51bGwgPyB0Yy54IC0gdyAvIDIgOiB0aGlzLnN0YXJ0WCAtIGR3IC8gMlxuICAgICAgICBsZXQgeXkgPSB0YyAhPSBudWxsID8gdGMueSAtIGggLyAyIDogdGhpcy5zdGFydFkgLSBkaCAvIDJcbiAgICAgICAgbGV0IHggPSB0aGlzLmZsaXBwZWQgPyB4eCA6IHRoaXMuc3RhcnRYXG4gICAgICAgIGxldCB5ID0gdGhpcy5mbGlwcGVkID8geXkgOiB0aGlzLnN0YXJ0WVxuXG4gICAgICAgIGNvbnNvbGUubG9nKFwiRE9NRmxpcHBhYmxlLnN0YXJ0XCIsIHRoaXMuZmxpcHBlZCwgdGFyZ2V0Q2VudGVyLCB4LCB5LCB0aGlzLnNhdmVkKVxuICAgICAgICBsZXQgb25VcGRhdGUgPSB0aGlzLm9uVXBkYXRlICE9PSBudWxsID8gKCkgPT4gdGhpcy5vblVwZGF0ZSh0aGlzKSA6IG51bGxcbiAgICAgICAgY29uc29sZS5sb2codGhpcy5mbGlwRHVyYXRpb24pXG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNhcmQsIHRoaXMuZmxpcER1cmF0aW9uLCB7XG4gICAgICAgICAgICByb3RhdGlvblk6IHRhcmdldFksXG4gICAgICAgICAgICBlYXNlOiBQb3dlcjEuZWFzZU91dCxcbiAgICAgICAgICAgIHRyYW5zZm9ybU9yaWdpbjogJzUwJSA1MCUnLFxuICAgICAgICAgICAgb25VcGRhdGUsXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiBlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5mbGlwcGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy5oaWRlKHRoaXMuZnJvbnQpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlKHRoaXMuYmFja0J0bilcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93KHRoaXMuYmFja0J0bilcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vbkZyb250RmxpcHBlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZyb250RmxpcHBlZCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vbkJhY2tGbGlwcGVkID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlKHRoaXMuaW5mb0J0biwgdGhpcy5mYWRlRHVyYXRpb24pXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSh0aGlzLmNsb3NlQnRuLCB0aGlzLmZhZGVEdXJhdGlvbilcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25CYWNrRmxpcHBlZCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmxpcC51bmxvYWQoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnNjYXR0ZXIuc2NhbGUgPSB0YXJnZXRTY2FsZVxuICAgICAgICAgICAgICAgIHRoaXMuc2NhbGVCdXR0b25zKClcbiAgICAgICAgICAgICAgICB0aGlzLnNjYXR0ZXIucm90YXRpb25EZWdyZWVzID0gdGFyZ2V0WlxuICAgICAgICAgICAgICAgIHRoaXMuc2NhdHRlci53aWR0aCA9IHRoaXMuZmxpcHBlZCA/IHcgOiB0aGlzLnNjYXR0ZXJTdGFydFdpZHRoXG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLmhlaWdodCA9IHRoaXMuZmxpcHBlZCA/IGggOiB0aGlzLnNjYXR0ZXJTdGFydEhlaWdodFxuXG4gICAgICAgICAgICAgICAgbGV0IHsgc2NhbGFibGUsIHRyYW5zbGF0YWJsZSwgcm90YXRhYmxlIH0gPSB0aGlzLnNhdmVkXG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnNjYWxhYmxlID0gc2NhbGFibGVcbiAgICAgICAgICAgICAgICB0aGlzLnNjYXR0ZXIudHJhbnNsYXRhYmxlID0gdHJhbnNsYXRhYmxlXG4gICAgICAgICAgICAgICAgdGhpcy5zY2F0dGVyLnJvdGF0YWJsZSA9IHJvdGF0YWJsZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZvcmNlM0Q6IHRydWVcbiAgICAgICAgfSlcblxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9ncmVlbnNvY2suY29tL2ZvcnVtcy90b3BpYy83OTk3LXJvdGF0ZS10aGUtc2hvcnRlc3Qtd2F5L1xuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5lbGVtZW50LCB0aGlzLmZsaXBEdXJhdGlvbiAvIDIsIHtcbiAgICAgICAgICAgIHNjYWxlOiB0YXJnZXRTY2FsZSxcbiAgICAgICAgICAgIGVhc2U6IFBvd2VyMS5lYXNlT3V0LFxuICAgICAgICAgICAgcm90YXRpb25aOiB0YXJnZXRaICsgJ19zaG9ydCcsXG4gICAgICAgICAgICB0cmFuc2Zvcm1PcmlnaW46ICc1MCUgNTAlJyxcbiAgICAgICAgICAgIHdpZHRoOiB3LFxuICAgICAgICAgICAgaGVpZ2h0OiBoLFxuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiBlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5mbGlwcGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGlkZSh0aGlzLmZyb250KVxuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLmhpZGUodGhpcy5pbmZvQnRuKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGlkZSh0aGlzLmJhY2spXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuc2hvdyh0aGlzLmluZm9CdG4pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cbn1cbiIsIlxuZXhwb3J0IGNvbnN0IGRlZXBab29tVGlsZUNhY2hlID0gbmV3IE1hcCgpXG5cblxuLyoqIFRoZSBjdXJyZW50IFRpbGUgaW1wbGVtZW50YXRpb24gc2ltcGx5IHVzZXMgUElYSS5TcHJpdGVzLlxuICpcbiAqIEJUVzogUElYSS5leHRyYXMuVGlsaW5nU3ByaXRlIGlzIG5vdCBhcHByb3ByaWF0ZS4gSXQgc2hvdWxkIGJlIHVzZWQgZm9yXG4gKiByZXBlYXRpbmcgcGF0dGVybnMuXG4gKiovXG5leHBvcnQgY2xhc3MgVGlsZSBleHRlbmRzIFBJWEkuU3ByaXRlIHtcbiAgICBjb25zdHJ1Y3Rvcih0ZXh0dXJlLCB1cmwpIHtcbiAgICAgICAgc3VwZXIodGV4dHVyZSlcbiAgICAgICAgdGhpcy51cmwgPSB1cmxcbiAgICAgICAgdGhpcy5yZWdpc3Rlcih1cmwpXG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21JbWFnZShpbWFnZUlkLCBjcm9zc29yaWdpbiwgc2NhbGVNb2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlsZShQSVhJLlRleHR1cmUuZnJvbUltYWdlKGltYWdlSWQsIGNyb3Nzb3JpZ2luLCBzY2FsZU1vZGUpLCBpbWFnZUlkKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVycyB0aGUgdGlsZSBpbiB0aGUgZ2xvYmFsIHJlZmVyZW5jZSBjb3VudGVyIGZvciB0ZXh0dXJlc1xuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB1cmxcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtkZWJ1Zz1mYWxzZV1cbiAgICAgKiBAbWVtYmVyb2YgVGlsZVxuICAgICAqL1xuICAgIHJlZ2lzdGVyKHVybCwgZGVidWcgPSBmYWxzZSkge1xuICAgICAgICBpZiAoZGVlcFpvb21UaWxlQ2FjaGUuaGFzKHVybCkpIHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IGRlZXBab29tVGlsZUNhY2hlLmdldCh1cmwpXG4gICAgICAgICAgICB0aWxlcy5hZGQodGhpcylcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJUaWxlLnJlZ2lzdGVyXCIsIHVybCwgdGlsZXMuc2l6ZSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlZXBab29tVGlsZUNhY2hlLnNldCh1cmwsIG5ldyBTZXQoW3RoaXNdKSlcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJUaWxlLnJlZ2lzdGVyXCIsIHVybCwgMSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVucmVnaXN0ZXJzIHRoZSByaWxlIGluIHRoZSBnbG9iYWwgcmVmZXJlbmNlIGNvdW50ZXIgZm9yIHRleHR1cmVzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGhvdyBvZnRlbiBhIHRleHR1cmUgaXMgdXNlZC5cbiAgICAgKiBAbWVtYmVyb2YgVGlsZVxuICAgICAqL1xuICAgIHVucmVnaXN0ZXIoKSB7XG4gICAgICAgIGxldCB0aWxlcyA9IGRlZXBab29tVGlsZUNhY2hlLmdldCh0aGlzLnVybClcbiAgICAgICAgdGlsZXMuZGVsZXRlKHRoaXMpXG4gICAgICAgIGlmICh0aWxlcy5zaXplID09IDApIHtcbiAgICAgICAgICAgIGRlZXBab29tVGlsZUNhY2hlLmRlbGV0ZSh0aGlzLnVybClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlsZXMuc2l6ZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlc3Ryb3lzIHRoaXMgc3ByaXRlIGFuZCBvcHRpb25hbGx5IGl0cyB0ZXh0dXJlIGFuZCBjaGlsZHJlblxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBvcHRpb25zICBQYXJ0IG9mIHRoZSBQSVhJIEFQSSwgYnV0IGlnbm9yZWQgaW4gdGhlIGltcGxlbWVudGF0aW9uXG4gICAgICogQG1lbWJlcm9mIFRpbGVcbiAgICAgKi9cbiAgICBkZXN0cm95KG9wdGlvbnMsIGRlYnVnID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50ICE9IG51bGwpIHtcblxuICAgICAgICB9XG4gICAgICAgIGxldCBjb3VudCA9IHRoaXMudW5yZWdpc3RlcigpXG4gICAgICAgIGlmIChjb3VudCA8PSAwKSB7XG4gICAgICAgICAgICBsZXQgb3B0cyA9IHsgY2hpbGRyZW46IHRydWUsIHRleHR1cmU6IHRydWUsIGJhc2VUZXh0dXJlOiB0cnVlIH1cbiAgICAgICAgICAgIHN1cGVyLmRlc3Ryb3kob3B0cylcbiAgICAgICAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5sb2coXCJUaWxlLmRlc3Ryb3lcIiwgZGVlcFpvb21UaWxlQ2FjaGUuc2l6ZSwgb3B0cylcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvcHRzID0geyBjaGlsZHJlbjogdHJ1ZSwgdGV4dHVyZTogZmFsc2UsIGJhc2VUZXh0dXJlOiBmYWxzZSB9XG4gICAgICAgICAgICBpZiAoZGVidWcpIGNvbnNvbGUubG9nKFwiVGlsZS5kZXN0cm95XCIsIGRlZXBab29tVGlsZUNhY2hlLnNpemUsIG9wdHMpXG4gICAgICAgICAgICBzdXBlci5kZXN0cm95KG9wdHMpXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBkZWVwWm9vbVRpbGVDYWNoZSwgVGlsZSB9IGZyb20gJy4vdGlsZS5qcydcblxuLyoqXG4gKiBBIFRpbGUgTG9hZGVyIGNvbXBvbmVudCB0aGF0IGNhbiBiZSBwbHVnZ2VkIGludG8gYSBUaWxlcyBMYXllci5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpbGVMb2FkZXIge1xuICAgIGNvbnN0cnVjdG9yKHRpbGVzKSB7XG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZVxuICAgICAgICB0aGlzLnRpbGVzID0gdGlsZXNcbiAgICAgICAgdGhpcy5zZXR1cCgpXG4gICAgfVxuXG4gICAgLyoqIFNldHVwIGNvbGxlY3Rpb25zIGFuZCBpbnN0YW5jZSB2YXJzLiAqL1xuICAgIHNldHVwKCkge1xuICAgICAgICB0aGlzLm1hcCA9IG5ldyBNYXAoKSAvLyBNYXAge3VybCA6IFsgY29sLCByb3ddfVxuICAgICAgICB0aGlzLmxvYWRpbmcgPSBuZXcgU2V0KCkgLy8gU2V0IHVybFxuICAgICAgICB0aGlzLmxvYWRlZCA9IG5ldyBNYXAoKSAvLyBNYXAge3VybCA6IHNwcml0ZSB9XG4gICAgICAgIHRoaXMubG9hZFF1ZXVlID0gW11cbiAgICB9XG5cbiAgICAvKiogU2NoZWR1bGVzIGEgdGlsZSB1cmwgZm9yIGxvYWRpbmcuIFRoZSBsb2FkaW5nIGl0c2VsZiBtdXN0IGJlIHRyaWdnZXJlZFxuICAgIGJ5IGEgY2FsbCB0byBsb2FkT25lVGlsZSBvciBsb2FkQWxsXG5cbiAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmwgLSB0aGUgdXJsIG9mIHRoZSB0ZXh0dXJlIC8gdGlsZVxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvbCAtIHRoZSB0aWxlIGNvbFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHJvdyAtIHRoZSB0aWxlIHJvd1xuICAgICoqL1xuICAgIHNjaGVkdWxlKHVybCwgY29sLCByb3cpIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZGVkLmhhcyh1cmwpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHRoaXMubG9hZGluZy5oYXModXJsKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIHRoaXMubWFwLnNldCh1cmwsIFtjb2wsIHJvd10pXG4gICAgICAgIHRoaXMubG9hZGluZy5hZGQodXJsKVxuICAgICAgICB0aGlzLmxvYWRRdWV1ZS5wdXNoKHVybClcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICB1bnNjaGVkdWxlKHVybCkge1xuICAgICAgICBpZiAodGhpcy5sb2FkZWQuaGFzKHVybCkpIHRoaXMubG9hZGVkLmRlbGV0ZSh1cmwpXG4gICAgICAgIGlmICh0aGlzLmxvYWRpbmcuaGFzKHVybCkpIHRoaXMubG9hZGluZy5kZWxldGUodXJsKVxuICAgICAgICB0aGlzLmxvYWRRdWV1ZSA9IHRoaXMubG9hZFF1ZXVlLmZpbHRlcihpdGVtID0+IGl0ZW0gIT0gdXJsKVxuICAgIH1cblxuICAgIC8qKiBDYW5jZWxzIGxvYWRpbmcgYnkgY2xlYXJpbmcgdGhlIGxvYWQgcXVldWUgKiovXG4gICAgY2FuY2VsKCkge1xuICAgICAgICB0aGlzLmxvYWRRdWV1ZSA9IFtdXG4gICAgICAgIHRoaXMubG9hZGluZy5jbGVhcigpXG4gICAgfVxuXG4gICAgLyoqIERlc3Ryb3lzIGFsbHMgY29sbGVjdGlvbnMuICoqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuc2V0dXAoKVxuICAgIH1cblxuICAgIC8qKiBQcml2YXRlIG1ldGhvZC4gSW5mb3JtcyB0aGUgdGlsZSBsYXllciBhYm91dCBhIHRleHR1cmUgZm9yIGEgZ2l2ZW4gdXJsLlxuICAgICAqIENyZWF0ZXMgdGhlIHNwcml0ZSBmb3IgdGhlIGxvYWRlZCB0ZXh0dXJlIGFuZCBpbmZvcm1zIHRoZSB0aWxlIGxheWVyLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmwgLSB0aGUgdXJsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHRleHR1cmUgLSB0aGUgbG9hZGVkIHJlc291cmNlXG4gICAgICoqL1xuICAgIF90ZXh0dXJlQXZhaWxhYmxlKHVybCwgY29sLCByb3csIHRleHR1cmUpIHtcbiAgICAgICAgbGV0IHRpbGUgPSB0aGlzLmxvYWRlZC5nZXQodXJsKVxuICAgICAgICBpZiAodGlsZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJUaWxlIGFscmVhZHkgbG9hZGVkXCIpXG4gICAgICAgICAgICB0aWxlLnVucmVnaXN0ZXIoKVxuICAgICAgICB9XG4gICAgICAgIHRpbGUgPSBuZXcgVGlsZSh0ZXh0dXJlLCB1cmwpXG4gICAgICAgIHRoaXMubG9hZGVkLnNldCh1cmwsIHRpbGUpXG4gICAgICAgIHRoaXMudGlsZXMudGlsZUF2YWlsYWJsZSh0aWxlLCBjb2wsIHJvdywgdXJsKVxuICAgIH1cbn1cblxuLyoqXG4gKiBVc2VzIHRoZSBQSVhJIExvYWRlciBidXQgY2FuIGJlIHJlcGxhY2VkIHdpdGggb3RoZSBsb2FkZXJzIGltcGxlbWVudGluZ1xuICogdGhlIHB1YmxpYyBtZXRob2RzIHdpdGhvdXQgdW5kZXJzY29yZS5cbiAqIENhbGxzIHRoZSBUaWxlcy50aWxlQXZhaWxhYmxlIG1ldGhvZCBpZiB0aGUgdGV4dHVyZSBpcyBhdmFpbGFibGUuXG4gKiovXG5leHBvcnQgY2xhc3MgUElYSVRpbGVMb2FkZXIgZXh0ZW5kcyBUaWxlTG9hZGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHRpbGVzLCBjb21wcmVzc2lvbikge1xuICAgICAgICBzdXBlcih0aWxlcylcbiAgICAgICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZVxuICAgICAgICB0aGlzLmxvYWRlciA9IG5ldyBQSVhJLmxvYWRlcnMuTG9hZGVyKClcbiAgICAgICAgdGhpcy5sb2FkZXIub24oJ2xvYWQnLCB0aGlzLl9vbkxvYWRlZC5iaW5kKHRoaXMpKVxuICAgICAgICB0aGlzLmxvYWRlci5vbignZXJyb3InLCB0aGlzLl9vbkVycm9yLmJpbmQodGhpcykpXG4gICAgICAgIGlmIChjb21wcmVzc2lvbikge1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIucHJlKFBJWEkuY29tcHJlc3NlZFRleHR1cmVzLmltYWdlUGFyc2VyKCkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzY2hlZHVsZSh1cmwsIGNvbCwgcm93KSB7XG4gICAgICAgIC8vIE92ZXJ3cml0dGVuIHNjaGVkdWxlIHRvIGF2b2lkIEJhc2VUZXh0dXJlIGFuZCBUZXh0dXJlIGFscmVhZHkgbG9hZGVkIGVycm9ycy5cbiAgICAgICAgaWYgKHRoaXMubG9hZGVkLmhhcyh1cmwpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHRoaXMubG9hZGluZy5oYXModXJsKSkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgaWYgKGRlZXBab29tVGlsZUNhY2hlLmhhcyh1cmwpKSB7XG4gICAgICAgICAgICBsZXQgdGlsZXMgPSBkZWVwWm9vbVRpbGVDYWNoZS5nZXQodXJsKVxuICAgICAgICAgICAgZm9yIChsZXQgdGlsZSBvZiB0aWxlcy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJSZXVzaW5nIGNhY2hlZCB0ZXh0dXJlXCIsIHRpbGUucGFyZW50KVxuICAgICAgICAgICAgICAgIGxldCB0ZXh0dXJlID0gdGlsZS50ZXh0dXJlXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUF2YWlsYWJsZSh1cmwsIGNvbCwgcm93LCB0ZXh0dXJlKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBsZXQgdGV4dHVyZSA9IFBJWEkudXRpbHMuVGV4dHVyZUNhY2hlW3VybF1cbiAgICAgICAgaWYgKHRleHR1cmUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlYnVnKSBjb25zb2xlLmxvZygnVGV4dHVyZSBhbHJlYWR5IGxvYWRlZCcsIHRleHR1cmUpXG4gICAgICAgICAgICB0aGlzLl90ZXh0dXJlQXZhaWxhYmxlKHVybCwgY29sLCByb3csIHRleHR1cmUpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBsZXQgYmFzZSA9IFBJWEkudXRpbHMuQmFzZVRleHR1cmVDYWNoZVt1cmxdXG4gICAgICAgIGlmIChiYXNlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coJ0Jhc2VUZXh0dXJlIGFscmVhZHkgbG9hZGVkJywgYmFzZSlcbiAgICAgICAgICAgIGxldCB0ZXh0dXJlID0gbmV3IFBJWEkuVGV4dHVyZShiYXNlKVxuICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUF2YWlsYWJsZSh1cmwsIGNvbCwgcm93LCB0ZXh0dXJlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1cGVyLnNjaGVkdWxlKHVybCwgY29sLCByb3cpXG4gICAgfVxuXG4gICAgLyoqIExvYWQgb25lIGFuZCBvbmx5IG9uZSBvZiB0aGUgc2NoZWR1bGVkIHRpbGVzICoqL1xuICAgIGxvYWRPbmVUaWxlKCkge1xuICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgdGhpcy5fbG9hZE9uZVRpbGUoKVxuICAgIH1cblxuICAgIC8qKiBMb2FkIGFsbCBzY2hlZHVsZWQgdGlsZXMgKiovXG4gICAgbG9hZEFsbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIHRoaXMuX2xvYWRBbGxUaWxlcygpXG4gICAgfVxuXG4gICAgLyoqIERlc3Ryb3lzIHRoZSBsb2FkZXIgY29tcGxldGx5ICoqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZVxuICAgICAgICBzdXBlci5kZXN0cm95KClcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMubG9hZGVyLnJlc2V0KClcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkVycm9yIHdoaWxlIHJlc2V0dGluZyBsb2FkZXJcIiwgZXJyb3IpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfb25FcnJvcihsb2FkZXIsIGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignQ2Fubm90IGxvYWQnLCBlcnJvcilcbiAgICB9XG5cbiAgICAvKiogUHJpdmF0ZSBtZXRob2QuIENhbGxlZCBieSB0aGUgUElYSSBsb2FkZXIgYWZ0ZXIgZWFjaCBzdWNjZXNzZnVsbFxuICAgICAqIGxvYWRpbmcgb2YgYSBzaW5nbGUgdGlsZS5cbiAgICAgKiBDcmVhdGVzIHRoZSBzcHJpdGUgZm9yIHRoZSBsb2FkZWQgdGV4dHVyZSBhbmQgaW5mb3JtcyB0aGUgdGlsZSBsYXllci5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gbG9hZGVyIC0gdGhlIGxvYWRlciBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSByZXNvdXJjZSAtIHRoZSBsb2FkZWQgcmVzb3VyY2Ugd2l0aCB1cmwgYW5kIHRleHR1cmUgYXR0clxuICAgICAqKi9cbiAgICBfb25Mb2FkZWQobG9hZGVyLCByZXNvdXJjZSkge1xuICAgICAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgICAgICAgIGxldCB0ZXh0dXJlID0gcmVzb3VyY2UudGV4dHVyZVxuICAgICAgICAgICAgbGV0IGRlc3Ryb3lCYXNlID0gIWRlZXBab29tVGlsZUNhY2hlLmhhcyhyZXNvdXJjZS51cmwpXG4gICAgICAgICAgICB0ZXh0dXJlLmRlc3Ryb3koZGVzdHJveUJhc2UpXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJSZWNlaXZlZCByZXNvdXJjZSBhZnRlciBkZXN0cm95XCIsIHRleHR1cmUpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IFtjb2wsIHJvd10gPSB0aGlzLm1hcC5nZXQocmVzb3VyY2UudXJsKVxuICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUF2YWlsYWJsZShyZXNvdXJjZS51cmwsIGNvbCwgcm93LCByZXNvdXJjZS50ZXh0dXJlKVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlRleHR1cmUgdW5hdmFpbGFibGU6IFwiICsgZXJyLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUHJpdmF0ZSBtZXRob2Q6IGxvYWRzIG9uZSB0aWxlIGZyb20gdGhlIHF1ZXVlLiAqKi9cbiAgICBfbG9hZE9uZVRpbGUocmV0cnkgPSAxKSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJfbG9hZE9uZVRpbGVcIilcbiAgICAgICAgaWYgKHRoaXMuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUud2FybihcIl9sb2FkT25lVGlsZSBhZnRlciBkZXN0cm95XCIpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2FkZXIubG9hZGluZykge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZE9uZVRpbGUoKVxuICAgICAgICAgICAgfSwgcmV0cnkpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2FkUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbGV0IHVybCA9IHRoaXMubG9hZFF1ZXVlLnBvcCgpXG4gICAgICAgICAgICB0aGlzLmxvYWRlci5hZGQodXJsLCB1cmwpXG4gICAgICAgICAgICB0aGlzLmxvYWRlci5sb2FkKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBQcml2YXRlIG1ldGhvZDogbG9hZHMgYWxsIHRpbGVzIGZyb20gdGhlIHF1ZXVlIGluIGJhdGNoZXMuIEJhdGNoZXMgYXJlXG4gICAgaGVscGZ1bGwgdG8gYXZvaWQgbG9hZGluZyB0aWxlcyB0aGF0IGFyZSBubyBsb25nZXIgbmVlZGVkIGJlY2F1c2UgdGhlXG4gICAgdXNlciBoYXMgYWxyZWFkeSB6b29tZWQgdG8gYSBkaWZmZXJlbnQgbGV2ZWwuKiovXG4gICAgX2xvYWRBbGxUaWxlcyhiYXRjaFNpemUgPSA4LCByZXRyeSA9IDE2KSB7XG4gICAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubG9hZFF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvYWRlci5sb2FkaW5nKSB7XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIkxvYWRlciBidXN5XCIsIHRoaXMubG9hZFF1ZXVlLmxlbmd0aClcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZEFsbFRpbGVzKClcbiAgICAgICAgICAgICAgICB9LCByZXRyeSlcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBpID0gMFxuICAgICAgICAgICAgbGV0IHVybHMgPSBbXVxuICAgICAgICAgICAgd2hpbGUgKGkgPCBiYXRjaFNpemUgJiYgdGhpcy5sb2FkUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCB1cmwgPSB0aGlzLmxvYWRRdWV1ZS5wb3AoKVxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5sb2FkZWQuaGFzKHVybCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc291cmNlID0gdGhpcy5sb2FkZXIucmVzb3VyY2VzW3VybF1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc291cmNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIlJlc291cmNlIGFscmVhZHkgYWRkZWRcIiwgdXJsKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXJscy5wdXNoKHVybClcbiAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gMVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5sb2FkZXIuYWRkKHVybHMpLmxvYWQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRBbGxUaWxlcygpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIFVzZXMgWE1MSHR0cFJlcXVlc3RzIGJ1dCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBvdGhlciBsb2FkZXJzIGltcGxlbWVudGluZ1xuICogdGhlIHB1YmxpYyBtZXRob2RzIHdpdGhvdXQgdW5kZXJzY29yZS5cbiAqIENhbGxzIHRoZSBUaWxlcy50aWxlQXZhaWxhYmxlIG1ldGhvZCBpZiB0aGUgdGV4dHVyZSBpcyBhdmFpbGFibGUuXG4gKiovXG5leHBvcnQgY2xhc3MgUmVxdWVzdFRpbGVMb2FkZXIgZXh0ZW5kcyBUaWxlTG9hZGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHRpbGVzLCBjb21wcmVzc2lvbikge1xuICAgICAgICBzdXBlcih0aWxlcylcbiAgICAgICAgdGhpcy5jb21wcmVzc2lvbiA9IGNvbXByZXNzaW9uXG4gICAgfVxuXG4gICAgc2NoZWR1bGUodXJsLCBjb2wsIHJvdykge1xuICAgICAgICB0aGlzLl9sb2FkKHVybCwgY29sLCByb3cpXG4gICAgICAgIHJldHVybiBzdXBlci5zY2hlZHVsZSh1cmwsIGNvbCwgcm93KVxuICAgIH1cblxuICAgIF9sb2FkKHVybCwgY29sLCByb3csIGNhbGxiYWNrID0gbnVsbCkge1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbikge1xuICAgICAgICAgICAgbGV0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgICAgICB4aHIub3BlbignR0VUJywgdXJsLCBmYWxzZSlcbiAgICAgICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInXG4gICAgICAgICAgICB4aHIub25sb2FkID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IENvbXByZXNzZWRJbWFnZSA9IFBJWEkuY29tcHJlc3NlZFRleHR1cmVzLkNvbXByZXNzZWRJbWFnZVxuICAgICAgICAgICAgICAgIGxldCBjb21wcmVzc2VkID0gQ29tcHJlc3NlZEltYWdlLmxvYWRGcm9tQXJyYXlCdWZmZXIoXG4gICAgICAgICAgICAgICAgICAgIHhoci5yZXNwb25zZSxcbiAgICAgICAgICAgICAgICAgICAgdXJsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGxldCBiYXNlID0gbmV3IFBJWEkuQmFzZVRleHR1cmUoY29tcHJlc3NlZClcbiAgICAgICAgICAgICAgICBsZXQgdGV4dHVyZSA9IG5ldyBQSVhJLlRleHR1cmUoYmFzZSlcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlQXZhaWxhYmxlKHVybCwgY29sLCByb3csIHRleHR1cmUpXG4gICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjaygpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB4aHIuc2VuZCgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgdGV4dHVyZSA9IFBJWEkuVGV4dHVyZS5mcm9tSW1hZ2UoJ2Fzc2V0cy9pbWFnZS5wbmcnKVxuICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUF2YWlsYWJsZSh1cmwsIGNvbCwgcm93LCB0ZXh0dXJlKVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjaygpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogTG9hZCBvbmUgYW5kIG9ubHkgb25lIG9mIHRoZSBzY2hlZHVsZWQgdGlsZXMgKiovXG4gICAgbG9hZE9uZVRpbGUoKSB7XG4gICAgICAgIHRoaXMuX2xvYWRPbmVUaWxlKClcbiAgICB9XG5cbiAgICAvKiogTG9hZCBhbGwgc2NoZWR1bGVkIHRpbGVzICoqL1xuICAgIGxvYWRBbGwoKSB7XG4gICAgICAgIHRoaXMuX2xvYWRBbGxUaWxlcygpXG4gICAgfVxuXG4gICAgLyoqIFByaXZhdGUgbWV0aG9kOiBsb2FkcyBvbmUgdGlsZSBmcm9tIHRoZSBxdWV1ZS4gKiovXG4gICAgX2xvYWRPbmVUaWxlKHJldHJ5ID0gMSkge1xuICAgICAgICBpZiAodGhpcy5sb2FkUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbGV0IHVybCA9IHRoaXMubG9hZFF1ZXVlLnBvcCgpXG4gICAgICAgICAgICBsZXQgW2NvbCwgcm93XSA9IHRoaXMubWFwLmdldCh1cmwpXG4gICAgICAgICAgICB0aGlzLl9sb2FkKHVybCwgY29sLCByb3cpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUHJpdmF0ZSBtZXRob2Q6IGxvYWRzIGFsbCB0aWxlcyBmcm9tIHRoZSBxdWV1ZSBpbiBiYXRjaGVzLiBCYXRjaGVzIGFyZVxuICAgIGhlbHBmdWxsIHRvIGF2b2lkIGxvYWRpbmcgdGlsZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIG5lZWRlZCBiZWNhdXNlIHRoZVxuICAgIHVzZXIgaGFzIGFscmVhZHkgem9vbWVkIHRvIGEgZGlmZmVyZW50IGxldmVsLioqL1xuICAgIF9sb2FkQWxsVGlsZXMoYmF0Y2hTaXplID0gOCwgcmV0cnkgPSAxNikge1xuICAgICAgICBpZiAodGhpcy5sb2FkUXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbGV0IGkgPSAwXG4gICAgICAgICAgICBsZXQgdXJscyA9IFtdXG4gICAgICAgICAgICB3aGlsZSAoaSA8IGJhdGNoU2l6ZSAmJiB0aGlzLmxvYWRRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHVybCA9IHRoaXMubG9hZFF1ZXVlLnBvcCgpXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUudGltZSh1cmwpXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmxvYWRlZC5oYXModXJsKSkge1xuICAgICAgICAgICAgICAgICAgICB1cmxzLnB1c2godXJsKVxuICAgICAgICAgICAgICAgICAgICBpICs9IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgdG90YWwgPSB1cmxzLmxlbmd0aFxuICAgICAgICAgICAgbGV0IGNvdW50ID0gMFxuICAgICAgICAgICAgZm9yIChsZXQgdXJsIG9mIHVybHMpIHtcbiAgICAgICAgICAgICAgICBsZXQgW2NvbCwgcm93XSA9IHRoaXMubWFwLmdldCh1cmwpXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZCh1cmwsIGNvbCwgcm93LCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50KytcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IHRvdGFsKSB0aGlzLl9sb2FkQWxsVGlsZXMoKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuLyoqXG4gKiBVc2VzIFdvcmtlcnMgYnV0IGNhbiBiZSByZXBsYWNlZCB3aXRoIG90aGVyIGxvYWRlcnMgaW1wbGVtZW50aW5nXG4gKiB0aGUgcHVibGljIG1ldGhvZHMgd2l0aG91dCB1bmRlcnNjb3JlLlxuICogQ2FsbHMgdGhlIFRpbGVzLnRpbGVBdmFpbGFibGUgbWV0aG9kIGlmIHRoZSB0ZXh0dXJlIGlzIGF2YWlsYWJsZS5cbiAqKi9cbmV4cG9ydCBjbGFzcyBXb3JrZXJUaWxlTG9hZGVyIGV4dGVuZHMgVGlsZUxvYWRlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcih0aWxlcykge1xuICAgICAgICBzdXBlcih0aWxlcylcbiAgICAgICAgbGV0IHdvcmtlciA9IHRoaXMud29ya2VyID0gbmV3IFdvcmtlcihcIi4uLy4uL2xpYi9waXhpL2RlZXB6b29tL3RpbGVsb2FkZXIuanNcIilcbiAgICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGxldCB7IHVybCwgY29sLCByb3csIGJ1ZmZlciB9ID0gZXZlbnQuZGF0YVxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJXb3JrZXJUaWxlTG9hZGVyLmxvYWRlZFwiLCB1cmwsIGJ1ZmZlcilcbiAgICAgICAgICAgICAgICBsZXQgQ29tcHJlc3NlZEltYWdlID0gUElYSS5jb21wcmVzc2VkVGV4dHVyZXMuQ29tcHJlc3NlZEltYWdlXG4gICAgICAgICAgICAgICAgbGV0IGNvbXByZXNzZWQgPSBDb21wcmVzc2VkSW1hZ2UubG9hZEZyb21BcnJheUJ1ZmZlcihidWZmZXIsIHVybClcbiAgICAgICAgICAgICAgICBsZXQgYmFzZSA9IG5ldyBQSVhJLkJhc2VUZXh0dXJlKGNvbXByZXNzZWQpXG4gICAgICAgICAgICAgICAgbGV0IHRleHR1cmUgPSBuZXcgUElYSS5UZXh0dXJlKGJhc2UpXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUF2YWlsYWJsZSh1cmwsIGNvbCwgcm93LCB0ZXh0dXJlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbG9hZE9uZSgpIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZFF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxldCB1cmwgPSB0aGlzLmxvYWRRdWV1ZS5wb3AoKVxuICAgICAgICAgICAgbGV0IFtjb2wsIHJvd10gPSB0aGlzLm1hcC5nZXQodXJsKVxuICAgICAgICAgICAgbGV0IHRpbGUgPSBbY29sLCByb3csIHVybF1cbiAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHsgY29tbWFuZDogXCJsb2FkXCIsIHRpbGVzOiBbdGlsZV0gfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxvYWRBbGwoKSB7XG4gICAgICAgIGxldCB0aWxlcyA9IFtdXG4gICAgICAgIHdoaWxlICh0aGlzLmxvYWRRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBsZXQgdXJsID0gdGhpcy5sb2FkUXVldWUucG9wKClcbiAgICAgICAgICAgIGxldCBbY29sLCByb3ddID0gdGhpcy5tYXAuZ2V0KHVybClcbiAgICAgICAgICAgIHRpbGVzLnB1c2goW2NvbCwgcm93LCB1cmxdKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHsgY29tbWFuZDogXCJsb2FkXCIsIHRpbGVzIH0pXG4gICAgfVxuXG4gICAgY2FuY2VsKCkge1xuICAgICAgICBzdXBlci5jYW5jZWwoKVxuICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7IGNvbW1hbmQ6IFwiYWJvcnRcIiB9KVxuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHsgY29tbWFuZDogXCJhYm9ydFwiIH0pXG4gICAgICAgIHRoaXMud29ya2VyLnRlcm1pbmF0ZSgpXG4gICAgICAgIHRoaXMud29ya2VyID0gbnVsbFxuICAgICAgICBzdXBlci5kZXN0cm95KClcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBDb2xvcnMgfSBmcm9tICcuLi8uLi91dGlscy5qcydcbmltcG9ydCB7IFdvcmtlclRpbGVMb2FkZXIsIFBJWElUaWxlTG9hZGVyIH0gZnJvbSBcIi4vbG9hZGVyLmpzXCJcblxuXG4vKipcbiAqIEEgbGF5ZXIgb2YgdGlsZXMgdGhhdCByZXByZXNlbnRzIGEgem9vbSBsZXZlbCBvZiBhIERlZXBab29tSW1hZ2UgYXMgYSBncmlkXG4gKiBvZiBzcHJpdGVzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgLSB0aGUgem9vbSBsZXZlbCBvZiB0aGUgdGlsZSBsYXllclxuICogQHBhcmFtIHtEZWVwWm9vbUltYWdlfSB2aWV3IC0gdGhlIHpvb21hYmxlIGltYWdlIHRoZSBsYXllciBiZWxvbmdzIHRvXG4gKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgLSB0aGUgc2NhbGUgb2YgdGhlIHRpbGUgbGF5ZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb2xzIC0gdGhlIG51bWJlciBvZiBjb2x1bW5zIG9mIHRoZSBsYXllclxuICogQHBhcmFtIHtudW1iZXJ9IHJvd3MgLSB0aGUgbnVtYmVyIG9mIHJvd3Mgb2YgdGhlIGxheWVyXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSB0aGUgd2lkdGggb2YgdGhlIGxheWVyIGluIHBpeGVsXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gdGhlIGhlaWdodCBvZiB0aGUgbGF5ZXIgaW4gcGl4ZWxcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aWxlU2l6ZSAtIHRoZSBzaXplIG9mIGEgc2luZ2xlIHRpbGUgaW4gcGl4ZWxcbiAqIEBwYXJhbSB7bnVtYmVyfSBvdmVybGFwIC0gdGhlIG92ZXJsYXAgb2YgdGhlIHRpbGVzIGluIHBpeGVsXG4gKiBAcGFyYW0ge251bWJlcn0gZmFkZUluVGltZSAtIHRpbWUgbmVlZGVkIHRvIGZhZGUgaW4gdGlsZXMgaWYgVHdlZW5MaXRlIGlzIHNldFxuICoqL1xuZXhwb3J0IGNsYXNzIFRpbGVzIGV4dGVuZHMgUElYSS5Db250YWluZXIge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBsZXZlbCxcbiAgICAgICAgdmlldyxcbiAgICAgICAgc2NhbGUsXG4gICAgICAgIGNvbHMsXG4gICAgICAgIHJvd3MsXG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIHRpbGVTaXplLFxuICAgICAgICBvdmVybGFwLFxuICAgICAgICBmYWRlSW5UaW1lID0gMC4zM1xuICAgICkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZVxuICAgICAgICB0aGlzLnNob3dHcmlkID0gZmFsc2VcbiAgICAgICAgdGhpcy52aWV3ID0gdmlld1xuICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWxcbiAgICAgICAgdGhpcy5jb2xzID0gY29sc1xuICAgICAgICB0aGlzLnJvd3MgPSByb3dzXG4gICAgICAgIHRoaXMucGl4ZWxXaWR0aCA9IHdpZHRoXG4gICAgICAgIHRoaXMucGl4ZWxIZWlnaHQgPSBoZWlnaHRcbiAgICAgICAgdGhpcy50aWxlU2l6ZSA9IHRpbGVTaXplXG4gICAgICAgIHRoaXMub3ZlcmxhcCA9IG92ZXJsYXBcbiAgICAgICAgdGhpcy5uZWVkZWQgPSBuZXcgTWFwKCkgLy8gdXJsIGFzIGtleSwgW2NvbCwgcm93XSBhcyB2YWx1ZVxuICAgICAgICB0aGlzLnJlcXVlc3RlZCA9IG5ldyBTZXQoKVxuICAgICAgICB0aGlzLmF2YWlsYWJsZSA9IG5ldyBNYXAoKVxuICAgICAgICB0aGlzLnNjYWxlLnNldChzY2FsZSwgc2NhbGUpXG4gICAgICAgIHRoaXMudGlsZVNjYWxlID0gc2NhbGVcbiAgICAgICAgdGhpcy5mYWRlSW5UaW1lID0gZmFkZUluVGltZVxuICAgICAgICB0aGlzLmtlZXAgPSBmYWxzZVxuICAgICAgICBpZiAodGhpcy52aWV3LnByZWZlcldvcmtlciAmJiB2aWV3LmluZm8uY29tcHJlc3Npb24ubGVuZ3RoID4gMClcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gbmV3IFdvcmtlclRpbGVMb2FkZXIodGhpcylcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBuZXcgUElYSVRpbGVMb2FkZXIodGhpcywgdmlldy5pbmZvLmNvbXByZXNzaW9uKVxuICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gZmFsc2VcbiAgICAgICAgdGhpcy5faGlnaGxpZ2h0ID0gbnVsbFxuXG4gICAgICAgIHRoaXMuX2luZm8gPSBudWxsXG5cbiAgICAgICAgdGhpcy5fY2VudGVyUG9pbnQgPSBudWxsXG4gICAgICAgIHRoaXMuX2JvdW5kc1JlY3QgPSBudWxsXG5cbiAgICAgICAgdGhpcy5pbmZvQ29sb3IgPSBDb2xvcnMucmFuZG9tKClcbiAgICAgICAgdGhpcy5wcHJpbnQoKVxuICAgICAgICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlXG4gICAgfVxuXG5cblxuICAgIC8qKiBUZXN0cyB3aGV0aGVyIGFsbCB0aWxlcyBhcmUgbG9hZGVkLiAqKi9cbiAgICBpc0NvbXBsZXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb2xzICogdGhpcy5yb3dzID09PSB0aGlzLmNoaWxkcmVuLmxlbmd0aFxuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRoZSBoaWdobGlnaCBncmFwaGljcyBsYXllciBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLlxuICAgICAqKi9cbiAgICBnZXQgaGlnaGxpZ2h0KCkge1xuICAgICAgICBpZiAodGhpcy5faGlnaGxpZ2h0ID09IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBncmFwaGljcyA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgICAgIGdyYXBoaWNzLmJlZ2luRmlsbCgweGZmZmYwMCwgMC4xKVxuICAgICAgICAgICAgZ3JhcGhpY3MubGluZVN0eWxlKDIsIDB4ZmZmZjAwKVxuICAgICAgICAgICAgZ3JhcGhpY3MuZHJhd1JlY3QoMSwgMSwgdGhpcy50aWxlU2l6ZSAtIDIsIHRoaXMudGlsZVNpemUgLSAyKVxuICAgICAgICAgICAgZ3JhcGhpY3MuZW5kRmlsbCgpXG4gICAgICAgICAgICBncmFwaGljcy5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLl9oaWdobGlnaHQgPSBncmFwaGljc1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9oaWdobGlnaHRcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0aGUgaGlnaGxpZ2ggZ3JhcGhpY3MgbGF5ZXIgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAgICAgKiovXG4gICAgZ2V0IGluZm8oKSB7XG4gICAgICAgIGlmICh0aGlzLl9pbmZvID09IG51bGwpIHtcbiAgICAgICAgICAgIGxldCBncmFwaGljcyA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgICAgIGdyYXBoaWNzLmxpbmVTdHlsZSg0LCAweGZmMDAwMClcbiAgICAgICAgICAgIGdyYXBoaWNzLmludGVyYWN0aXZlID0gZmFsc2VcbiAgICAgICAgICAgIHRoaXMuX2luZm8gPSBncmFwaGljc1xuICAgICAgICAgICAgdGhpcy5hZGRDaGlsZCh0aGlzLl9pbmZvKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9pbmZvXG4gICAgfVxuXG4gICAgLyoqIEhlbHBlciBtZXRob2QgcHJldHR5IHByaW50aW5nIGRlYnVnIGluZm9ybWF0aW9uLiAqKi9cbiAgICBwcHJpbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnKVxuICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgJ1RpbGVzIGxldmVsOiAnICtcbiAgICAgICAgICAgICAgICB0aGlzLmxldmVsICtcbiAgICAgICAgICAgICAgICAnIHNjYWxlOiAnICtcbiAgICAgICAgICAgICAgICB0aGlzLnNjYWxlLnggK1xuICAgICAgICAgICAgICAgICcgY29sczogJyArXG4gICAgICAgICAgICAgICAgdGhpcy5jb2xzICtcbiAgICAgICAgICAgICAgICAnIHJvd3M6ICcgK1xuICAgICAgICAgICAgICAgIHRoaXMucm93cyArXG4gICAgICAgICAgICAgICAgJyB3OiAnICtcbiAgICAgICAgICAgICAgICB0aGlzLnBpeGVsV2lkdGggK1xuICAgICAgICAgICAgICAgICcgaDogJyArXG4gICAgICAgICAgICAgICAgdGhpcy5waXhlbEhlaWdodCArXG4gICAgICAgICAgICAgICAgJyB0c2l6ZTonICtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbGVTaXplXG4gICAgICAgICAgICApXG4gICAgfVxuXG4gICAgLyoqIENvbXB1dGVzIHRoZSB0aWxlIHBvc2l0aW9uIGFuZCBvYmV5cyB0aGUgb3ZlcmxhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY29sIC0gVGhlIGNvbHVtbiBvZiB0aGUgdGlsZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByb3cgLSBUaGUgcm93IG9mIHRoZSB0aWxlXG4gICAgICogQHJldHVybnMge1BJWEkuUG9pbnR9IG9ialxuICAgICAqKi9cbiAgICB0aWxlUG9zaXRpb24oY29sLCByb3cpIHtcbiAgICAgICAgbGV0IHggPSBjb2wgKiB0aGlzLnRpbGVTaXplXG4gICAgICAgIGxldCB5ID0gcm93ICogdGhpcy50aWxlU2l6ZVxuICAgICAgICBsZXQgb3ZlcmxhcCA9IHRoaXMub3ZlcmxhcFxuICAgICAgICBpZiAoY29sICE9IDApIHtcbiAgICAgICAgICAgIHggLT0gb3ZlcmxhcFxuICAgICAgICB9XG4gICAgICAgIGlmIChyb3cgIT0gMCkge1xuICAgICAgICAgICAgeSAtPSBvdmVybGFwXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQSVhJLlBvaW50KHgsIHkpXG4gICAgfVxuXG4gICAgLyoqIENvbXB1dGVzIHRoZSB0aWxlIHNpemUgd2l0aG91dCBvdmVybGFwXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNvbCAtIFRoZSBjb2x1bW4gb2YgdGhlIHRpbGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcm93IC0gVGhlIHJvdyBvZiB0aGUgdGlsZVxuICAgICAqIEByZXR1cm5zIHtQSVhJLlBvaW50fSBvYmpcbiAgICAgKiovXG4gICAgdGlsZURpbWVuc2lvbnMoY29sLCByb3cpIHtcbiAgICAgICAgbGV0IHcgPSB0aGlzLnRpbGVTaXplXG4gICAgICAgIGxldCBoID0gdGhpcy50aWxlU2l6ZVxuICAgICAgICBsZXQgcG9zID0gdGhpcy50aWxlUG9zaXRpb24oY29sLCByb3cpXG4gICAgICAgIGlmIChjb2wgPT0gdGhpcy5jb2xzIC0gMSkge1xuICAgICAgICAgICAgdyA9IHRoaXMucGl4ZWxXaWR0aCAtIHBvcy54XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJvdyA9PSB0aGlzLnJvd3MgLSAxKSB7XG4gICAgICAgICAgICBoID0gdGhpcy5waXhlbEhlaWdodCAtIHBvcy55XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQSVhJLlBvaW50KHcsIGgpXG4gICAgfVxuXG4gICAgLyoqIE1ldGhvZCB0byBzdXBwb3J0IGRlYnVnZ2luZy4gSGlnaGxpZ2h0cyB0aGUgc3BlY2lmaWVkIHRpbGUgYXQgY29sLCByb3cgKiovXG4gICAgaGlnaGxpZ2h0VGlsZShjb2wsIHJvdykge1xuICAgICAgICBpZiAoY29sID4gLTEgJiYgcm93ID4gLTEgJiYgY29sIDwgdGhpcy5jb2xzICYmIHJvdyA8IHRoaXMucm93cykge1xuICAgICAgICAgICAgbGV0IGdyYXBoaWNzID0gdGhpcy5oaWdobGlnaHRcbiAgICAgICAgICAgIGxldCBkaW0gPSB0aGlzLnRpbGVEaW1lbnNpb25zKGNvbCwgcm93KVxuICAgICAgICAgICAgZ3JhcGhpY3MucG9zaXRpb24gPSB0aGlzLnRpbGVQb3NpdGlvbihjb2wsIHJvdylcbiAgICAgICAgICAgIGdyYXBoaWNzLmNsZWFyKClcbiAgICAgICAgICAgIGdyYXBoaWNzLmJlZ2luRmlsbCgweGZmMDBmZiwgMC4xKVxuICAgICAgICAgICAgZ3JhcGhpY3MubGluZVN0eWxlKDIsIDB4ZmZmZjAwKVxuICAgICAgICAgICAgZ3JhcGhpY3MuZHJhd1JlY3QoMSwgMSwgZGltLnggLSAyLCBkaW0ueSAtIDIpXG4gICAgICAgICAgICBncmFwaGljcy5lbmRGaWxsKClcbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5oaWdobGlnaHQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuaGlnaGxpZ2h0KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIExvYWRzIHRoZSB0aWxlcyBmb3IgdGhlIGdpdmVuIHVybHMgYW5kIGFkZHMgdGhlIHRpbGVzIGFzIHNwcml0ZXMuXG4gICAgICogQHBhcmFtIHthcnJheX0gdXJscG9zIC0gQW4gYXJyYXkgb2YgVVJMLCBwb3MgcGFpcnNcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9ubHlvbmUgLSBMb2FkcyBvbmx5IG9uIHRpbGUgYXQgYSB0aW1lIGlmIHRydWVcbiAgICAgKiovXG4gICAgbG9hZFRpbGVzKHVybHBvcywgb25seW9uZSwgcmVmQ29sLCByZWZSb3cpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvd0dyaWQpIHtcbiAgICAgICAgICAgIHRoaXMuaGlnaGxpZ2h0VGlsZShyZWZDb2wsIHJlZlJvdylcbiAgICAgICAgfVxuICAgICAgICB1cmxwb3MuZm9yRWFjaChkID0+IHtcbiAgICAgICAgICAgIGxldCBbdXJsLCBjb2wsIHJvd10gPSBkXG4gICAgICAgICAgICBpZiAodGhpcy5sb2FkZXIuc2NoZWR1bGUodXJsLCBjb2wsIHJvdykpIHtcbiAgICAgICAgICAgICAgICBpZiAob25seW9uZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2FkZXIubG9hZE9uZVRpbGUoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy5sb2FkZXIubG9hZEFsbCgpXG4gICAgfVxuXG4gICAgLyoqIFByaXZhdGUgbWV0aG9kOiBhZGQgYSByZWQgYm9yZGVyIHRvIGEgdGlsZSBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLiAqKi9cbiAgICBfYWRkVGlsZUJvcmRlcih0aWxlLCBjb2wsIHJvdykge1xuICAgICAgICBsZXQgZGltID0gdGhpcy50aWxlRGltZW5zaW9ucyhjb2wsIHJvdylcbiAgICAgICAgbGV0IGdyYXBoaWNzID0gbmV3IFBJWEkuR3JhcGhpY3MoKVxuICAgICAgICBncmFwaGljcy5iZWdpbkZpbGwoMCwgMClcbiAgICAgICAgZ3JhcGhpY3MubGluZVN0eWxlKDIsIDB4ZmYwMDAwKVxuICAgICAgICBncmFwaGljcy5kcmF3UmVjdCgxLCAxLCBkaW0ueCAtIDIsIGRpbS55IC0gMilcbiAgICAgICAgZ3JhcGhpY3MuZW5kRmlsbCgpXG4gICAgICAgIHRpbGUuYWRkQ2hpbGQoZ3JhcGhpY3MpXG4gICAgfVxuXG4gICAgLyoqIEFkZHMgYSB0aWxlLiAqKi9cbiAgICBhZGRUaWxlKHRpbGUsIGNvbCwgcm93LCB1cmwpIHtcbiAgICAgICAgaWYgKHRoaXMuYXZhaWxhYmxlLmhhcyh1cmwpKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RyeWluZyB0byBhZGQgYXZhaWxhYmxlIHRpbGUnKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGRDaGlsZEF0KHRpbGUsIDApXG4gICAgICAgIHRoaXMuYXZhaWxhYmxlLnNldCh1cmwsIHRpbGUpXG4gICAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdBZGRpbmcgdG8gZGVzdHJveWVkIHRpbGVzIGxheWVyJylcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGlzLl9hZGRUaWxlQm9yZGVyKHRpbGUsIGNvbCwgcm93KVxuICAgIH1cblxuICAgIC8qKiBDYWxsZWQgYnkgdGhlIGxvYWRlciBhZnRlciBlYWNoIHN1Y2Nlc3NmdWxsIGxvYWRpbmcgb2YgYSBzaW5nbGUgdGlsZS5cbiAgICAgKiBBZGRzIHRoZSBzcHJpdGUgdG8gdGhlIHRpbGUgbGF5ZXIuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHRpbGUgLSB0aGUgbG9hZGVkIHRpbGUgc3ByaXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvbCAtIHRoZSBjb2wgcG9zaXRpb25cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcm93IC0gdGhlIHJvd3Bvc2l0aW9uXG4gICAgICoqL1xuICAgIHRpbGVBdmFpbGFibGUodGlsZSwgY29sLCByb3csIHVybCkge1xuICAgICAgICBsZXQgcG9zID0gdGhpcy50aWxlUG9zaXRpb24oY29sLCByb3cpXG4gICAgICAgIGlmICh0aGlzLnNob3dHcmlkKSB7XG4gICAgICAgICAgICB0aGlzLl9hZGRUaWxlQm9yZGVyKHRpbGUsIGNvbCwgcm93KVxuICAgICAgICB9XG4gICAgICAgIHRpbGUucG9zaXRpb24gPSBwb3NcbiAgICAgICAgdGlsZS5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgIGlmIChUd2VlbkxpdGUpIHtcbiAgICAgICAgICAgIHRpbGUuYWxwaGEgPSAwXG4gICAgICAgICAgICBUd2VlbkxpdGUudG8odGlsZSwgdGhpcy5mYWRlSW5UaW1lLCB7IGFscGhhOiB0aGlzLmFscGhhIH0pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGRUaWxlKHRpbGUsIGNvbCwgcm93LCB1cmwpXG4gICAgfVxuXG4gICAgLyoqIERlc3Ryb3lzIHRoZSB0aWxlcyBsYXllciBhbmQgZGVzdHJveXMgdGhlIGxvYWRlci4gQXN5bmMgbG9hZCBjYWxscyBhcmVcbiAgICAgKiBjYW5jZWxsZWQuXG4gICAgICoqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZVxuICAgICAgICB0aGlzLmxvYWRlci5kZXN0cm95KClcbiAgICAgICAgc3VwZXIuZGVzdHJveSh7IGNoaWxkcmVuOiB0cnVlIH0pIC8vIENhbGxzIGRlc3Ryb3lDaGlsZHJlblxuICAgICAgICB0aGlzLmF2YWlsYWJsZS5jbGVhcigpXG4gICAgICAgIHRoaXMucmVxdWVzdGVkLmNsZWFyKClcbiAgICAgICAgdGhpcy5uZWVkZWQuY2xlYXIoKVxuICAgIH1cblxuICAgIGRlc3Ryb3lUaWxlKHVybCwgdGlsZSkge1xuICAgICAgICB0aGlzLmxvYWRlci51bnNjaGVkdWxlKHVybClcbiAgICAgICAgdGhpcy5yZW1vdmVDaGlsZCh0aWxlKVxuICAgICAgICB0aWxlLmRlc3Ryb3koKVxuICAgICAgICB0aGlzLmF2YWlsYWJsZS5kZWxldGUodXJsKVxuICAgIH1cblxuICAgIGRlc3Ryb3lUaWxlQnlVcmwodXJsKSB7XG4gICAgICAgIGlmICh0aGlzLmF2YWlsYWJsZS5oYXModXJsKSkge1xuICAgICAgICAgICAgbGV0IHRpbGUgPSB0aGlzLmF2YWlsYWJsZS5nZXQodXJsKVxuICAgICAgICAgICAgdGhpcy5kZXN0cm95VGlsZSh1cmwsIHRpbGUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBEZXN0cm95cyB0aGUgdGlsZXMgd2hpY2ggYXJlIG5vdCB3aXRoIHRoZSBib3VuZHMgb2YgdGhlIGFwcCB0byBmcmVlXG4gICAgKiBtZW1vcnkuXG4gICAgKiovXG4gICAgZGVzdHJveVRpbGVzKHF1YWRUcmVlcykge1xuICAgICAgICBsZXQgY291bnQgPSAwXG4gICAgICAgIGZvciAobGV0IFt1cmwsIHRpbGVdIG9mIHRoaXMuYXZhaWxhYmxlLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgaWYgKCFxdWFkVHJlZXMuaGFzKHVybCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlc3Ryb3lUaWxlKHVybCwgdGlsZSlcbiAgICAgICAgICAgICAgICBjb3VudCArPSAxXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvdW50ICYmIHRoaXMuZGVidWcpXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnZGVzdHJveVRpbGVzJywgdGhpcy5sZXZlbCwgY291bnQpXG4gICAgfVxuXG4gICAgZGVzdHJveVVubmVlZGVkVGlsZXMoKSB7XG4gICAgICAgIGxldCBjb3VudCA9IDBcbiAgICAgICAgZm9yIChsZXQgW3VybCwgdGlsZV0gb2YgdGhpcy5hdmFpbGFibGUuZW50cmllcygpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMubmVlZGVkLmhhcyh1cmwpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95VGlsZSh1cmwsIHRpbGUpXG4gICAgICAgICAgICAgICAgY291bnQgKz0gMVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb3VudCAmJiB0aGlzLmRlYnVnKVxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Rlc3Ryb3lVbm5lZWRlZFRpbGVzJywgdGhpcy5sZXZlbCwgY291bnQpXG4gICAgfVxuXG4gICAgaGlnaGxpZ2h0SW5mb3MoKSB7XG4gICAgICAgIGxldCBncmFwaGljcyA9IHRoaXMuaW5mb1xuICAgICAgICBsZXQgY29sb3IgPSB0aGlzLmluZm9Db2xvclxuICAgICAgICBncmFwaGljcy5jbGVhcigpXG4gICAgICAgIGdyYXBoaWNzLmxpbmVTdHlsZSgyLCBjb2xvcilcbiAgICAgICAgZm9yIChsZXQgW2NvbCwgcm93XSBvZiB0aGlzLm5lZWRlZC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgbGV0IGRpbSA9IHRoaXMudGlsZURpbWVuc2lvbnMoY29sLCByb3cpXG4gICAgICAgICAgICBsZXQgcG9zID0gdGhpcy50aWxlUG9zaXRpb24oY29sLCByb3cpXG4gICAgICAgICAgICBncmFwaGljcy5iZWdpbkZpbGwoY29sb3IsIDAuMilcbiAgICAgICAgICAgIGdyYXBoaWNzLmRyYXdSZWN0KHBvcy54ICsgMSwgcG9zLnkgKyAxLCBkaW0ueCAtIDIsIGRpbS55IC0gMilcbiAgICAgICAgICAgIGdyYXBoaWNzLmVuZEZpbGwoKVxuICAgICAgICB9XG4gICAgICAgIGxldCByID0gdGhpcy5fYm91bmRzUmVjdFxuICAgICAgICBpZiAociAhPSBudWxsKSB7XG4gICAgICAgICAgICBncmFwaGljcy5saW5lU3R5bGUoMjAsIGNvbG9yKVxuICAgICAgICAgICAgZ3JhcGhpY3MuZHJhd1JlY3Qoci54LCByLnksIHIud2lkdGgsIHIuaGVpZ2h0KVxuICAgICAgICAgICAgZ3JhcGhpY3MubW92ZVRvKHIueCwgci55KVxuICAgICAgICAgICAgZ3JhcGhpY3MubGluZVRvKHIueCArIHIud2lkdGgsIHIueSArIHIuaGVpZ2h0KVxuXG4gICAgICAgICAgICBncmFwaGljcy5tb3ZlVG8oci54LCByLnkgKyByLmhlaWdodClcbiAgICAgICAgICAgIGdyYXBoaWNzLmxpbmVUbyhyLnggKyByLndpZHRoLCByLnkpXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcCA9IHRoaXMuX2NlbnRlclBvaW50XG4gICAgICAgIGlmIChwICE9IG51bGwpIHtcbiAgICAgICAgICAgIGdyYXBoaWNzLmRyYXdDaXJjbGUocC54LCBwLnksIDIwKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGludFRpbGVzKHF1YWRUcmVlcykge1xuICAgICAgICBmb3IgKGxldCBbdXJsLCB0aWxlXSBvZiB0aGlzLmF2YWlsYWJsZS5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGlmICghcXVhZFRyZWVzLmhhcyh1cmwpKSB0aWxlLnRpbnQgPSAweGZmMDAwMFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW50aW50VGlsZXMoKSB7XG4gICAgICAgIGZvciAobGV0IFt1cmwsIHRpbGVdIG9mIHRoaXMuYXZhaWxhYmxlLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgdGlsZS50aW50ID0gMHhmZmZmZmZcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7IENhcGFiaWxpdGllcyB9IGZyb20gJy4uLy4uL2NhcGFiaWxpdGllcy5qcydcbmltcG9ydCB7IFBvaW50cyB9IGZyb20gJy4uLy4uL3V0aWxzLmpzJ1xuaW1wb3J0IHsgZGVlcFpvb21UaWxlQ2FjaGUgfSBmcm9tICcuL3RpbGUuanMnXG5pbXBvcnQgeyBUaWxlcyB9IGZyb20gJy4vdGlsZXMuanMnXG5cbmZ1bmN0aW9uIGlzRXZlbihuKSB7XG4gICAgcmV0dXJuIG4gJSAyID09IDBcbn1cblxuXG5mdW5jdGlvbiBwcmludFRpbGVDYWNoZUluZm9zKCkge1xuICAgIGxldCByZWZlcmVuY2VzID0gbmV3IE1hcCgpXG4gICAgbGV0IG11bHRpcGxlcyA9IDBcbiAgICBmb3IgKGxldCBbdXJsLCB0aWxlc10gb2YgZGVlcFpvb21UaWxlQ2FjaGUuZW50cmllcygpKSB7XG4gICAgICAgIGxldCBjb3VudCA9IHRpbGVzLnNpemVcbiAgICAgICAgcmVmZXJlbmNlcy5zZXQodXJsLCBjb3VudClcbiAgICAgICAgaWYgKGNvdW50ID4gMSkge1xuICAgICAgICAgICAgbXVsdGlwbGVzICs9IDFcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyh7IG11bHRpcGxlcywgcmVmZXJlbmNlcyB9KVxufVxuLyoqXG4gKiBBIHV0aWxpdHkgY2xhc3MgdGhhdCBob2xkcyBpbmZvcm1hdGlvbiB0eXBpY2FsbHkgcHJvdmlkZWQgYnkgRFpJIGZpbGVzLCBpLmUuXG4gKiBoZWlnaHQgYW5kIHdpZHRoIG9mIHRoZSBvdmVyYWxsIGltYWdlLCBvdmVybGFwLCBhbmQgaW1hZ2UgdHlwZS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqfSBhdHRycyAtIEEgSlNPTi1PYmplY3QgaG9sZGluZyB0aGUgbGlzdGVkIGtleXMgYW5kIHZhbHVlc1xuICogQGV4YW1wbGVcbiAqICAgICB7XG4gKiAgICAgICAgIFwidGlsZVNpemVcIjogMTAyNCxcbiAqICAgICAgICAgXCJmb3JtYXRcIjogXCJqcGVnXCIsXG4gKiAgICAgICAgIFwib3ZlcmxhcFwiOiAxLFxuICogICAgICAgICBcImhlaWdodFwiOiA0Nzk0LFxuICogICAgICAgICBcIndpZHRoXCI6IDQwOTUsXG4gKiAgICAgICAgIFwiY2xpcFwiOiB7IFwibWluTGV2ZWxcIjogMTIsIFwibWF4TGV2ZWxcIjogMjAsIFwic3RhcnRDb2xcIjogMzAxNDM2LCBcInN0YXJ0Um93XCI6IDM1NDA2MCB9LFxuICogICAgICAgICAgICAgICAgICAgLy8gb3B0aW9uYWw6IG1pbkxldmVsIGFuZCBtYXhMZXZlbCBkZWZpbmUgdGhlIGxldmVsIGJvdW5kc1xuICogICAgICAgICAgICAgICAgICAgLy8gc3RhcnRDb2w6IGZpcnN0IGNvbCBhdCBtYXhMZXZlbFxuICogICAgICAgICAgICAgICAgICAgLy8gc3RhcnRSb3c6IGZpcnN0IHJvdyBhdCBtYXhMZXZlbFxuICogICAgICAgICBcInBhdGhcIjogXCJ2YXIvVmVybWVlci9WZXJtZWVyX2ZpbGVzXCIsXG4gKiAgICAgICAgIFwidHlwZVwiOiBcImR6aVwiLCAgLy8gb3B0aW9uYWw6IGR6aSAoZGVmYXVsdCkgb3IgbWFwXG4gKiAgICAgICAgIFwidXJsVGlsZVRlbXBsYXRlXCI6IFwie3BhdGh9L3tsZXZlbH0ve2NvbHVtbn0ve3Jvd30ue2Zvcm1hdH1cIlxuICogICAgICAgICAgIC8vIG9wdGlvbmFsOiB7cGF0aH0ve2xldmVsfS97Y29sdW1ufV97cm93fS57Zm9ybWF0fSAoZGVmYXVsdCkgb3JcbiAqICAgICAgICAgICAvLyBhIHRlbXBsYXRlIFN0cmluZyB3aXRoIHRoZSBmb3JtYXQgb2YgdGhlIFVSTFxuICogICAgIH1cbiAqL1xuZXhwb3J0IGNsYXNzIERlZXBab29tSW5mbyB7XG4gICAgY29uc3RydWN0b3IoYXR0cnMpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIGF0dHJzKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBhdHRyc1trZXldXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tYXhMZXZlbCA9IDAgLy8gVGhlIGhpZ2hlc3QgbGV2ZWwgbnVtYmVyLCB0eXBpY2FsbHkgY29ycmVzcG9uZHMgdG8gdGhlXG4gICAgICAgIC8vIG51bWJlciBpbiB0aGUgZmlsZSBzeXN0ZW0gZm9yIHRoZSBmb2xkZXIgd2l0aCB0aWxlc1xuICAgICAgICB0aGlzLmNsaXAgPSB0aGlzLmNsaXAgfHwgbnVsbCAvLyBlLmcuIHsgbGV2ZWw6IDEyLCBjb2w6IDMwMTQzNiwgcm93OiAzNTQwNjAgfVxuICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnR5cGUgfHwgJ2R6aSdcbiAgICAgICAgdGhpcy51cmxUaWxlVGVtcGxhdGUgPVxuICAgICAgICAgICAgdGhpcy51cmxUaWxlVGVtcGxhdGUgfHwgJ3twYXRofS97bGV2ZWx9L3tjb2x1bW59X3tyb3d9Lntmb3JtYXR9J1xuICAgICAgICB0aGlzLnNldHVwRGltZW5zaW9ucygpXG4gICAgfVxuXG4gICAgLyogQ29tcHV0ZXMgdGhlIG5lZWRlZCBudW1iZXIgb2YgbGF5ZXJzIGZyb20gdGhlIHdpZHRoIGFuZCBoZWlnaHRcbiAgICAqICBvZiB0aGUgaW1hZ2UuIE5vdGUgdGhhdCB0aGlzIGluY2x1ZGVzIHRoZSBsZXZlbCAwLCBpLmUuIDAgLi4uIDRcbiAgICAqIG1lYW5zIHRoYXQgNSBsZXZlbHMgZXhpc3QuXG4gICAgKiovXG4gICAgbnVtTGV2ZWxzKCkge1xuICAgICAgICBsZXQgbWF4RGltZW5zaW9uID0gTWF0aC5tYXgodGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpXG4gICAgICAgIGxldCBib3VuZGFyeSA9IHRoaXMudHlwZSA9PT0gJ2R6aScgPyAxIDogdGhpcy50aWxlU2l6ZVxuICAgICAgICBsZXQgbnVtTGV2ZWxzID0gMFxuICAgICAgICB3aGlsZSAobWF4RGltZW5zaW9uID49IGJvdW5kYXJ5KSB7XG4gICAgICAgICAgICBtYXhEaW1lbnNpb24gLz0gMlxuICAgICAgICAgICAgbnVtTGV2ZWxzKytcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVtTGV2ZWxzXG4gICAgfVxuXG4gICAgLyoqIENvbXB1dGVzIHRoZSBzY2FsZSBhdCB0aGUgZ2l2ZW4gbGV2ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIC0gVGhlIGxldmVsIG9mIHRoZSB3YW50ZWQgbGF5ZXJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzY2FsZVxuICAgICAqKi9cbiAgICBnZXRTY2FsZShsZXZlbCkge1xuICAgICAgICBsZXQgc2NhbGUgPSAxXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdkemknKSB7XG4gICAgICAgICAgICBzY2FsZSA9IE1hdGgucG93KDAuNSwgdGhpcy5tYXhMZXZlbCAtIGxldmVsICsgMSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNjYWxlID0gTWF0aC5wb3coMC41LCB0aGlzLm1heExldmVsIC0gbGV2ZWwpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjYWxlXG4gICAgfVxuXG4gICAgLyoqIENvbXB1dGVzIHRoZSBzY2FsZWQgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgZ2l2ZW4gbGV2ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIC0gVGhlIGxldmVsIG9mIHRoZSB3YW50ZWQgbGF5ZXJcbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9IHNpemUgLSBUaGUgd2lkdGggYW5kIGhlaWdodFxuICAgICAqKi9cbiAgICBnZXREaW1lbnNpb25zKGxldmVsKSB7XG4gICAgICAgIGxldCBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUobGV2ZWwpXG4gICAgICAgIGxldCB3ID0gTWF0aC5jZWlsKHRoaXMud2lkdGggKiBzY2FsZSlcbiAgICAgICAgbGV0IGggPSBNYXRoLmNlaWwodGhpcy5oZWlnaHQgKiBzY2FsZSlcbiAgICAgICAgcmV0dXJuIFt3LCBoXVxuICAgIH1cblxuICAgIC8qKiBDb21wdXRlcyB0aGUgbnVtYmVyIG9mIGNvbHMgYW5kIHJvd3Mgb2YgdGlsZXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIC0gVGhlIGxldmVsIG9mIHRoZSB3YW50ZWQgbGF5ZXJcbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9IHNpemUgLSBUaGUgY29scyBhbmQgcm93c1xuICAgICAqKi9cbiAgICBnZXROdW1UaWxlcyhsZXZlbCkge1xuICAgICAgICBsZXQgZGltID0gdGhpcy5nZXREaW1lbnNpb25zKGxldmVsKVxuICAgICAgICBsZXQgY29scyA9IE1hdGguY2VpbChkaW1bMF0gLyB0aGlzLnRpbGVTaXplKVxuICAgICAgICBsZXQgcm93cyA9IE1hdGguY2VpbChkaW1bMV0gLyB0aGlzLnRpbGVTaXplKVxuICAgICAgICBpZiAodGhpcy5jbGlwKSB7XG4gICAgICAgICAgICBsZXQgcmVzdCA9IHRoaXMucmVzdHNbbGV2ZWxdXG4gICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXN0LnJlc3RDb2wpIHtcbiAgICAgICAgICAgICAgICAgICAgY29scyArPSAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXN0LnJlc3RSb3dzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJvd3MgKz0gMVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2NvbHMsIHJvd3NdXG4gICAgfVxuXG4gICAgc2V0dXBEaW1lbnNpb25zKGxvYWRCYXNlSW1hZ2UgPSBmYWxzZSkge1xuICAgICAgICAvKiogU2V0dXAgaW5zdGFuY2UgdmFyaWFibGVzIGFuZCBsb2FkIHRoZSBiYXNlIGltYWdlLCBpLmUuIHRoZSBsYXJnZXN0XG4gICAgICAgIGltYWdlIHRoYXQgY2FuIGJlIHJlcHJlc2VudGVkIGFzIGEgc2luZ2xlIHRpbGUuXG4gICAgICAgIEBwcml2YXRlXG4gICAgICAgICoqL1xuICAgICAgICBsZXQgd3cgPSB0aGlzLndpZHRoXG4gICAgICAgIGxldCBoaCA9IHRoaXMuaGVpZ2h0XG4gICAgICAgIGxldCBzY2FsZSA9IDEuMFxuICAgICAgICBsZXQgbGV2ZWwgPSAwXG4gICAgICAgIGxldCBzaW5nbGUgPSAwXG4gICAgICAgIGNvbnN0IHRzaXplID0gdGhpcy50aWxlU2l6ZVxuXG4gICAgICAgIGlmICh0aGlzLmNsaXApIHtcbiAgICAgICAgICAgIHRoaXMuYmFzZUxldmVsID0gdGhpcy5jbGlwLm1pbkxldmVsXG4gICAgICAgICAgICB0aGlzLm1heExldmVsID0gdGhpcy5jbGlwLm1heExldmVsXG4gICAgICAgICAgICB0aGlzLmJhc2VJbWFnZSA9IG51bGxcbiAgICAgICAgICAgIHRoaXMuc2l6ZSA9IHRoaXMuZ2V0RGltZW5zaW9ucyh0aGlzLmJhc2VMZXZlbClcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0cyA9IHt9XG4gICAgICAgICAgICB0aGlzLnJlc3RzID0ge31cbiAgICAgICAgICAgIGxldCBzdGFydENvbCA9IHRoaXMuY2xpcC5zdGFydENvbFxuICAgICAgICAgICAgbGV0IHN0YXJ0Um93ID0gdGhpcy5jbGlwLnN0YXJ0Um93XG4gICAgICAgICAgICBsZXQgZmxvYXRTdGFydENvbCA9IHN0YXJ0Q29sXG4gICAgICAgICAgICBsZXQgZmxvYXRTdGFydFJvdyA9IHN0YXJ0Um93XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5tYXhMZXZlbDsgaSA+PSB0aGlzLmJhc2VMZXZlbDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXRzW2ldID0geyBzdGFydENvbCwgc3RhcnRSb3cgfVxuICAgICAgICAgICAgICAgIGxldCByZXN0Q29sID0gZmxvYXRTdGFydENvbCAlIDFcbiAgICAgICAgICAgICAgICBsZXQgcmVzdFJvdyA9IGZsb2F0U3RhcnRSb3cgJSAxXG4gICAgICAgICAgICAgICAgdGhpcy5yZXN0c1tpXSA9IHsgcmVzdENvbCwgcmVzdFJvdyB9XG4gICAgICAgICAgICAgICAgc3RhcnRDb2wgPSBNYXRoLmZsb29yKHN0YXJ0Q29sIC8gMilcbiAgICAgICAgICAgICAgICBzdGFydFJvdyA9IE1hdGguZmxvb3Ioc3RhcnRSb3cgLyAyKVxuICAgICAgICAgICAgICAgIGZsb2F0U3RhcnRDb2wgLz0gMlxuICAgICAgICAgICAgICAgIGZsb2F0U3RhcnRSb3cgLz0gMlxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYm91bmRhcnkgPSB0aGlzLnR5cGUgPT09ICdkemknID8gMS4wIDogdHNpemVcbiAgICAgICAgICAgIHdoaWxlICh3dyA+IGJvdW5kYXJ5ICYmIGhoID4gYm91bmRhcnkpIHtcbiAgICAgICAgICAgICAgICBpZiAod3cgPj0gdHNpemUgJiYgaGggPj0gdHNpemUpIHtcbiAgICAgICAgICAgICAgICAgICAgc2luZ2xlICs9IDFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2NhbGUgPSBzY2FsZSAvIDIuMFxuICAgICAgICAgICAgICAgIHd3ID0gTWF0aC5jZWlsKHRoaXMud2lkdGggKiBzY2FsZSlcbiAgICAgICAgICAgICAgICBoaCA9IE1hdGguY2VpbCh0aGlzLmhlaWdodCAqIHNjYWxlKVxuICAgICAgICAgICAgICAgIGxldmVsICs9IDFcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYmFzZUxldmVsID0gbGV2ZWwgLSBzaW5nbGVcbiAgICAgICAgICAgIHRoaXMubWF4TGV2ZWwgPSB0aGlzLm51bUxldmVscygpIC0gMVxuICAgICAgICAgICAgdGhpcy5iYXNlVVJMID0gdGhpcy51cmxGb3JUaWxlKHRoaXMuYmFzZUxldmVsLCAwLCAwLCBmYWxzZSlcblxuICAgICAgICAgICAgaWYgKGxvYWRCYXNlSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlRm9yVVJMKHRoaXMuYmFzZVVSTCwgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2l6ZSA9IFtlLnRhcmdldC5uYXR1cmFsV2lkdGgsIGUudGFyZ2V0Lm5hdHVyYWxIZWlnaHRdXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmFzZUltYWdlID0gZS50YXJnZXRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJhc2VJbWFnZSA9IG51bGxcbiAgICAgICAgICAgICAgICB0aGlzLnNpemUgPSB0aGlzLmdldERpbWVuc2lvbnModGhpcy5iYXNlTGV2ZWwpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbWF4TG9hZGFibGVMZXZlbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2xpcCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWF4TGV2ZWxcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnZHppJyA/IHRoaXMubWF4TGV2ZWwgOiB0aGlzLm1heExldmVsXG4gICAgfVxuXG4gICAgLyoqIENvbXB1dGVzIHRoZSB1cmwgZm9yIHRoZSBnaXZlbiBsZXZlbCwgY29sdW1uIGFuZCBhbmQgcm93LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSBsZXZlbCBvZiB0aGUgd2FudGVkIGxheWVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNvbHVtbiAtIFRoZSBjb2x1bW4gb2YgdGhlIHRpbGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcm93IC0gVGhlIHJvdyBvZiB0aGUgdGlsZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IHVybFxuICAgICAqKi9cbiAgICB1cmxGb3JUaWxlKGxldmVsLCBjb2x1bW4sIHJvdywgY29tcHJlc3NlZCA9IHRydWUpIHtcbiAgICAgICAgbGV0IGZvcm1hdCA9IHRoaXMuZm9ybWF0XG4gICAgICAgIGlmIChjb21wcmVzc2VkICYmIHRoaXMuY29tcHJlc3Npb24pIHtcbiAgICAgICAgICAgIGxldCBzdXBwb3J0ZWQgPSBDYXBhYmlsaXRpZXMuaXNJT1MgPyAncHZyJyA6ICdkZHMnXG4gICAgICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbi5pbmRleE9mKHN1cHBvcnRlZCkgPj0gMCkge1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHN1cHBvcnRlZFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNsaXApIHtcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSB0aGlzLm9mZnNldHNbbGV2ZWxdXG4gICAgICAgICAgICBpZiAob2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgc3RhcnRDb2wsIHN0YXJ0Um93IH0gPSBvZmZzZXRcbiAgICAgICAgICAgICAgICBjb2x1bW4gKz0gc3RhcnRDb2xcbiAgICAgICAgICAgICAgICByb3cgKz0gc3RhcnRSb3dcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgdXJsID0gdGhpcy51cmxUaWxlVGVtcGxhdGVcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXHtwYXRoXFx9L2csIHRoaXMucGF0aClcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXHtsZXZlbFxcfS9nLCBsZXZlbClcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXHtyb3dcXH0vZywgcm93KVxuICAgICAgICAgICAgLnJlcGxhY2UoL1xce2NvbHVtblxcfS9nLCBjb2x1bW4pXG4gICAgICAgICAgICAucmVwbGFjZSgvXFx7Zm9ybWF0XFx9L2csIGZvcm1hdClcbiAgICAgICAgcmV0dXJuIHVybFxuICAgIH1cblxuICAgIC8qKiBMb2FkcyB0aGUgaW1hZ2UgZm9yIHRoZSBnaXZlbiB1cmwgYW5kIGV4ZWN1dGVzIGEgY2FsbGJhY2sgZnVuY3Rpb25cbiAgICBvbiBjb21wbGV0aW9uLlxuICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSB1cmwgb2YgdGhlIHRpbGVcbiAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNvbXBsZXRlIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uXG4gICAgKiBAcmV0dXJucyB7SW1hZ2V9IG9ialxuICAgICoqL1xuICAgIGltYWdlRm9yVVJMKHVybCwgY29tcGxldGUpIHtcbiAgICAgICAgbGV0IGltZyA9IG5ldyBJbWFnZSgpXG4gICAgICAgIGltZy5vbmxvYWQgPSBjb21wbGV0ZS5iaW5kKHRoaXMpXG4gICAgICAgIGltZy5zcmMgPSB1cmxcbiAgICAgICAgcmV0dXJuIGltZ1xuICAgIH1cblxuICAgIC8qKiBDb21wdXRlcyB0aGUgY29sdW1ucyBhbmQgcm93cyBhcyB3ZWxsIGFzIHNjYWxlZCB3aWR0aCBhbmQgaGVpZ2h0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSBsZXZlbCBvZiB0aGUgd2FudGVkIGxheWVyXG4gICAgICogQHJldHVybnMge2FycmF5fSBbY29scywgcm93cywgd2lkdGgsIGhlaWdodF1cbiAgICAgKiovXG4gICAgZGltZW5zaW9ucyhsZXZlbCkge1xuICAgICAgICBsZXQgZGltID0gdGhpcy5nZXREaW1lbnNpb25zKGxldmVsKVxuICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLmdldE51bVRpbGVzKGxldmVsKVxuICAgICAgICByZXR1cm4gW3RpbGVzWzBdLCB0aWxlc1sxXSwgZGltWzBdLCBkaW1bMV1dXG4gICAgfVxuXG4gICAgdGVzdCgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInc9XCIgKyB0aGlzLndpZHRoICsgXCIgaD1cIiArIHRoaXMuaGVpZ2h0ICsgXCIgbWF4bGV2ZWw9XCIgKyB0aGlzLm1heExldmVsICsgXCIgYmFzZT1cIiArIHRoaXMuYmFzZUxldmVsKVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSB0aGlzLm1heExldmVsOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICcgJyArXG4gICAgICAgICAgICAgICAgaSArXG4gICAgICAgICAgICAgICAgJyAtPiAnICtcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNjYWxlKGkpICtcbiAgICAgICAgICAgICAgICAnIFsnICtcbiAgICAgICAgICAgICAgICB0aGlzLmRpbWVuc2lvbnMoaSkgK1xuICAgICAgICAgICAgICAgICddJ1xuICAgICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMudXJsRm9yVGlsZSh0aGlzLmJhc2VMZXZlbCwgMCwgMCkpXG4gICAgfVxufVxuXG4vKipcbiAqIEEgdXRpbGl0eSBjbGFzcyB0aGF0IGRlc2NyaWJlcyBhIHF1YWQgdHJlZSBvZiB0aWxlcy4gRWFjaCB0aWxlIG9uIGEgZ2l2ZW5cbiAqIGxldmVsIGhhcyB1cCB0byBmb3VyIGNvcnJlc3BvbmRpbmcgdGlsZXMgb24gdGhlIG5leHQgbGV2ZWwuIEEgVGlsZVF1YWROb2RlXG4gKiB1c2VzIHRoZSBhdHRyaWJ1dGVzIG53IChpLmUuIG5vcnRod2VzdCksIG5lLCBzdywgc2UgdG8gbGluayB0byB0aGVcbiAqIHF1YWQgbm9kZXMgb24gdGhlIG5leHQgbGV2ZWwuIFRoZSBwcmV2aW91cyBhdHRyaWJ1dGVzIGxpbmtzIHRvIHRoZSBxdWFkXG4gKiBvbmUgbGV2ZWwgYmVsb3cgdGhhdCBob2xkcyB0aGUgZ2l2ZW4gcXVhZCBhcyBudywgbmUsIHN3LCBvciBzZS5cbiAqIFdlIHVzZSB0aGlzIG5vZGUgY2xhc3MgYmVjYXVzZSB3ZSBuZWVkIGEgcmVwcmVzZW50YXRpb24gb2YgdGlsZXMgdGhhdCBhcmVcbiAqIG5lZWRlZCBidXQgbm90IGxvYWRlZCB5ZXQgdG8gY29tcHV0ZSB0aWxlcyB3aGljaCBjYW4gYmUgYWJhbmRvbmVkIHRvIHJlZHVjZVxuICogdGhlIG1lbW9yeSBwcmVzc3VyZS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bGV2ZWx9IE51bWJlciAtIFRoZSBsZXZlbCB0aGUgcXVhZCBub2RlIGJlbG9uZ3MgdG9cbiAqIEBwYXJhbSB7Y29sfSBOdW1iZXIgLSBUaGUgY29sIG9mIHRoZSBxdWFkXG4gKiBAcGFyYW0ge3Jvd30gTnVtYmVyIC0gVGhlIGxldmVsIHRoZSBxdWFkIG5vZGUgYmVsb25ncyB0b1xuICogQHBhcmFtIHt1cmx9IFN0cmluZyAtIFRoZSBsZXZlbCB0aGUgcXVhZCBub2RlIGJlbG9uZ3MgdG9cbiAqL1xuY2xhc3MgVGlsZVF1YWROb2RlIHtcbiAgICBjb25zdHJ1Y3RvcihsZXZlbCwgY29sLCByb3csIHVybCkge1xuICAgICAgICB0aGlzLmxldmVsID0gbGV2ZWxcbiAgICAgICAgdGhpcy5jb2wgPSBjb2xcbiAgICAgICAgdGhpcy5yb3cgPSByb3dcbiAgICAgICAgdGhpcy51cmwgPSB1cmxcbiAgICAgICAgdGhpcy5udyA9IG51bGxcbiAgICAgICAgdGhpcy5uZSA9IG51bGxcbiAgICAgICAgdGhpcy5zdyA9IG51bGxcbiAgICAgICAgdGhpcy5zZSA9IG51bGxcbiAgICAgICAgdGhpcy5wcmV2aW91cyA9IG51bGxcbiAgICB9XG5cbiAgICAvKiogUmV0dXJuIFRydWUgaWYgdGhpcyBub2RlIGhhcyBubyBzdWNjZXNzb3JzIGFuZCBjYW4gYmUgdXNlZCBhc1xuICAgIGFuIGluZGljYXRvciBvZiB0aWxlcyB0byBmcmVlLlxuICAgICoqL1xuICAgIG5vUXVhZHMoKSB7XG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzID09PSBudWxsKSByZXR1cm4gZmFsc2VcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMubncgPT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMubmUgPT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMuc3cgPT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMuc2UgPT09IG51bGxcbiAgICAgICAgKVxuICAgIH1cblxuICAgIC8qKiBVbmxpbmsgdGhlIGdpdmVuIHF1YWQgbm9kZVxuXG4gICAgKiBAcGFyYW0ge25vZGV9IFRpbGVRdWFkTm9kZSAtIFRoZSBUaWxlUXVhZE5vZGUgdG8gcmVtb3ZlXG4gICAgKiovXG4gICAgdW5saW5rKG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMubncgPT09IG5vZGUpIHRoaXMubncgPSBudWxsXG4gICAgICAgIGlmICh0aGlzLm5lID09PSBub2RlKSB0aGlzLm5lID0gbnVsbFxuICAgICAgICBpZiAodGhpcy5zdyA9PT0gbm9kZSkgdGhpcy5zdyA9IG51bGxcbiAgICAgICAgaWYgKHRoaXMuc2UgPT09IG5vZGUpIHRoaXMuc2UgPSBudWxsXG4gICAgfVxuXG4gICAgLyoqIExpbmsgdGhpcyBxdWFkIG5vZGUgdG8gdGhlIGdpdmVuIHByZXZpb3VzIG5vZGUuIFVzZSB0aGUgbm9ydGhcbiAgICAqIGFuZCB3ZXN0IGZsYWdzIHRvIGFkZHJlc3MgbncsIG5lLCBzdywgYW5kIHNlLlxuXG4gICAgKiBAcGFyYW0ge25vZGV9IFRpbGVRdWFkTm9kZSAtIFRoZSBUaWxlUXVhZE5vZGUgdG8gcmVtb3ZlXG4gICAgKiBAcGFyYW0ge25vcnRofSBCb29sZWFuIC0gTGluayB0byBub3J0aCAodHJ1ZSkgb3Igc291dGggKGZhbHNlKVxuICAgICogQHBhcmFtIHt3ZXN0fSBCb29sZWFuIC0gTGluayB0byB3ZXN0ICh0cnVlKSBvciBlYXN0IChmYWxzZSlcbiAgICAqKi9cbiAgICBsaW5rKG5vcnRoLCB3ZXN0LCBwcmV2aW91cykge1xuICAgICAgICB0aGlzLnByZXZpb3VzID0gcHJldmlvdXNcbiAgICAgICAgaWYgKG5vcnRoKSB7XG4gICAgICAgICAgICBpZiAod2VzdCkge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzLm53ID0gdGhpc1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91cy5uZSA9IHRoaXNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh3ZXN0KSB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXMuc3cgPSB0aGlzXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzLnNlID0gdGhpc1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbi8qKlxuICogVGhlIG1haW4gY2xhc3Mgb2YgYSBkZWVwbHkgem9vbWFibGUgaW1hZ2UgdGhhdCBpcyByZXByZXNlbnRlZCBieSBhIGhpZXJhcmNoeVxuICogb2YgdGlsZSBsYXllcnMgZm9yIGVhY2ggem9vbSBsZXZlbC4gVGhpcyBnaXZlcyB0aGUgdXNlciB0aGUgaW1wcmVzc2lvbiB0aGF0XG4gKiBldmVuIGh1Z2UgcGljdHVyZXMgKHVwIHRvIGdpZ2FwaXhlbC1pbWFnZXMpIGNhbiBiZSB6b29tZWQgaW5zdGFudGFuZW91c2x5LFxuICogc2luY2UgdGhlIHRpbGVzIGF0IHNtYWxsZXIgbGV2ZWxzIGFyZSBzY2FsZWQgaW1tZWRpYXRlbHkgYW5kIG92ZXJsb2FkZWQgYnlcbiAqIG1vcmUgZGV0YWlsZWQgdGlsZXMgYXQgdGhlIGxhcmdlciBsZXZlbCBhcyBmYXN0IGFzIHBvc3NpYmxlLlxuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7RGVlcFpvb21JbmZvfSBkZWVwWm9vbUluZm8gLSBJbmZvcm1hdGlvbiBleHRyYWN0ZWQgZnJvbSBhIEpTT04tT2JqZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBEZWVwWm9vbUltYWdlIGV4dGVuZHMgUElYSS5Db250YWluZXIge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBkZWVwWm9vbUluZm8sXG4gICAgICAgIHtcbiAgICAgICAgICAgIGRlYnVnID0gZmFsc2UsXG4gICAgICAgICAgICBzaGFkb3cgPSBmYWxzZSxcbiAgICAgICAgICAgIGNlbnRlciA9IGZhbHNlLFxuICAgICAgICAgICAgd29ybGQgPSBudWxsLCAgICAgICAgICAgICAgIC8vIERlZmluZXMgdGhlIHdvcmxkIGJvdW5kcyB0aGUgaW1hZ2VzIGxpdmVzIGluXG4gICAgICAgICAgICBoaWdoUmVzb2x1dGlvbiA9IHRydWUsXG4gICAgICAgICAgICBhdXRvTG9hZFRpbGVzID0gdHJ1ZSxcbiAgICAgICAgICAgIHByZWZlcldvcmtlciA9IGZhbHNlLFxuICAgICAgICAgICAgbWluaW11bUxldmVsID0gMCxcbiAgICAgICAgICAgIGFscGhhID0gMSxcbiAgICAgICAgICAgIGFwcCA9IHdpbmRvdy5hcHBcbiAgICAgICAgfSA9IHt9XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy5hcHAgPSBhcHBcbiAgICAgICAgdGhpcy5kZWJ1ZyA9IGRlYnVnXG4gICAgICAgIHRoaXMuc2hhZG93ID0gc2hhZG93XG4gICAgICAgIHRoaXMud29ybGQgPSB3b3JsZFxuICAgICAgICB0aGlzLnByZWZlcldvcmtlciA9IHByZWZlcldvcmtlclxuICAgICAgICB0aGlzLnJlc29sdXRpb24gPSBoaWdoUmVzb2x1dGlvblxuICAgICAgICAgICAgPyBNYXRoLnJvdW5kKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKVxuICAgICAgICAgICAgOiAxXG4gICAgICAgIHRoaXMuYWxwaGEgPSBhbHBoYVxuICAgICAgICB0aGlzLmZhc3RMb2FkcyA9IDBcbiAgICAgICAgdGhpcy5hdXRvTG9hZFRpbGVzID0gYXV0b0xvYWRUaWxlc1xuICAgICAgICB0aGlzLm1pbmltdW1MZXZlbCA9IG1pbmltdW1MZXZlbFxuICAgICAgICB0aGlzLnF1YWRUcmVlcyA9IG5ldyBNYXAoKSAvLyB1cmwgYXMga2V5cywgVGlsZVF1YWROb2RlcyBhcyB2YWx1ZXNcbiAgICAgICAgdGhpcy5zZXR1cChkZWVwWm9vbUluZm8sIGNlbnRlcilcbiAgICB9XG5cbiAgICBnZXQgcG9pbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9wb2ludCA9PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgZ3JhcGhpY3MgPSBuZXcgUElYSS5HcmFwaGljcygpXG4gICAgICAgICAgICBncmFwaGljcy5saW5lU3R5bGUoMiwgMHgwMGZmMDApXG4gICAgICAgICAgICBncmFwaGljcy5kcmF3Q2lyY2xlKDAsIDAsIDIpXG4gICAgICAgICAgICBncmFwaGljcy5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLl9wb2ludCA9IGdyYXBoaWNzXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvaW50XG4gICAgfVxuXG4gICAgLyoqIFJlYWRzIHRoZSBEZWVwWm9vbUluZm8gb2JqZWN0IGFuZCBpbml0aWFsaXplcyBhbGwgdGlsZSBsYXllcnMuXG4gICAgICogQ2FsbGVkIGJ5IHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBDcmVhdGVzIHRoZSBzcHJpdGUgZm9yIHRoZSBsb2FkZWQgdGV4dHVyZSBhbmQgYWRkIHRoZSBzcHJpdGUgdG8gdGhlIHRpbGVcbiAgICAgKiBsYXllci5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGVlcFpvb21JbmZvIC0gdGhlIERlZXBab29tSW5mbyBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gY2VudGVyIC0gSWYgdHJ1ZSBlbnN1cmVzIHRoYXQgdGhlIHBpdm90IGlzIHNldCB0byB0aGUgY2VudGVyXG4gICAgICoqL1xuICAgIHNldHVwKGRlZXBab29tSW5mbywgY2VudGVyKSB7XG4gICAgICAgIHRoaXMuaW5mbyA9IGRlZXBab29tSW5mb1xuICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gdHJ1ZVxuICAgICAgICB0aGlzLnRpbGVMYXllcnMgPSB7fVxuXG4gICAgICAgIHRoaXMuX2ZvcmVncm91bmQgPSBudWxsXG4gICAgICAgIHRoaXMudGlsZUNvbnRhaW5lciA9IG5ldyBQSVhJLkNvbnRhaW5lcigpXG4gICAgICAgIHRoaXMudGlsZUNvbnRhaW5lci5pbnRlcmFjdGl2ZSA9IGZhbHNlXG5cbiAgICAgICAgbGV0IFt3LCBoXSA9IHRoaXMuYmFzZVNpemVcbiAgICAgICAgaWYgKHRoaXMuc2hhZG93KSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcnMgPSBbbmV3IFBJWEkuZmlsdGVycy5Ecm9wU2hhZG93RmlsdGVyKDQ1LCAzKV1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMudGlsZUNvbnRhaW5lcilcblxuICAgICAgICBpZiAoZGVlcFpvb21JbmZvLmNsaXApIHtcbiAgICAgICAgICAgIGxldCBtYXNrID0gbmV3IFBJWEkuR3JhcGhpY3MoKVxuICAgICAgICAgICAgbWFzay5iZWdpbkZpbGwoMSwgMSlcbiAgICAgICAgICAgIG1hc2suZHJhd1JlY3QoMCwgMCwgdywgaClcbiAgICAgICAgICAgIG1hc2suZW5kRmlsbCgpXG4gICAgICAgICAgICB0aGlzLm1hc2sgPSBtYXNrXG4gICAgICAgICAgICBtYXNrLmFscGhhID0gMFxuICAgICAgICAgICAgdGhpcy5hZGRDaGlsZChtYXNrKVxuICAgICAgICAgICAgdGhpcy5taW5pbXVtTGV2ZWwgPSBkZWVwWm9vbUluZm8uYmFzZUxldmVsXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJyZW50TGV2ZWwgPSBNYXRoLm1heCh0aGlzLm1pbmltdW1MZXZlbCwgZGVlcFpvb21JbmZvLmJhc2VMZXZlbClcbiAgICAgICAgY29uc29sZS5sb2coXCJhdXRvTG9hZFRpbGVzXCIsIHRoaXMuYXV0b0xvYWRUaWxlcylcbiAgICAgICAgaWYgKHRoaXMuYXV0b0xvYWRUaWxlcykge1xuICAgICAgICAgICAgdGhpcy5zZXR1cFRpbGVzKGNlbnRlcilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBEZWZhdWx0IHNldHVwIG1ldGhvZCBmb3IgdGlsZXMuIExvYWRzIGFsbCB0aWxlcyBvZiB0aGUgY3VycmVudCBsZXZlbC5cbiAgICBDYW4gYmUgb3ZlcndyaXR0ZW4gaW4gc3ViY2xhc3Nlcy5cbiAgICBAcGFyYW0ge2Jvb2xlYW59IGNlbnRlciAtIElmIHRydWUgZW5zdXJlcyB0aGF0IHRoZSBwaXZvdCBpcyBzZXQgdG8gdGhlIGNlbnRlclxuICAgICoqL1xuICAgIHNldHVwVGlsZXMoY2VudGVyID0gZmFsc2UpIHtcbiAgICAgICAgLy8gRmlyc3QgbG9hZCBiYWNrZ3JvdW5kIHRpbGVcbiAgICAgICAgbGV0IHRpbGVzID0gdGhpcy5lbnN1cmVBbGxUaWxlcyh0aGlzLmN1cnJlbnRMZXZlbClcbiAgICAgICAgaWYgKGNlbnRlcikge1xuICAgICAgICAgICAgdGhpcy5waXZvdC5zZXQodyAvIDIsIGggLyAyKVxuICAgICAgICB9XG4gICAgICAgIGxldCBzY2FsZUxldmVsID0gdGhpcy5sZXZlbEZvclNjYWxlKDEpXG4gICAgICAgIHRoaXMuZW5zdXJlQWxsVGlsZXMoc2NhbGVMZXZlbClcbiAgICB9XG5cbiAgICByZW1vdmVUaWxlUXVhZE5vZGUobGV2ZWwsIGNvbCwgcm93LCB1cmwpIHtcbiAgICAgICAgaWYgKHRoaXMucXVhZFRyZWVzLmhhcyh1cmwpKSB7XG4gICAgICAgICAgICBsZXQgcXVhZCA9IHRoaXMucXVhZFRyZWVzLmdldCh1cmwpXG4gICAgICAgICAgICB0aGlzLnRpbGVRdWFkUmVtb3ZlZChxdWFkKVxuICAgICAgICAgICAgdGhpcy5xdWFkVHJlZXMuZGVsZXRlKHVybClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFkZFRpbGVRdWFkTm9kZShsZXZlbCwgY29sLCByb3csIHVybCkge1xuICAgICAgICBpZiAodGhpcy5xdWFkVHJlZXMuaGFzKHVybCkpIHJldHVybiB0aGlzLnF1YWRUcmVlcy5nZXQodXJsKVxuICAgICAgICBsZXQgcXVhZCA9IG5ldyBUaWxlUXVhZE5vZGUobGV2ZWwsIGNvbCwgcm93LCB1cmwpXG4gICAgICAgIHRoaXMucXVhZFRyZWVzLnNldCh1cmwsIHF1YWQpXG4gICAgICAgIHRoaXMudGlsZVF1YWRBZGRlZChxdWFkKVxuICAgICAgICByZXR1cm4gcXVhZFxuICAgIH1cblxuICAgIHRpbGVRdWFkUmVtb3ZlZChxdWFkKSB7XG4gICAgICAgIGxldCBiZWxvdyA9IHF1YWQucHJldmlvdXNcbiAgICAgICAgLy8gaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKFwidGlsZVF1YWRSZW1vdmVkXCIsIHF1YWQpXG4gICAgICAgIGlmIChiZWxvdykge1xuICAgICAgICAgICAgYmVsb3cudW5saW5rKHF1YWQpXG4gICAgICAgICAgICBpZiAoYmVsb3cubm9RdWFkcygpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUubG9nKCdSZW1vdmVkIHRpbGUgYmVsb3cnKVxuICAgICAgICAgICAgICAgIGxldCBsZXZlbEJlbG93ID0gcXVhZC5sZXZlbCAtIDFcbiAgICAgICAgICAgICAgICBpZiAobGV2ZWxCZWxvdyA8IHRoaXMubWluaW11bUxldmVsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBsZXQgYyA9IE1hdGguZmxvb3IocXVhZC5jb2wgLyAyKVxuICAgICAgICAgICAgICAgIGxldCByID0gTWF0aC5mbG9vcihxdWFkLnJvdyAvIDIpXG4gICAgICAgICAgICAgICAgbGV0IHVybEJlbG93ID0gdGhpcy5pbmZvLnVybEZvclRpbGUobGV2ZWxCZWxvdywgYywgcilcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5xdWFkVHJlZXMuaGFzKHVybEJlbG93KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZVRpbGVRdWFkTm9kZShsZXZlbEJlbG93LCBjLCByLCB1cmxCZWxvdylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aWxlUXVhZEFkZGVkKHF1YWQpIHtcbiAgICAgICAgbGV0IGxldmVsQmVsb3cgPSBxdWFkLmxldmVsIC0gMVxuICAgICAgICBpZiAobGV2ZWxCZWxvdyA8IHRoaXMubWluaW11bUxldmVsKSByZXR1cm5cbiAgICAgICAgLy9pZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2coXCJ0aWxlUXVhZEFkZGVkXCIsIHF1YWQpXG4gICAgICAgIGxldCBjID0gTWF0aC5mbG9vcihxdWFkLmNvbCAvIDIpXG4gICAgICAgIGxldCByID0gTWF0aC5mbG9vcihxdWFkLnJvdyAvIDIpXG4gICAgICAgIGxldCB1cmxCZWxvdyA9IHRoaXMuaW5mby51cmxGb3JUaWxlKGxldmVsQmVsb3csIGMsIHIpXG4gICAgICAgIGxldCBiZWxvdyA9IG51bGxcbiAgICAgICAgaWYgKCF0aGlzLnF1YWRUcmVlcy5oYXModXJsQmVsb3cpKSB7XG4gICAgICAgICAgICBiZWxvdyA9IHRoaXMuYWRkVGlsZVF1YWROb2RlKGxldmVsQmVsb3csIGMsIHIsIHVybEJlbG93KVxuICAgICAgICAgICAgcXVhZC5saW5rKGlzRXZlbihxdWFkLnJvdyksIGlzRXZlbihxdWFkLmNvbCksIGJlbG93KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgdGhlIHRpbGUgbGF5ZXIgbGV2ZWwgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZ2l2ZW4gc2NhbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNjYWxlIC0gdGhlIHNjYWxlIGZhY3RvclxuICAgICAqKi9cbiAgICBsZXZlbEZvclNjYWxlKHNjYWxlKSB7XG4gICAgICAgIGxldCBsZXZlbCA9IE1hdGgucm91bmQoTWF0aC5sb2cyKHNjYWxlICogdGhpcy5yZXNvbHV0aW9uKSkgLy8gTWF0aC5mbG9vcihNYXRoLmxvZzIoZXZlbnQuc2NhbGUpKSsxXG4gICAgICAgIGxldCBuZXdMZXZlbCA9IHRoaXMuaW5mby5iYXNlTGV2ZWwgKyBNYXRoLm1heChsZXZlbCwgMClcbiAgICAgICAgcmV0dXJuIE1hdGgubWluKG5ld0xldmVsLCB0aGlzLmluZm8ubWF4TG9hZGFibGVMZXZlbClcbiAgICB9XG5cbiAgICAvKiogUmV0dXJucyB0aGUgdGlsZSBsYXllciBsZXZlbCB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBnaXZlbiBzY2FsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgLSB0aGUgc2NhbGUgZmFjdG9yXG4gICAgICoqL1xuICAgIGxldmVsQW5kQWxwaGFGb3JTY2FsZShzY2FsZSkge1xuICAgICAgICBsZXQgdmFsdWUgPSBNYXRoLmxvZzIoc2NhbGUgKiB0aGlzLnJlc29sdXRpb24pXG4gICAgICAgIGxldCBsZXZlbCA9IE1hdGgucm91bmQodmFsdWUpXG4gICAgICAgIGxldCBuZXdMZXZlbCA9IHRoaXMuaW5mby5iYXNlTGV2ZWwgKyBNYXRoLm1heChsZXZlbCwgMClcblxuICAgICAgICByZXR1cm4geyBsZXZlbDogTWF0aC5taW4obmV3TGV2ZWwsIHRoaXMuaW5mby5tYXhMb2FkYWJsZUxldmVsKSwgYWxwaGE6IHZhbHVlIC0gbGV2ZWwgfVxuICAgIH1cblxuICAgIC8qKiBBZGRzIGEgdGlsZSBsYXllciB0byB0aGUgRGVlcFpvb21JbWFnZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gdGhlIGFjY2VzcyBrZXlcbiAgICAgKiBAcGFyYW0ge1RpbGVzfSB0aWxlcyAtIHRoZSB0aWxlIGxheWVyIG9iamVjdFxuICAgICAqKi9cbiAgICBhZGRUaWxlcyhrZXksIHRpbGVzKSB7XG4gICAgICAgIGlmIChrZXkgaW4gdGhpcy50aWxlTGF5ZXJzKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RpbGVzIGFscmVhZHkgYXZhaWxhYmwnLCBrZXkpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aWxlQ29udGFpbmVyLmFkZENoaWxkKHRpbGVzKVxuICAgICAgICB0aGlzLnRpbGVMYXllcnNba2V5XSA9IHRpbGVzXG4gICAgfVxuXG4gICAgZGVzdHJveVRpbGVzKGtleSkge1xuICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLnRpbGVMYXllcnNba2V5XVxuICAgICAgICB0aGlzLnRpbGVDb250YWluZXIucmVtb3ZlQ2hpbGQodGlsZXMpXG4gICAgICAgIHRpbGVzLmRlc3Ryb3koKVxuICAgICAgICBkZWxldGUgdGhpcy50aWxlTGF5ZXJzW2tleV1cbiAgICB9XG5cbiAgICAvKiogR2V0dGVyIGZvciBQSVhJLkNvbnRhaW5lciBmb3JlZ3JvdW5kIGxheWVyLlxuICAgICAqIEFkZHMgYSBQSVhJLkNvbnRhaW5lciBpZiBuZWNlc3NhcnkuXG4gICAgICoqL1xuICAgIGdldCBmb3JlZ3JvdW5kKCkge1xuICAgICAgICBpZiAodGhpcy5fZm9yZWdyb3VuZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9mb3JlZ3JvdW5kID0gbmV3IFBJWEkuQ29udGFpbmVyKClcbiAgICAgICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5fZm9yZWdyb3VuZClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZm9yZWdyb3VuZFxuICAgIH1cblxuICAgIC8qKiBHZXR0ZXIgZm9yIHRoZSBEZWVwWm9vbUluZm8gYmFzZSBsZXZlbCBzaXplLlxuICAgICAqKi9cbiAgICBnZXQgYmFzZVNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmluZm8uZ2V0RGltZW5zaW9ucyh0aGlzLmluZm8uYmFzZUxldmVsKVxuICAgIH1cblxuICAgIC8qKiBHZXR0ZXIgZm9yIHRoZSBjdXJyZW50IHNjYWxlZCBzaXplIGluIHBpeGVscy5cbiAgICAgKiovXG4gICAgZ2V0IHBpeGVsU2l6ZSgpIHtcbiAgICAgICAgbGV0IFt3LCBoXSA9IHRoaXMuYmFzZVNpemVcbiAgICAgICAgcmV0dXJuIFt3ICogdGhpcy5zY2FsZS54LCBoICogdGhpcy5zY2FsZS55XVxuICAgIH1cblxuICAgIC8qKiBHZXR0ZXIgZm9yIHRoZSBtYXggc2NhbGUgZmFjdG9yLlxuICAgICAqKi9cbiAgICBnZXQgbWF4U2NhbGUoKSB7XG4gICAgICAgIGxldCBkZWx0YSA9IHRoaXMuaW5mby5tYXhMZXZlbCAtIHRoaXMuaW5mby5iYXNlTGV2ZWxcbiAgICAgICAgcmV0dXJuIE1hdGgucG93KDIsIGRlbHRhKSAvIHRoaXMucmVzb2x1dGlvbiAqIDJcbiAgICB9XG5cbiAgICAvKiogR2V0dGVyIGZvciB0aGUgY3VycmVudCB3aWR0aC5cbiAgICAgKiovXG4gICAgZ2V0IHdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5waXhlbFNpemVbMF1cbiAgICB9XG5cbiAgICAvKiogR2V0dGVyIGZvciB0aGUgY3VycmVudCBoZWlnaHQuXG4gICAgICoqL1xuICAgIGdldCBoZWlnaHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpeGVsU2l6ZVsxXVxuICAgIH1cblxuXG4gICAgLyogT3ZlcnJpZGVzIFBJWEkuQ29udGFpbmVyLmhpdEFyZWEoKVxuICAgICAqIEFsbG93cyB0byBvcHRpbWl6ZSB0aGUgaGl0IHRlc3RpbmcuIENvbnRhaW5lciB3aXRoIGhpdCBhcmVhcyBhcmUgZGlyZWN0bHlcbiAgICAgKiBoaXQgdGVzdGVkIHdpdGhvdXQgY29uc2lkZXJhdGlvbiBvZiBjaGlsZHJlbi5cbiAgICAgKi9cbiAgICBnZXQgaGl0QXJlYSgpIHtcbiAgICAgICAgLy8gRGVmaW5pbmcgdGhlIGhpdEFyZWEgcmVzdWx0ZWQgaGl0dGluZyB0aGUgc2NhdHRlciBpbiBtYXNrZWQgYXJlYVxuICAgICAgICAvLyB3aGVuIGEgbWFzayB3YXMgdXNlZCAoQFTDvHNjaFtzdWJtYXBzXSkuIFJlbW92aW5nIHRoZSBoaXRBcmVhKCkgYWx0b2dldGhlclxuICAgICAgICAvLyBicm9rZSB0aGUgaW50ZXJhY3Rpb24gaW4gb3RoZXIgcHJvamVjdHMgKEBnb29nbGVhcnQpLlxuICAgICAgICAvLyBGaXg6IFdoZW4gbWFza2VkLCB0aGUgaGl0QXJlYSBpcyBpZ25vcmVkIGJ5IHJldHVybmluZyBudWxsLlxuICAgICAgICAvLyBUT0RPOiB0ZXN0IGlmIGNoaWxkcyBhcmUgaGl0dGVzdGVkLCB3aXRob3V0IHNldHRpbmcgaW50ZXJhY3RpdmVDaGlsZHJlbi5cbiAgICAgICAgLy8gT3BlbCwgMDMtMDUtMjAxOFxuICAgICAgICBpZiAodGhpcy5tYXNrKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyogT3ZlcnJpZGVzIFBJWEkuQ29udGFpbmVyLmNvbnRhaW5zKClcbiAgICAgKiBBbGxvd3MgdG8gb3B0aW1pemUgdGhlIGhpdCB0ZXN0aW5nLlxuICAgICAqL1xuICAgIGNvbnRhaW5zKHgsIHkpIHtcbiAgICAgICAgbGV0IFt3LCBoXSA9IHRoaXMuYmFzZVNpemVcbiAgICAgICAgcmV0dXJuIHggPj0gMCAmJiB4IDw9IHcgJiYgeSA+PSAwICYmIHkgPD0gaFxuICAgIH1cblxuICAgIC8qKiBPdmVycmlkZXMgUElYSS5Db250YWluZXIuX2NhbGN1bGF0ZUJvdW5kcygpXG4gICAgICogT25seSBjb25zaWRlcnMgdGhlIGJhc2Ugc2l6ZSBhbmQgcmVkdWNlcyB0aGUgY2FsY3VsYXRpb24gdG8gYSBzaW5nbGVcbiAgICAgKiByZWN0LlxuICAgICAqL1xuICAgIF9jYWxjdWxhdGVCb3VuZHMoKSB7XG4gICAgICAgIGxldCBbdywgaF0gPSB0aGlzLmJhc2VTaXplXG4gICAgICAgIHRoaXMuX2JvdW5kcy5hZGRGcmFtZSh0aGlzLnRyYW5zZm9ybSwgMCwgMCwgdywgaClcbiAgICB9XG5cbiAgICAvKiogT3ZlcnJpZGVzIFBJWEkuQ29udGFpbmVyLmNhbGN1bGF0ZUJvdW5kcygpXG4gICAgICogU2tpcHMgdGhlIGNoaWxkcmVuIGFuZCBvbmx5IGNvbnNpZGVycyB0aGUgZGVlcCB6b29tIGJhc2Ugc2l6ZS4gQ2FsbHNcbiAgICAgKiB0aGUgYWxzbyBvdmVyd3JpdHRlbiBfY2FsY3VsYXRlQm91bmRzIG1ldGhvZC5cbiAgICAgKi9cbiAgICBjYWxjdWxhdGVCb3VuZHMoKSB7XG4gICAgICAgIHRoaXMuX2JvdW5kcy5jbGVhcigpXG4gICAgICAgIHRoaXMuX2NhbGN1bGF0ZUJvdW5kcygpXG4gICAgICAgIHRoaXMuX2xhc3RCb3VuZHNJRCA9IHRoaXMuX2JvdW5kc0lEXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgYSBzaW5nbGUgc3ByaXRlIHRoYXQgY2FuIGJlIHVzZWQgYSB0aHVtYm5haWwgcmVwcmVzZW50YXRpb24gb2ZcbiAgICAgKiBsYXJnZSBpbWFnZXMuXG4gICAgICogQHJldHVybiB7U3ByaXRlfSBzcHJpdGUgLSBBIHNwcml0ZSB3aXRoIGEgc2luZ2xlIHRpbGUgdGV4dHVyZVxuICAgICAqL1xuICAgIHRodW1ibmFpbCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQSVhJLlNwcml0ZS5mcm9tSW1hZ2UodGhpcy5pbmZvLmJhc2VVUkwpXG4gICAgfVxuXG4gICAgLyoqIFJldHVybnMgYSBsaXN0IG9mIGFsbCB0aWxlcyBvZiBhIGdpdmVuIGxldmVsLlxuICAgICAqIEBwYXJhbSB7VGlsZXN9IHRpbGVzIC0gdGhlIGdyaWQgb2YgdGlsZXNcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgLSBUaGUgem9vbSBsZXZlbCBvZiB0aGUgZ3JpZFxuICAgICAqIEByZXR1cm4ge0FycmF5W119IC0gQW4gYXJyYXkgb2YgW3VybCwgY29sLCByb3ddIGFycmF5c1xuICAgICAqKi9cbiAgICBhbGxUaWxlcyh0aWxlcywgbGV2ZWwpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdXG4gICAgICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IHRpbGVzLmNvbHM7IGNvbCsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCB0aWxlcy5yb3dzOyByb3crKykge1xuICAgICAgICAgICAgICAgIGxldCB1cmwgPSB0aGlzLmluZm8udXJsRm9yVGlsZShsZXZlbCwgY29sLCByb3cpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goW3VybCwgY29sLCByb3ddKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICB3b3JsZEJvdW5kcygpIHtcbiAgICAgICAgbGV0IHZpZXdCb3VuZHMgPSB0aGlzLmFwcC5zY2VuZS5ib3VuZHNcbiAgICAgICAgLy8gVXNpbmcgZ2V0Qm91bmRzIGV4dGVuZHMgdmlzaWJsZSBzY29wZSBhZnRlciBsb2FkaW5nIHRpbGVzIGFuZCBsZWFkc1xuICAgICAgICAvLyB0byBleGNlc3NpdmUgbG9hZGluZ1xuICAgICAgICBpZiAodGhpcy53b3JsZCAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgYm91bmRzID0gdGhpcy53b3JsZC5ib3VuZHNcbiAgICAgICAgICAgIGxldCB4ID0gTWF0aC5tYXgoLWJvdW5kcy53aWR0aCwgYm91bmRzLngpXG4gICAgICAgICAgICBsZXQgeSA9IE1hdGgubWF4KC1ib3VuZHMuaGVpZ2h0LCBib3VuZHMueSlcbiAgICAgICAgICAgIGxldCB3aWR0aCA9IE1hdGgubWluKHZpZXdCb3VuZHMud2lkdGgsIGJvdW5kcy53aWR0aClcbiAgICAgICAgICAgIGxldCBoZWlnaHQgPSBNYXRoLm1pbih2aWV3Qm91bmRzLmhlaWdodCwgYm91bmRzLmhlaWdodClcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJ3b3JsZEJvdW5kcyBuZXdcIiwgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0pXG4gICAgICAgICAgICByZXR1cm4geyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH1cbiAgICAgICAgfVxuICAgICAgICAvL2NvbnNvbGUubG9nKFwid29ybGRCb3VuZHMgb2xkXCIsIHZpZXdCb3VuZHMpXG4gICAgICAgIHJldHVybiB2aWV3Qm91bmRzXG4gICAgfVxuXG4gICAgLyoqIExvYWRzIGFsbCB0aWxlcyB0aGF0IGFyZSBuZWVkZWQgdG8gZmlsbCB0aGUgYXBwIGJvdW5kcy5cbiAgICAgKiBAcGFyYW0ge1RpbGVzfSB0aWxlcyAtIHRoZSBncmlkIG9mIHRpbGVzXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIC0gVGhlIHpvb20gbGV2ZWwgb2YgdGhlIGdyaWRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGRlYnVnXG4gICAgICogQHJldHVybiB7QXJyYXlbXX0gLSBBbiBhcnJheSBvZiBbdXJsLCBjb2wsIHJvd10gYXJyYXlzXG4gICAgICovXG4gICAgbmVlZGVkVGlsZXModGlsZXMsIGxldmVsLCBkZWJ1ZyA9IGZhbHNlKSB7XG4gICAgICAgIGxldCBuZWVkZWQgPSBbXVxuICAgICAgICBsZXQgdHNpemUgPSB0aWxlcy50aWxlU2l6ZVxuICAgICAgICBsZXQgd29ybGRCb3VuZHMgPSB0aGlzLndvcmxkQm91bmRzKClcbiAgICAgICAgbGV0IG1heFdpZHRoID0gd29ybGRCb3VuZHMud2lkdGhcbiAgICAgICAgbGV0IG1heEhlaWdodCA9IHdvcmxkQm91bmRzLmhlaWdodFxuXG4gICAgICAgIGxldCBwb2ludEluV2luZG93ID0gbmV3IFBJWEkuUG9pbnQoKVxuICAgICAgICBsZXQgd29ybGRUb3BMZWZ0ID0gbmV3IFBJWEkuUG9pbnQod29ybGRCb3VuZHMueCwgd29ybGRCb3VuZHMueSlcbiAgICAgICAgbGV0IHdvcmxkQm90dG9tUmlnaHQgPSBuZXcgUElYSS5Qb2ludCh3b3JsZEJvdW5kcy54ICsgbWF4V2lkdGgsIHdvcmxkQm91bmRzLnkgKyBtYXhIZWlnaHQpXG4gICAgICAgIGxldCB3b3JsZENlbnRlciA9IG5ldyBQSVhJLlBvaW50KHdvcmxkQm91bmRzLnggKyBtYXhXaWR0aCAvIDIsIHdvcmxkQm91bmRzLnkgKyBtYXhIZWlnaHQgLyAyKVxuICAgICAgICBsZXQgdGlsZXNDZW50ZXIgPSB0aWxlcy50b0xvY2FsKHdvcmxkQ2VudGVyKVxuXG4gICAgICAgIGxldCB0b3BMZWZ0ID0gdGlsZXMudG9Mb2NhbCh3b3JsZFRvcExlZnQpXG4gICAgICAgIGxldCBib3R0b21SaWdodCA9IHRpbGVzLnRvTG9jYWwod29ybGRCb3R0b21SaWdodClcbiAgICAgICAgdGlsZXMuX2NlbnRlclBvaW50ID0gdGlsZXNDZW50ZXJcbiAgICAgICAgbGV0IGJvdW5kcyA9IG5ldyBQSVhJLlJlY3RhbmdsZShcbiAgICAgICAgICAgIHRvcExlZnQueCxcbiAgICAgICAgICAgIHRvcExlZnQueSxcbiAgICAgICAgICAgIGJvdHRvbVJpZ2h0LnggLSB0b3BMZWZ0LngsXG4gICAgICAgICAgICBib3R0b21SaWdodC55IC0gdG9wTGVmdC55KVxuXG4gICAgICAgIHRpbGVzLl9ib3VuZHNSZWN0ID0gYm91bmRzXG5cbiAgICAgICAgLyogVU86IHdlIG5lZWQgYSB0b0xvY2FsIGNhbGwgaGVyZSBzaW5jZSB0aGUgdHJhbnNmb3JtIG1heSBuZWVkIGFuIHVwZGF0ZVxuICAgICAgICB3aGljaCBpcyBndWFyYW50ZWVkIGJ5IHRoZSB0b0xvY2FsIG1ldGhvZC4gKi9cbiAgICAgICAgbGV0IGNlbnRlckNvbCA9IE1hdGguZmxvb3IodGlsZXNDZW50ZXIueCAvIHRzaXplKVxuICAgICAgICBsZXQgY2VudGVyUm93ID0gTWF0aC5mbG9vcih0aWxlc0NlbnRlci55IC8gdHNpemUpXG5cbiAgICAgICAgLy8gRXhwYW5kIGJlY2F1c2Ugd2Ugd2FudCB0byB0ZXN0IGZvciBpbmNsdWRlZCBjZW50ZXJzXG4gICAgICAgIGJvdW5kcy54IC09IHRzaXplIC8gMlxuICAgICAgICBib3VuZHMueSAtPSB0c2l6ZSAvIDJcbiAgICAgICAgYm91bmRzLndpZHRoICs9IHRzaXplXG4gICAgICAgIGJvdW5kcy5oZWlnaHQgKz0gdHNpemVcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IG1heFRpbGVzV2lkdGggPSBNYXRoLmNlaWwobWF4V2lkdGggLyB0c2l6ZSlcbiAgICAgICAgICAgIGxldCBtYXhUaWxlc0hlaWdodCA9IE1hdGguY2VpbChtYXhIZWlnaHQgLyB0c2l6ZSlcblxuICAgICAgICAgICAgbWF4VGlsZXNXaWR0aCArPSAyXG4gICAgICAgICAgICBtYXhUaWxlc0hlaWdodCArPSAyXG5cbiAgICAgICAgICAgIGxldCBzdGFydENvbCA9IE1hdGgubWF4KDAsIGNlbnRlckNvbCAtIG1heFRpbGVzV2lkdGgpXG4gICAgICAgICAgICBsZXQgZW5kQ29sID0gTWF0aC5taW4odGlsZXMuY29scywgY2VudGVyQ29sICsgbWF4VGlsZXNXaWR0aClcblxuICAgICAgICAgICAgbGV0IHN0YXJ0Um93ID0gTWF0aC5tYXgoMCwgY2VudGVyUm93IC0gbWF4VGlsZXNIZWlnaHQpXG4gICAgICAgICAgICBsZXQgZW5kUm93ID0gTWF0aC5taW4odGlsZXMucm93cywgY2VudGVyUm93ICsgbWF4VGlsZXNIZWlnaHQpXG5cbiAgICAgICAgICAgIGZvciAobGV0IGNvbCA9IHN0YXJ0Q29sOyBjb2wgPCBlbmRDb2w7IGNvbCsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IGN4ID0gKGNvbCArIDAuNSkgKiB0c2l6ZVxuICAgICAgICAgICAgICAgIGZvciAobGV0IHJvdyA9IHN0YXJ0Um93OyByb3cgPCBlbmRSb3c7IHJvdysrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjeSA9IChyb3cgKyAwLjUpICogdHNpemVcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRpbGVDZW50ZXIgPSBuZXcgUElYSS5Qb2ludChjeCwgY3kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChib3VuZHMuY29udGFpbnModGlsZUNlbnRlci54LCB0aWxlQ2VudGVyLnkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdXJsID0gdGhpcy5pbmZvLnVybEZvclRpbGUobGV2ZWwsIGNvbCwgcm93KVxuICAgICAgICAgICAgICAgICAgICAgICAgbmVlZGVkLnB1c2goW3VybCwgY29sLCByb3ddKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm1lc3NhZ2UpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY2VudGVyQ29sLCBjZW50ZXJSb3csIG5lZWRlZCB9XG4gICAgfVxuXG5cblxuXG4gICAgLyoqIFJldHVybnMgYWxsIGNoYW5nZWQgdGlsZXMgZm9yIGEgZ2l2ZW4gbGV2ZWwuXG4gICAgICogQHBhcmFtIHtUaWxlc30gdGlsZXMgLSB0aGUgZ3JpZCBvZiB0aWxlc1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSB6b29tIGxldmVsIG9mIHRoZSBncmlkXG4gICAgICogQHJldHVybiB7b2JqZWN0fSAtIEFuIG9iamVjdCB3aXRoIHRoZSBrZXlzIGFkZGVkIGFuZCByZW1vdmVkIHdoaWNoIHZhbHVlcyBhcmUgW3VybCwgY29sLCByb3ddIGFycmF5c1xuICAgICAqL1xuICAgIGNoYW5nZWRUaWxlcyh0aWxlcywgbGV2ZWwpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVidWcpIGNvbnNvbGUudGltZSgnY2hhbmdlZFRpbGVzJylcbiAgICAgICAgbGV0IGNoYW5nZWQgPSB7IGFkZGVkOiBbXSwgcmVtb3ZlZDogW10gfVxuICAgICAgICBsZXQgbmV3TmVlZGVkID0gbmV3IE1hcCgpXG4gICAgICAgIGxldCB7IGNlbnRlckNvbCwgY2VudGVyUm93LCBuZWVkZWQgfSA9IHRoaXMubmVlZGVkVGlsZXModGlsZXMsIGxldmVsKVxuICAgICAgICBuZWVkZWQuZm9yRWFjaChkID0+IHtcbiAgICAgICAgICAgIGxldCBbdXJsLCBjb2wsIHJvd10gPSBkXG4gICAgICAgICAgICBuZXdOZWVkZWQuc2V0KHVybCwgW2NvbCwgcm93XSlcbiAgICAgICAgICAgIGlmICghdGlsZXMucmVxdWVzdGVkLmhhcyh1cmwpKSB7XG4gICAgICAgICAgICAgICAgY2hhbmdlZC5hZGRlZC5wdXNoKGQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGZvciAobGV0IHVybCBvZiB0aWxlcy5uZWVkZWQua2V5cygpKSB7XG4gICAgICAgICAgICBpZiAoIW5ld05lZWRlZC5oYXModXJsKSkge1xuICAgICAgICAgICAgICAgIGxldCBbY29sLCByb3ddID0gdGlsZXMubmVlZGVkLmdldCh1cmwpXG4gICAgICAgICAgICAgICAgY2hhbmdlZC5yZW1vdmVkLnB1c2goW3VybCwgY29sLCByb3ddKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRpbGVzLm5lZWRlZCA9IG5ld05lZWRlZFxuICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS5sb2cobmV3TmVlZGVkKVxuICAgICAgICBpZiAodGhpcy5kZWJ1ZykgY29uc29sZS50aW1lRW5kKCdjaGFuZ2VkVGlsZXMnKVxuICAgICAgICByZXR1cm4geyBjZW50ZXJDb2wsIGNlbnRlclJvdywgY2hhbmdlZCB9XG4gICAgfVxuXG4gICAgLyoqIFBvcHVsYXRlcyBhbGwgdGlsZXMgZm9yIGEgZ2l2ZW4gbGV2ZWwuXG4gICAgICogQHBhcmFtIHtUaWxlc30gdGlsZXMgLSB0aGUgZ3JpZCBvZiB0aWxlc1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSB6b29tIGxldmVsIG9mIHRoZSBncmlkXG4gICAgICovXG4gICAgcG9wdWxhdGVBbGxUaWxlcyh0aWxlcywgbGV2ZWwpIHtcbiAgICAgICAgbGV0IGFsbCA9IHRoaXMuYWxsVGlsZXModGlsZXMsIGxldmVsKVxuICAgICAgICBmb3IgKGxldCBbdXJsLCBjb2wsIHJvd10gb2YgYWxsKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFRpbGVRdWFkTm9kZShsZXZlbCwgY29sLCByb3csIHVybClcbiAgICAgICAgfVxuICAgICAgICB0aWxlcy5sb2FkVGlsZXMoYWxsLCBmYWxzZSwgMCwgMClcbiAgICB9XG5cbiAgICAvKiogTG9hZHMgYWxsIHRpbGVzIHRoYXQgYXJlIG5lZWRlZCB0byBmaWxsIHRoZSBicm93c2VyIHdpbmRvdy5cbiAgICAgKiBJZiB0aGUgb3B0aW9uYWwgYWJvdXQgcGFyYW1ldGVyIGlzIHByb3ZpZGVkIChhcyBhIHBvaW50IHdpdGggY29sIGFzIHgsXG4gICAgICogYW5kIHJvdyBhcyB5IGF0dHIpIHRoZSB0aWxlcyBhcmUgc29ydGVkIGJ5IHRoZSBkaXN0YW5jZSB0byB0aGlzIHBvaW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtUaWxlc30gdGlsZXMgLSB0aGUgZ3JpZCBvZiB0aWxlc1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSB6b29tIGxldmVsIG9mIHRoZSBncmlkXG4gICAgICogT3B0aW9uYWwgcGFyYW1ldGVyOlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gb25seW9uZSAtIGlmIHRydWUgb25seSBvbmUgdGlsZSBpcyBsb2FkZWRcbiAgICAgKiBAcGFyYW0ge1BJWEkuUG9pbnR9IGFib3V0IC0gcG9pbnQgb2YgaW50ZXJhY3Rpb25cbiAgICAgKi9cbiAgICBwb3B1bGF0ZVRpbGVzKHRpbGVzLCBsZXZlbCwgeyBvbmx5b25lID0gZmFsc2UsIGFib3V0ID0gbnVsbCB9ID0ge30pIHtcbiAgICAgICAgaWYgKHRpbGVzLmlzQ29tcGxldGUoKSlcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICBsZXQgcmVmZXJlbmNlQ29sID0gLTFcbiAgICAgICAgbGV0IHJlZmVyZW5jZVJvdyA9IC0xXG4gICAgICAgIGxldCB7IGNlbnRlckNvbCwgY2VudGVyUm93LCBjaGFuZ2VkIH0gPSB0aGlzLmNoYW5nZWRUaWxlcyh0aWxlcywgbGV2ZWwpXG4gICAgICAgIGlmIChhYm91dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBXZSB3YW50IHRvIGxvYWQgdGlsZXMgaW4gdGhlIGZvY3VzIG9mIHRoZSB1c2VyIGZpcnN0LCB0aGVyZWZvcmVcbiAgICAgICAgICAgIC8vIHdlIHNvcnQgYWNjb3JkaW5nIHRvIHRoZSBkaXN0YW5jZSBvZiB0aGUgZm9jdXMgb2YgaW50ZXJhY3Rpb25cbiAgICAgICAgICAgIGxldCByZWZQb2ludCA9IHRoaXMudG9Mb2NhbChhYm91dClcbiAgICAgICAgICAgIGxldCBzY2FsZWRUaWxlU2l6ZSA9IHRpbGVzLnRpbGVTaXplICogdGlsZXMudGlsZVNjYWxlXG4gICAgICAgICAgICByZWZlcmVuY2VDb2wgPSBNYXRoLmZsb29yKHJlZlBvaW50LnggLyBzY2FsZWRUaWxlU2l6ZSlcbiAgICAgICAgICAgIHJlZmVyZW5jZVJvdyA9IE1hdGguZmxvb3IocmVmUG9pbnQueSAvIHNjYWxlZFRpbGVTaXplKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVmZXJlbmNlQ29sID0gY2VudGVyQ29sXG4gICAgICAgICAgICByZWZlcmVuY2VSb3cgPSBjZW50ZXJSb3dcbiAgICAgICAgfVxuICAgICAgICByZWZlcmVuY2VDb2wgPSBjZW50ZXJDb2xcbiAgICAgICAgcmVmZXJlbmNlUm93ID0gY2VudGVyUm93XG5cbiAgICAgICAgbGV0IHJlbW92ZWQgPSBjaGFuZ2VkLnJlbW92ZWRcbiAgICAgICAgZm9yIChsZXQgW3VybCwgY29sLCByb3ddIG9mIHJlbW92ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlVGlsZVF1YWROb2RlKGxldmVsLCBjb2wsIHJvdywgdXJsKVxuICAgICAgICB9XG4gICAgICAgIGxldCBhZGRlZCA9IGNoYW5nZWQuYWRkZWRcbiAgICAgICAgaWYgKGFkZGVkLmxlbmd0aCA9PSAwKSByZXR1cm5cbiAgICAgICAgZm9yIChsZXQgW3VybCwgY29sLCByb3ddIG9mIGFkZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFRpbGVRdWFkTm9kZShsZXZlbCwgY29sLCByb3csIHVybClcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVmID0gbmV3IFBJWEkuUG9pbnQocmVmZXJlbmNlQ29sLCByZWZlcmVuY2VSb3cpXG4gICAgICAgIC8vIE5vdGU6IFRoZSBhcnJheSBtdXN0IGJlIHNvcnRlZCBpbiBhIHdheSB0aGF0IHRoZSBuZWFyZXN0IHRpbGVzXG4gICAgICAgIC8vIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheSBzaW5jZSB0aGUgbG9hZCBxdWV1ZSB1c2VzIEFycmF5LnB1c2hcbiAgICAgICAgLy8gQXJyYXkucG9wXG4gICAgICAgIGFkZGVkLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGxldCBhYSA9IG5ldyBQSVhJLlBvaW50KGFbMV0sIGFbMl0pXG4gICAgICAgICAgICBsZXQgYmIgPSBuZXcgUElYSS5Qb2ludChiWzFdLCBiWzJdKVxuICAgICAgICAgICAgbGV0IGRhID0gUG9pbnRzLmRpc3RhbmNlKGFhLCByZWYpXG4gICAgICAgICAgICBsZXQgZGIgPSBQb2ludHMuZGlzdGFuY2UoYmIsIHJlZilcbiAgICAgICAgICAgIHJldHVybiBkYiAtIGRhXG4gICAgICAgIH0pXG4gICAgICAgIHRpbGVzLmxvYWRUaWxlcyhhZGRlZCwgb25seW9uZSwgcmVmZXJlbmNlQ29sLCByZWZlcmVuY2VSb3cpXG4gICAgfVxuXG4gICAgLyoqIFByaXZhdGUgbWV0aG9kOiBjcmVhdGVzIGFsbCB0aWxlcyBmb3IgYSBnaXZlbiBsZXZlbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgLSBUaGUgem9vbSBsZXZlbCBvZiB0aGUgZ3JpZFxuICAgICAqIEByZXR1cm4ge1RpbGVzfSAtIHRpbGVzXG4gICAgICovXG4gICAgX2NyZWF0ZVRpbGVzKGtleSwgbGV2ZWwpIHtcbiAgICAgICAgbGV0IFtjb2xzLCByb3dzLCB3LCBoXSA9IHRoaXMuaW5mby5kaW1lbnNpb25zKGxldmVsKVxuICAgICAgICBsZXQgaW5jcmVhc2VkTGV2ZWxzID0gbGV2ZWwgLSB0aGlzLmluZm8uYmFzZUxldmVsXG4gICAgICAgIGxldCBpbnZTY2FsZSA9IE1hdGgucG93KDAuNSwgaW5jcmVhc2VkTGV2ZWxzKVxuICAgICAgICBsZXQgdGlsZXMgPSBuZXcgVGlsZXMoXG4gICAgICAgICAgICBsZXZlbCxcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBpbnZTY2FsZSxcbiAgICAgICAgICAgIGNvbHMsXG4gICAgICAgICAgICByb3dzLFxuICAgICAgICAgICAgdyxcbiAgICAgICAgICAgIGgsXG4gICAgICAgICAgICB0aGlzLmluZm8udGlsZVNpemUsXG4gICAgICAgICAgICB0aGlzLmluZm8ub3ZlcmxhcFxuICAgICAgICApXG4gICAgICAgIHRoaXMuYWRkVGlsZXMoa2V5LCB0aWxlcylcbiAgICAgICAgaWYgKHRoaXMuaW5mby5jbGlwKSB7XG4gICAgICAgICAgICBsZXQgcmVzdCA9IHRoaXMuaW5mby5yZXN0c1tsZXZlbF1cbiAgICAgICAgICAgIGlmIChyZXN0KSB7XG4gICAgICAgICAgICAgICAgbGV0IHggPSByZXN0LnJlc3RDb2wgKiB0aGlzLmluZm8udGlsZVNpemUgKiBpbnZTY2FsZVxuICAgICAgICAgICAgICAgIGxldCB5ID0gcmVzdC5yZXN0Um93ICogdGhpcy5pbmZvLnRpbGVTaXplICogaW52U2NhbGVcbiAgICAgICAgICAgICAgICB0aWxlcy54ID0gLXhcbiAgICAgICAgICAgICAgICB0aWxlcy55ID0gLXlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGlsZXNcbiAgICB9XG5cbiAgICAvKiogRW5zdXJlcyB0aGF0IGFsbCBuZWVkZWQgdGlsZXMgb2YgYSBnaXZlbiBsZXZlbCBhcmUgbG9hZGVkLiBDcmVhdGVzXG4gICAgICogYSBuZXcgVGlsZXMgbGF5ZXIgaWYgbmVjZXNzYXJ5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIC0gVGhlIHpvb20gbGV2ZWwgb2YgdGhlIGdyaWRcbiAgICAgKiBAcmV0dXJuIHtUaWxlc30gdGlsZXNcbiAgICAgKi9cbiAgICBlbnN1cmVUaWxlcyhsZXZlbCwgYWJvdXQpIHtcbiAgICAgICAgbGV0IGtleSA9IGxldmVsLnRvU3RyaW5nKClcbiAgICAgICAgaWYgKGtleSBpbiB0aGlzLnRpbGVMYXllcnMpIHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IHRoaXMudGlsZUxheWVyc1trZXldXG4gICAgICAgICAgICB0aGlzLnBvcHVsYXRlVGlsZXModGlsZXMsIGxldmVsLCB7IGFib3V0OiBhYm91dCB9KVxuICAgICAgICAgICAgcmV0dXJuIHRpbGVzXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRpbGVzID0gdGhpcy5fY3JlYXRlVGlsZXMoa2V5LCBsZXZlbClcbiAgICAgICAgdGhpcy5wb3B1bGF0ZVRpbGVzKHRpbGVzLCBsZXZlbCwgeyBhYm91dDogYWJvdXQgfSlcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcImVuc3VyZVRpbGVzXCIsIGxldmVsKVxuICAgICAgICByZXR1cm4gdGlsZXNcbiAgICB9XG5cbiAgICB1bnRpbnRUaWxlcyhsZXZlbCkge1xuICAgICAgICBsZXQga2V5ID0gbGV2ZWwudG9TdHJpbmcoKVxuICAgICAgICBpZiAoa2V5IGluIHRoaXMudGlsZUxheWVycykge1xuICAgICAgICAgICAgbGV0IHRpbGVzID0gdGhpcy50aWxlTGF5ZXJzW2tleV1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBFbnN1cmVzIHRoYXQgYWxsIHRpbGVzIG9mIGEgZ2l2ZW4gbGV2ZWwgYXJlIGxvYWRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgLSBUaGUgem9vbSBsZXZlbCBvZiB0aGUgZ3JpZFxuICAgICAqL1xuICAgIGVuc3VyZUFsbFRpbGVzKGxldmVsKSB7XG4gICAgICAgIGxldCBrZXkgPSBsZXZlbC50b1N0cmluZygpXG4gICAgICAgIGlmIChrZXkgaW4gdGhpcy50aWxlTGF5ZXJzKSB7XG4gICAgICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLnRpbGVMYXllcnNba2V5XVxuICAgICAgICAgICAgdGhpcy5wb3B1bGF0ZUFsbFRpbGVzKHRpbGVzLCBsZXZlbClcbiAgICAgICAgICAgIHRpbGVzLmtlZXAgPSB0cnVlXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLl9jcmVhdGVUaWxlcyhrZXksIGxldmVsKVxuICAgICAgICB0aGlzLnBvcHVsYXRlQWxsVGlsZXModGlsZXMsIGxldmVsKVxuICAgICAgICB0aWxlcy5rZWVwID0gdHJ1ZVxuICAgICAgICByZXR1cm4gdGlsZXNcbiAgICB9XG5cbiAgICBoaWRlVGlsZXNBYm92ZUxldmVsKGxldmVsKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMudGlsZUxheWVycykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgbGV0IHRpbGVzID0gdGhpcy50aWxlTGF5ZXJzW2tleV1cbiAgICAgICAgICAgIGlmICh0aWxlcy5sZXZlbCA+IGxldmVsKSB7XG4gICAgICAgICAgICAgICAgdGlsZXMudmlzaWJsZSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqIERlc3Ryb3lzIGFsbCB0aWxlcyBhYm92ZSBhIGdpdmVuIGxldmVsIHRvIGVuc3VyZSB0aGF0IHRoZSBtZW1vcnkgY2FuXG4gICAgICogYmUgcmV1c2VkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSB6b29tIGxldmVsIG9mIHRoZSBncmlkXG4gICAgICovXG4gICAgZGVzdHJveVRpbGVzQWJvdmVMZXZlbChsZXZlbCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnRpbGVMYXllcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IHRoaXMudGlsZUxheWVyc1trZXldXG4gICAgICAgICAgICBpZiAodGlsZXMubGV2ZWwgPiBsZXZlbCAmJiAhdGlsZXMua2VlcCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHVybCBvZiB0aWxlcy5hdmFpbGFibGUua2V5cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBxdWFkID0gdGhpcy5xdWFkVHJlZXMuZ2V0KHVybClcbiAgICAgICAgICAgICAgICAgICAgaWYgKHF1YWQpIHRoaXMucmVtb3ZlVGlsZVF1YWROb2RlKHF1YWQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveVRpbGVzKGtleSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBkZXN0cm95QWxsVGlsZXMoKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMudGlsZUxheWVycykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95VGlsZXMoa2V5KVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRpbnQgdGlsZXMgaW4gYWxsIGxheWVycyB0aGF0IGFyZSBubyBsb25nZXIgbmVlZGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgRGVlcFpvb21JbWFnZVxuICAgICAqL1xuICAgIHRpbnRPYnNvbGV0ZVRpbGVzKCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnRpbGVMYXllcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IHRoaXMudGlsZUxheWVyc1trZXldXG4gICAgICAgICAgICB0aWxlcy51bnRpbnRUaWxlcygpXG4gICAgICAgICAgICBpZiAoIXRpbGVzLmtlZXApIHtcbiAgICAgICAgICAgICAgICB0aWxlcy50aW50T2Jzb2xldGVUaWxlcygpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBEZXN0cm95IHRpbGVzIGluIGFsbCBsYXllcnMgdGhhdCBhcmUgbm8gbG9uZ2VyIG5lZWRlZFxuICAgICAqXG4gICAgICogQG1lbWJlcm9mIERlZXBab29tSW1hZ2VcbiAgICAgKi9cbiAgICBkZXN0cm95VW5uZWVkZWRUaWxlcygpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy50aWxlTGF5ZXJzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLnRpbGVMYXllcnNba2V5XVxuICAgICAgICAgICAgaWYgKCF0aWxlcy5rZWVwKSB7XG4gICAgICAgICAgICAgICAgdGlsZXMuZGVzdHJveVVubmVlZGVkVGlsZXMoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlc3Ryb3kgdGlsZXMgaW4gYWxsIGxheWVycyB0aGF0IGFyZSBubyBsb25nZXIgbmVlZGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgRGVlcFpvb21JbWFnZVxuICAgICAqL1xuICAgIGRlc3Ryb3lPYnNvbGV0ZVRpbGVzKCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnRpbGVMYXllcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IHRoaXMudGlsZUxheWVyc1trZXldXG4gICAgICAgICAgICBpZiAoIXRpbGVzLmtlZXApIHtcbiAgICAgICAgICAgICAgICB0aWxlcy5kZXN0cm95T2Jzb2xldGVUaWxlcygpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVzdHJveSB0aWxlcyBpbiBhbGwgbGF5ZXJzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZVxuICAgICAqIHZpc2libGUgcXVhZFRyZWVzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgRGVlcFpvb21JbWFnZVxuICAgICAqL1xuICAgIGRlc3Ryb3lUaWxlcygpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy50aWxlTGF5ZXJzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBsZXQgdGlsZXMgPSB0aGlzLnRpbGVMYXllcnNba2V5XVxuICAgICAgICAgICAgaWYgKCF0aWxlcy5rZWVwKSB7XG4gICAgICAgICAgICAgICAgdGlsZXMuZGVzdHJveVRpbGVzKHRoaXMucXVhZFRyZWVzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8qIFRpbnQgYWxsIHRpbGVzXG4gICAgKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgLSBUaGUgem9vbSBsZXZlbCBvZiB0aGUgZ3JpZFxuICAgICovXG4gICAgdGludFRpbGVzQmVsb3dMZXZlbChsZXZlbCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnRpbGVMYXllcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGxldCB0aWxlcyA9IHRoaXMudGlsZUxheWVyc1trZXldXG4gICAgICAgICAgICBpZiAodGlsZXMubGV2ZWwgPCBsZXZlbCkge1xuICAgICAgICAgICAgICAgIHRpbGVzLnRpbnRUaWxlcyh0aGlzLnF1YWRUcmVlcylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbnN1cmUgdGhhdCB0aGUgZ2l2ZW4gdGlsZXMgbGF5ZXIgaXMgdGhlIHRvcG1vc3Qgb25lIGFuZCB2aXNpYmxlLlxuICAgICAqIEBwYXJhbSB7Kn0gdGlsZXMgXG4gICAgICovXG4gICAgYnJpbmdUaWxlc1RvRnJvbnQodGlsZXMpIHtcbiAgICAgICAgdGhpcy50aWxlQ29udGFpbmVyLmFkZENoaWxkKHRpbGVzKVxuICAgICAgICB0aWxlcy52aXNpYmxlID0gdHJ1ZVxuICAgIH1cblxuICAgIC8qKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgYnkgYSBTY2F0dGVyIHZpZXcgdG8gaW5mb3JtXG4gICAgICogdGhlIHpvb21hYmxlIGltYWdlIHRoYXQgaXQgaGFzIGJlZW4gbW92ZWQsIHJvdGF0ZWQgb3Igc2NhbGVkLCBhbmQgc2hvdWxkXG4gICAgICogbG9hZCB0aWxlcyBhY2NvcmRpbmdseS5cbiAgICAgKiBAcGFyYW0ge1BJWEkuUG9pbnR9IHRyYW5zbGF0ZWQgLSB0aGUgbW92ZW1lbnQgb2YgdGhlIHNjYXR0ZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgLSB0aGUgem9vbSBmYWN0b3JcbiAgICAgKiBAcGFyYW0ge1BJWEkuUG9pbnR9IGFib3V0IC0gdGhlIGFuY2hvciBwb2ludCBvZiB0aGUgem9vbVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCAtIGluZm9ybXMgdGhlIGNhbGxiYWNrIHRvIHJldHVybiBhcyBmYXN0IGFzIHBvc3NpYmxlLFxuICAgICAqICBpLmUuIGFmdGVyIGxvYWRpbmcgYSBzaW5nbGUgdGlsZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVidWcgLSBsb2cgZGVidWcgaW5mb3NcbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZChldmVudCkge1xuICAgICAgICBsZXQga2V5ID0gdGhpcy5jdXJyZW50TGV2ZWwudG9TdHJpbmcoKVxuICAgICAgICBsZXQgY3VycmVudFRpbGVzID0gdGhpcy50aWxlTGF5ZXJzW2tleV1cbiAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50VGlsZXMgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5mYXN0KSB7XG4gICAgICAgICAgICB0aGlzLmZhc3RMb2FkcyArPSAxXG4gICAgICAgICAgICB0aGlzLnBvcHVsYXRlVGlsZXMoY3VycmVudFRpbGVzLCB0aGlzLmN1cnJlbnRMZXZlbCwge1xuICAgICAgICAgICAgICAgIG9ubHlvbmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFib3V0OiBldmVudC5hYm91dFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGlmICh0aGlzLmZhc3RMb2FkcyA9PSAzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mYXN0TG9hZHMgPSAwXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQuc2NhbGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5lbnN1cmVUaWxlcyh0aGlzLmN1cnJlbnRMZXZlbCwgZXZlbnQuYWJvdXQpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgbGV0IGxldmVsID0gdGhpcy5sZXZlbEZvclNjYWxlKGV2ZW50LnNjYWxlKVxuICAgICAgICBsZXQgbmV3TGV2ZWwgPSBNYXRoLm1heChsZXZlbCwgdGhpcy5taW5pbXVtTGV2ZWwpXG4gICAgICAgIGlmIChuZXdMZXZlbCAhPSB0aGlzLmN1cnJlbnRMZXZlbCkge1xuICAgICAgICAgICAgaWYgKCFjdXJyZW50VGlsZXMua2VlcCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRUaWxlcy5sb2FkZXIuY2FuY2VsKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaGlkZVRpbGVzQWJvdmVMZXZlbChuZXdMZXZlbClcbiAgICAgICAgICAgIGN1cnJlbnRUaWxlcyA9IHRoaXMuZW5zdXJlVGlsZXMobmV3TGV2ZWwsIGV2ZW50LmFib3V0KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50TGV2ZWwgPSBuZXdMZXZlbFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lbnN1cmVUaWxlcyh0aGlzLmN1cnJlbnRMZXZlbCwgZXZlbnQuYWJvdXQpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5icmluZ1RpbGVzVG9Gcm9udChjdXJyZW50VGlsZXMpXG4gICAgICAgIGlmICh0aGlzLl9mb3JlZ3JvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMuX2ZvcmVncm91bmQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICpBY3RpdmF0ZXMgdGhlIHRleHR1cmVzIG9uIHRoZSBEZWVwWm9vbUltYWdlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgRGVlcFpvb21JbWFnZVxuICAgKi9cbiAgICBhY3RpdmF0ZSgpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95VGlsZXNBYm92ZUxldmVsKHRoaXMuY3VycmVudExldmVsKVxuICAgICAgICB0aGlzLmVuc3VyZVRpbGVzKHRoaXMuY3VycmVudExldmVsLCBudWxsKVxuICAgICAgICAvL2NvbnNvbGUubG9nKFwiQWN0aXZhdGUgVGV4dHVyZXMhXCIsIHRoaXMuY3VycmVudExldmVsKVxuICAgIH1cblxuICAgIC8qKlxuICAgKkRlY3RpdmF0ZXMgdGhlIHRleHR1cmVzIG9uIHRoZSBEZWVwWm9vbUltYWdlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgRGVlcFpvb21JbWFnZVxuICAgKi9cbiAgICBkZWFjdGl2YXRlKCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lBbGxUaWxlcygpXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMudGlsZUxheWVycykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95VGlsZXMoa2V5KVxuICAgICAgICB9KVxuICAgICAgICB0aGlzLnRpbGVDb250YWluZXIuZGVzdHJveSh7IGNoaWxkcmVuOiB0cnVlIH0pXG4gICAgICAgIHByaW50VGlsZUNhY2hlSW5mb3MoKVxuICAgIH1cblxuICAgIHRocm93RmluaXNoZWQoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwidGhyb3dGaW5pc2hlZFwiKVxuICAgICAgICBsZXQga2V5ID0gdGhpcy5jdXJyZW50TGV2ZWwudG9TdHJpbmcoKVxuICAgICAgICBsZXQgY3VycmVudFRpbGVzID0gdGhpcy50aWxlTGF5ZXJzW2tleV1cbiAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50VGlsZXMgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbnN1cmVUaWxlcyh0aGlzLmN1cnJlbnRMZXZlbClcbiAgICAgICAgLy8gbGV0IGFsbCA9IG5ldyBTZXQoKVxuICAgICAgICAvLyBmb3IgKGxldCB0aWxlIG9mIGN1cnJlbnRUaWxlcy5jaGlsZHJlbikge1xuICAgICAgICAvLyAgICAgYWxsLmFkZCh0aWxlLnVybClcbiAgICAgICAgLy8gfVxuICAgICAgICAvLyBsZXQgeyBjZW50ZXJDb2wsIGNlbnRlclJvdywgbmVlZGVkIH0gPSB0aGlzLm5lZWRlZFRpbGVzKGN1cnJlbnRUaWxlcywgdGhpcy5jdXJyZW50TGV2ZWwpXG4gICAgICAgIC8vIGZvciAobGV0IFt1cmwsIGNvbCwgcm93XSBvZiBuZWVkZWQpIHtcbiAgICAgICAgLy8gICAgIGFsbC5kZWxldGUodXJsKVxuICAgICAgICAvLyB9XG4gICAgICAgIC8vIGZvciAobGV0IHVybCBvZiBhbGwpIHtcbiAgICAgICAgLy8gICAgIGN1cnJlbnRUaWxlcy5kZXN0cm95VGlsZUJ5VXJsKHVybClcbiAgICAgICAgLy8gfVxuICAgICAgICAvLyBjdXJyZW50VGlsZXMubG9hZGVyLmxvYWRlci5yZXNldCgpXG4gICAgfVxufVxuIiwiaW1wb3J0IHtnZXRJZCwgQW5nbGV9IGZyb20gJy4uL3V0aWxzLmpzJ1xuaW1wb3J0IHtET01TY2F0dGVyfSBmcm9tICcuLi9zY2F0dGVyLmpzJ1xuaW1wb3J0IHtDYXJkTG9hZGVyLCBET01GbGlwLCBET01GbGlwcGFibGV9IGZyb20gJy4uL2ZsaXBwYWJsZS5qcydcbmltcG9ydCB7Q2FwYWJpbGl0aWVzfSBmcm9tICcuLi9jYXBhYmlsaXRpZXMuanMnXG5pbXBvcnQge0RlZXBab29tSW1hZ2V9IGZyb20gJy4vZGVlcHpvb20vaW1hZ2UuanMnXG5cbmxldCBnbG9iYWxTY2F0dGVyTG9hZGVyQ2FudmFzID0gbnVsbFxuXG5leHBvcnQgY2xhc3MgU2NhdHRlckxvYWRlciBleHRlbmRzIENhcmRMb2FkZXIge1xuXG4gICAgZ2V0IHNjYXR0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNyY1xuICAgIH1cblxuICAgIHVuc2NhbGVkU2l6ZSgpIHtcbiAgICAgICAgbGV0IGRpc3BsYXlPYmplY3QgPSB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdFxuICAgICAgICBsZXQgdyA9IGRpc3BsYXlPYmplY3Qud2lkdGhcbiAgICAgICAgbGV0IGggPSBkaXNwbGF5T2JqZWN0LmhlaWdodFxuICAgICAgICByZXR1cm4gW3cgLyBkaXNwbGF5T2JqZWN0LnNjYWxlLngsIGggLyBkaXNwbGF5T2JqZWN0LnNjYWxlLnldXG4gICAgfVxuXG4gICAgc2NhbGVkU2l6ZSgpIHtcbiAgICAgICAgbGV0IGRpc3BsYXlPYmplY3QgPSB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdFxuICAgICAgICBsZXQgdyA9IGRpc3BsYXlPYmplY3Qud2lkdGhcbiAgICAgICAgbGV0IGggPSBkaXNwbGF5T2JqZWN0LmhlaWdodFxuICAgICAgICByZXR1cm4gW3csIGhdXG4gICAgfVxuXG4gICAgY2xvbmVTY2F0dGVySW1hZ2UoKSB7XG4gICAgICAgIGxldCB3ID0gdGhpcy5zY2F0dGVyLndpZHRoXG4gICAgICAgIGxldCBoID0gdGhpcy5zY2F0dGVyLmhlaWdodFxuICAgICAgICBsZXQgaXNTcHJpdGUgPSB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdCBpbnN0YW5jZW9mIFBJWEkuU3ByaXRlXG4gICAgICAgIGxldCBpc0RlZXBab29tID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3QgaW5zdGFuY2VvZiBEZWVwWm9vbUltYWdlXG4gICAgICAgIGxldCByZXNvbHV0aW9uID0gYXBwLnJlbmRlcmVyLnJlc29sdXRpb25cbiAgICAgICAgaWYgKGlzU3ByaXRlKSB7XG4gICAgICAgICAgICB3ID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3QudGV4dHVyZS53aWR0aFxuICAgICAgICAgICAgaCA9IHRoaXMuc2NhdHRlci5kaXNwbGF5T2JqZWN0LnRleHR1cmUuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNEZWVwWm9vbSkge1xuICAgICAgICAgICAgbGV0IFt3dywgaGhdID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3QuYmFzZVNpemVcbiAgICAgICAgICAgIHcgPSB3d1xuICAgICAgICAgICAgaCA9IGhoXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdsb2JhbFNjYXR0ZXJMb2FkZXJDYW52YXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGdsb2JhbFNjYXR0ZXJMb2FkZXJDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKVxuICAgICAgICB9XG4gICAgICAgIGxldCBjYW52YXMgPSBnbG9iYWxTY2F0dGVyTG9hZGVyQ2FudmFzXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHdcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IGhcbiAgICAgICAgbGV0IHJlbmRlcmVyID0gbmV3IFBJWEkuV2ViR0xSZW5kZXJlcih3LCBoLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3OiBjYW52YXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHV0aW9uOiByZXNvbHV0aW9ufSlcblxuICAgICAgICBsZXQgZGlzcGxheU9iamVjdCA9IHRoaXMuc2NhdHRlci5kaXNwbGF5T2JqZWN0XG4gICAgICAgIGxldCB4ID0gZGlzcGxheU9iamVjdC54XG4gICAgICAgIGxldCB5ID0gZGlzcGxheU9iamVjdC55XG4gICAgICAgIGxldCByb3QgPSBkaXNwbGF5T2JqZWN0LnJvdGF0aW9uXG4gICAgICAgIGxldCBzeCA9IGRpc3BsYXlPYmplY3Quc2NhbGUueFxuICAgICAgICBsZXQgc3kgPSBkaXNwbGF5T2JqZWN0LnNjYWxlLnlcbiAgICAgICAgZGlzcGxheU9iamVjdC5yb3RhdGlvbiA9IDBcbiAgICAgICAgLy8gVGhlIFNhZmFyaSBXZWJHTFJlbmRlcmVyIHdhbnRzIGV2ZXJ5dGhpbmcgZmxpcHBlZFxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3BpeGlqcy9waXhpLmpzL2lzc3Vlcy8yMjgzXG4gICAgICAgIGRpc3BsYXlPYmplY3QueCA9IDBcbiAgICAgICAgaWYgKENhcGFiaWxpdGllcy5pc1NhZmFyaSkge1xuICAgICAgICAgICAgZGlzcGxheU9iamVjdC55ID0gaFxuICAgICAgICAgICAgZGlzcGxheU9iamVjdC5zY2FsZS5zZXQoMSwgLTEpIC8vIHN4LCAtc3kpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkaXNwbGF5T2JqZWN0LnkgPSAwXG4gICAgICAgICAgICBkaXNwbGF5T2JqZWN0LnNjYWxlLnNldCgxLCAxKVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc1Nwcml0ZSkge1xuICAgICAgICAgICAgZGlzcGxheU9iamVjdC53aWR0aCA9IHdcbiAgICAgICAgICAgIGRpc3BsYXlPYmplY3QuaGVpZ2h0ID0gaFxuICAgICAgICB9XG4gICAgICAgIHJlbmRlcmVyLnJlbmRlcihkaXNwbGF5T2JqZWN0KVxuICAgICAgICBkaXNwbGF5T2JqZWN0LnJvdGF0aW9uID0gcm90XG4gICAgICAgIGRpc3BsYXlPYmplY3QueCA9IHhcbiAgICAgICAgZGlzcGxheU9iamVjdC55ID0geVxuICAgICAgICBkaXNwbGF5T2JqZWN0LnNjYWxlLnNldChzeCwgc3kpXG5cbiAgICAgICAgbGV0IHVybCA9IGNhbnZhcy50b0RhdGFVUkwoKVxuICAgICAgICByZXR1cm4gW3gsIHksIHcsIGgsIHVybF1cbiAgICB9XG5cbiAgICBsb2FkKGRvbU5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBpc0ltYWdlID0gZG9tTm9kZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnRcbiAgICAgICAgICAgIGxldCBpc1Nwcml0ZSA9IHRoaXMuc2NhdHRlci5kaXNwbGF5T2JqZWN0IGluc3RhbmNlb2YgUElYSS5TcHJpdGVcbiAgICAgICAgICAgIGxldCBpbWFnZSA9IChpc0ltYWdlKSA/IGRvbU5vZGUgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpXG4gICAgICAgICAgICBsZXQgW3gsIHksIHcsIGgsIGNsb25lVVJMXSA9IHRoaXMuY2xvbmVTY2F0dGVySW1hZ2UoKVxuICAgICAgICAgICAgbGV0IFt3dywgaGhdID0gdGhpcy51bnNjYWxlZFNpemUoKVxuICAgICAgICAgICAgaW1hZ2Uub25sb2FkID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzSW1hZ2UpXG4gICAgICAgICAgICAgICAgICAgIGRvbU5vZGUuYXBwZW5kQ2hpbGQoaW1hZ2UpXG4gICAgICAgICAgICAgICAgdGhpcy54ID0geFxuICAgICAgICAgICAgICAgIHRoaXMueSA9IHlcbiAgICAgICAgICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gd3dcbiAgICAgICAgICAgICAgICB0aGlzLndhbnRlZEhlaWdodCA9IGhoXG4gICAgICAgICAgICAgICAgdGhpcy5zY2FsZSA9IDFcbiAgICAgICAgICAgICAgICB0aGlzLnJvdGF0aW9uID0gdGhpcy5zY2F0dGVyLnJvdGF0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW1hZ2Uub25lcnJvciA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbWFnZS5zcmMgPSBjbG9uZVVSTFxuICAgICAgICAgICAgfSlcbiAgICB9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmxpcEVmZmVjdCB7XG5cbiAgICBjb25zdHJ1Y3RvcihzY2F0dGVyLCBkb21TY2F0dGVyQ29udGFpbmVyLCBmbGlwVGVtcGxhdGUsIGJhY2tMb2FkZXIpIHtcbiAgICAgICAgdGhpcy5mbGlwcGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy5zY2F0dGVyID0gc2NhdHRlclxuICAgICAgICB0aGlzLmJhY2tMb2FkZXIgPSBiYWNrTG9hZGVyXG4gICAgICAgIHRoaXMuc2NhdHRlckxvYWRlciA9IG5ldyBTY2F0dGVyTG9hZGVyKHNjYXR0ZXIpXG4gICAgICAgIHRoaXMuZG9tRmxpcCA9IG5ldyBET01GbGlwKGRvbVNjYXR0ZXJDb250YWluZXIsIGZsaXBUZW1wbGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NhdHRlckxvYWRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tMb2FkZXIsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkJhY2s6IHRoaXMuYmFja0NhcmRDbG9zZWQuYmluZCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgdGhpcy5zZXR1cEluZm9CdXR0b24oKVxuICAgIH1cblxuICAgIHN0YXJ0RmxpcCgpIHtcbiAgICAgICAgbGV0IGNlbnRlciA9IHRoaXMuZmxpcENlbnRlcigpXG4gICAgICAgIGxldCBsb2FkZXIgPSB0aGlzLmJhY2tMb2FkZXJcbiAgICAgICAgdGhpcy5kb21GbGlwLmxvYWQoKS50aGVuKChkb21GbGlwKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdC52aXNpYmxlID0gZmFsc2VcbiAgICAgICAgICAgIGRvbUZsaXAuY2VudGVyQXQoY2VudGVyKVxuICAgICAgICAgICAgZG9tRmxpcC56b29tKHRoaXMuc2NhdHRlci5zY2FsZSlcbiAgICAgICAgICAgIGxldCB0YXJnZXQgPSB0aGlzLmNvbnN0cmFpbnRGbGlwQ2VudGVyKGNlbnRlciwgbG9hZGVyKVxuICAgICAgICAgICAgY29uc29sZS5sb2coXCJGbGlwRWZmZWN0LnN0YXJ0RmxpcFwiLCB0YXJnZXQsIGxvYWRlcilcbiAgICAgICAgICAgIGRvbUZsaXAuc3RhcnQoe3RhcmdldENlbnRlcjogdGFyZ2V0fSlcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICB1bnNjYWxlZFNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjYXR0ZXJMb2FkZXIudW5zY2FsZWRTaXplKClcbiAgICB9XG5cbiAgICBmbGlwQ2VudGVyKCkge1xuICAgICAgICBsZXQgaXNTcHJpdGUgPSB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdCBpbnN0YW5jZW9mIFBJWEkuU3ByaXRlXG4gICAgICAgIGxldCByZXNvbHV0aW9uID0gKGlzU3ByaXRlKSA/IGFwcC5yZW5kZXJlci5yZXNvbHV0aW9uIDogMVxuICAgICAgICBsZXQgY2VudGVyID0gdGhpcy5zY2F0dGVyLmNlbnRlclxuICAgICAgICBsZXQgY2FudmFzID0gYXBwLnJlbmRlcmVyLnZpZXdcbiAgICAgICAgbGV0IGRvbU5vZGUgPSB0aGlzLmRvbUZsaXAuZG9tU2NhdHRlckNvbnRhaW5lci5lbGVtZW50XG4gICAgICAgIGxldCBwYWdlID0gd2luZG93LmNvbnZlcnRQb2ludEZyb21Ob2RlVG9QYWdlKGNhbnZhcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVyLngqcmVzb2x1dGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VudGVyLnkqcmVzb2x1dGlvbilcbiAgICAgICAgbGV0IGxvY2FsID0gd2luZG93LmNvbnZlcnRQb2ludEZyb21QYWdlVG9Ob2RlKGRvbU5vZGUsIHBhZ2UueCwgcGFnZS55KVxuICAgICAgICByZXR1cm4gbG9jYWxcbiAgICB9XG5cbiAgICBjb25zdHJhaW50RmxpcENlbnRlcihjZW50ZXIsIGxvYWRlcikge1xuICAgICAgICBsZXQgdyA9IGxvYWRlci53YW50ZWRXaWR0aFxuICAgICAgICBsZXQgaCA9IGxvYWRlci53YW50ZWRIZWlnaHRcbiAgICAgICAgY29uc29sZS5sb2coXCJjb25zdHJhaW50RmxpcENlbnRlclwiLCB3LCBoKVxuICAgICAgICBsZXQgY2FudmFzID0gYXBwLnJlbmRlcmVyLnZpZXdcbiAgICAgICAgbGV0IHggPSBjZW50ZXIueFxuICAgICAgICBsZXQgeSA9IGNlbnRlci55XG4gICAgICAgIGlmICh4IDwgdy8yKVxuICAgICAgICAgICAgeCA9IHcvMlxuICAgICAgICBpZiAoeSA8IGgvMilcbiAgICAgICAgICAgeSA9IGgvMlxuICAgICAgICBpZiAoeCA+IGNhbnZhcy53aWR0aClcbiAgICAgICAgICAgIHggPSBjYW52YXMud2lkdGggLSB3LzJcbiAgICAgICAgaWYgKHkgPiBjYW52YXMuaGVpZ2h0KVxuICAgICAgICAgICAgeSA9IGNhbnZhcy5oZWlnaHQgLSBoLzJcbiAgICAgICAgcmV0dXJuIHsgeCwgeSB9XG4gICAgfVxuXG4gICAgc2V0dXBJbmZvQnV0dG9uKCkge1xuICAgICAgICBsZXQgaXNjYWxlID0gMS4wIC8gdGhpcy5zY2F0dGVyLnNjYWxlXG4gICAgICAgIHRoaXMuaW5mb0J0biA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgdGhpcy5pbmZvQnRuLmJlZ2luRmlsbCgweDMzMzMzMylcbiAgICAgICAgdGhpcy5pbmZvQnRuLmxpbmVTdHlsZSg0LCAweEZGRkZGRilcbiAgICAgICAgdGhpcy5pbmZvQnRuLmRyYXdDaXJjbGUoMCwgMCwgMjIpXG4gICAgICAgIHRoaXMuaW5mb0J0bi5lbmRGaWxsKClcblxuICAgICAgICB0aGlzLmluZm9CdG4uYmVnaW5GaWxsKDB4RkZGRkZGKVxuICAgICAgICB0aGlzLmluZm9CdG4ubGluZVN0eWxlKDApXG4gICAgICAgIHRoaXMuaW5mb0J0bi5kcmF3Q2lyY2xlKDAsIC04LCA0KVxuICAgICAgICB0aGlzLmluZm9CdG4uZW5kRmlsbCgpXG5cbiAgICAgICAgdGhpcy5pbmZvQnRuLmxpbmVTdHlsZSg2LCAweEZGRkZGRilcbiAgICAgICAgdGhpcy5pbmZvQnRuLm1vdmVUbygwLCAtMilcbiAgICAgICAgdGhpcy5pbmZvQnRuLmxpbmVUbygwLCAxNClcbiAgICAgICAgdGhpcy5pbmZvQnRuLmVuZEZpbGwoKVxuXG4gICAgICAgIHRoaXMuaW5mb0J0bi5vbignY2xpY2snLCAoZSkgPT4geyB0aGlzLmluZm9TZWxlY3RlZCgpIH0pXG4gICAgICAgIHRoaXMuaW5mb0J0bi5vbigndGFwJywgKGUpID0+IHsgdGhpcy5pbmZvU2VsZWN0ZWQoKSB9KVxuXG4gICAgICAgIHRoaXMuaW5mb0J0bi5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgdGhpcy5pbmZvQnRuLndpZHRoID0gNDRcbiAgICAgICAgdGhpcy5pbmZvQnRuLmhlaWdodCA9IDQ0XG4gICAgICAgIHRoaXMuaW5mb0J0bi5waXZvdC54ID0gMzBcbiAgICAgICAgdGhpcy5pbmZvQnRuLnBpdm90LnkgPSAzMFxuXG4gICAgICAgIGxldCBkaXNwbGF5T2JqZWN0ID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3RcbiAgICAgICAgbGV0IFt3LCBoXSA9IHRoaXMudW5zY2FsZWRTaXplKClcbiAgICAgICAgdGhpcy5pbmZvQnRuLnBvc2l0aW9uID0gbmV3IFBJWEkuUG9pbnQodywgaClcbiAgICAgICAgaWYgKGRpc3BsYXlPYmplY3QuZm9yZWdyb3VuZCkge1xuICAgICAgICAgICAgdGhpcy5pbmZvQnRuLnNjYWxlLnggPSBpc2NhbGVcbiAgICAgICAgICAgIHRoaXMuaW5mb0J0bi5zY2FsZS55ID0gaXNjYWxlXG4gICAgICAgICAgICBkaXNwbGF5T2JqZWN0LmZvcmVncm91bmQuYWRkQ2hpbGQodGhpcy5pbmZvQnRuKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGlzcGxheU9iamVjdC5hZGRDaGlsZCh0aGlzLmluZm9CdG4pXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNjYXR0ZXIuYWRkVHJhbnNmb3JtRXZlbnRDYWxsYmFjayhlID0+IHtcbiAgICAgICAgICAgIGxldCBkaXNwbGF5T2JqZWN0ID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3RcbiAgICAgICAgICAgIGlmIChkaXNwbGF5T2JqZWN0LmZvcmVncm91bmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZS5zY2FsZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaXNjYWxlID0gMS4wIC8gZS5zY2FsZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZm9CdG4uc2NhbGUueCA9IGlzY2FsZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZm9CdG4uc2NhbGUueSA9IGlzY2FsZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBzZXR1cEJ1dHRvbih1cmwpIHtcbiAgICAgICAgbGV0IHN2Z0ltYWdlID0gbmV3IEltYWdlKClcbiAgICAgICAgbGV0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IDg4ICogNFxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gNDQgKiA0XG4gICAgICAgIHN2Z0ltYWdlLm9ubG9hZCA9IGUgPT4ge1xuICAgICAgICAgICAgbGV0IGRpc3BsYXlPYmplY3QgPSB0aGlzLnNjYXR0ZXIuZGlzcGxheU9iamVjdFxuICAgICAgICAgICAgY2FudmFzLmdldENvbnRleHQgKCcyZCcpLmRyYXdJbWFnZShzdmdJbWFnZSwgMCwgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KVxuICAgICAgICAgICAgbGV0IHRleHVyZSA9IG5ldyBQSVhJLlRleHR1cmUobmV3IFBJWEkuQmFzZVRleHR1cmUoY2FudmFzKSlcbiAgICAgICAgICAgIHRoaXMuaW5mb0J0biA9IG5ldyBQSVhJLlNwcml0ZSh0ZXh1cmUpXG4gICAgICAgICAgICB0aGlzLmluZm9CdG4uYW5jaG9yLnNldCgwLjUsIDAuNSlcbiAgICAgICAgICAgIGlmIChkaXNwbGF5T2JqZWN0LmZvcmVncm91bmQpIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5T2JqZWN0LmZvcmVncm91bmQuYWRkQ2hpbGQodGhpcy5pbmZvQnRuKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGlzcGxheU9iamVjdC5hZGRDaGlsZCh0aGlzLmluZm9CdG4pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmluZm9CdG4uc2NhbGUuc2V0KDAuNSwgMC41KVxuXG4gICAgICAgICAgICBsZXQgW3csIGhdID0gdGhpcy51bnNjYWxlZFNpemUoKVxuICAgICAgICAgICAgdGhpcy5pbmZvQnRuLnBvc2l0aW9uID0gbmV3IFBJWEkuUG9pbnQodywgaClcbiAgICAgICAgICAgIHRoaXMuaW5mb0J0bi5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgICAgIHRoaXMuaW5mb0J0bi51cGRhdGVUcmFuc2Zvcm0oKVxuICAgICAgICAgICAgdGhpcy5pbmZvQnRuLm9uKCdjbGljaycsIChlKSA9PiB7IHRoaXMuaW5mb1NlbGVjdGVkKCkgfSlcbiAgICAgICAgICAgIHRoaXMuaW5mb0J0bi5vbigndGFwJywgKGUpID0+IHsgdGhpcy5pbmZvU2VsZWN0ZWQoKSB9KVxuICAgICAgICB9XG4gICAgICAgIHN2Z0ltYWdlLnNyYyA9IHVybFxuICAgIH1cblxuICAgIGluZm9TZWxlY3RlZCgpIHtcbiAgICAgICAgdGhpcy5zdGFydEZsaXAoKVxuICAgIH1cblxuICAgIGJhY2tTZWxlY3RlZCgpIHtcbiAgICAgICAgdGhpcy5kb21GbGlwLnN0YXJ0KClcbiAgICB9XG5cbiAgICBiYWNrQ2FyZENsb3NlZCgpIHtcbiAgICAgICAgLyoqKiBUaGUgZmxpcCBlZmZlY3Qgc2hvdWxkIG5vdyBiZSBpbiBpdCdzIGluaXRpYWwgc3RhdGUgYWdhaW4uIEFsbFxuICAgICAgICBtZW1vcnkgc2hvdWxkIGJlIGZyZWVkLiAqKiovXG4gICAgICAgIGxldCBkaXNwbGF5T2JqZWN0ID0gdGhpcy5zY2F0dGVyLmRpc3BsYXlPYmplY3RcbiAgICAgICAgZGlzcGxheU9iamVjdC52aXNpYmxlID0gdHJ1ZVxuICAgICAgICB0aGlzLmRvbUZsaXAuZmFkZU91dEFuZFJlbW92ZSgpXG4gICAgICAgIHRoaXMuZmxpcHBlZCA9IGZhbHNlXG4gICAgfVxuXG4gICAgdGFyZ2V0Um90YXRpb24oYWxwaGEpIHtcbiAgICAgICAgbGV0IG9ydGhvID0gOTBcbiAgICAgICAgbGV0IHJlc3QgPSBhbHBoYSAlIG9ydGhvXG4gICAgICAgIGxldCBkZWx0YSA9IDAuMFxuICAgICAgICBpZiAocmVzdCA+IChvcnRobyAvIDIuMCkpIHtcbiAgICAgICAgICAgIGRlbHRhID0gb3J0aG8gLSByZXN0XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWx0YSA9IC1yZXN0XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlbHRhXG4gICAgfVxufVxuXG4iLCIvKiBnbG9iYWxzIFBvd2VyMiwgU2luZSAqL1xuLyplc2xpbnQgbm8tY29uc29sZTogW1wiZXJyb3JcIiwgeyBhbGxvdzogW1wibG9nXCIsIFwiaW5mb1wiLCBcImVycm9yXCJdIH1dKi9cblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIGZsaXBwYWJsZSBvblN0YXJ0IGZ1bmN0aW9uLlxuICpcbiAqIEBjYWxsYmFjayBvblN0YXJ0Q2FsbGJhY2tcbiAqIEBwYXJhbSB7RmxpcHBhYmxlfSBmbGlwcGFibGUgLSBBIHJlZmVyZW5jZSB0byB0aGUgZmxpcHBhYmxlIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBmbGlwcGFibGUpLlxuICovXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBmbGlwcGFibGUgb25VcGRhdGUgZnVuY3Rpb24uXG4gKlxuICogQGNhbGxiYWNrIG9uVXBkYXRlQ2FsbGJhY2tcbiAqIEBwYXJhbSB7RmxpcHBhYmxlfSBmbGlwcGFibGUgLSBBIHJlZmVyZW5jZSB0byB0aGUgZmxpcHBhYmxlIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBmbGlwcGFibGUpLlxuICovXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBmbGlwcGFibGUgb25Db21wbGV0ZSBmdW5jdGlvbi5cbiAqXG4gKiBAY2FsbGJhY2sgb25Db21wbGV0ZUNhbGxiYWNrXG4gKiBAcGFyYW0ge0ZsaXBwYWJsZX0gZmxpcHBhYmxlIC0gQSByZWZlcmVuY2UgdG8gdGhlIGZsaXBwYWJsZSAoYWxzbyB0aGlzIHJlZmVycyB0byB0aGUgZmxpcHBhYmxlKS5cbiAqL1xuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBGbGlwcGFibGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZyb250ID0gUElYSS5TcHJpdGUuZnJvbUltYWdlKCcuL2Fzc2V0cy9mcm9udC5qcGcnKVxuICogY29uc3QgYmFjayA9IFBJWEkuU3ByaXRlLmZyb21JbWFnZSgnLi9hc3NldHMvYmFjay5qcGcnKVxuICogYXBwLnNjZW5lLmFkZENoaWxkKGZyb250KVxuICogXG4gKiAvLyBDcmVhdGUgdGhlIGZsaXBwYWJsZVxuICogY29uc3QgZmxpcHBhYmxlID0gbmV3IEZsaXBwYWJsZShmcm9udCwgYmFjaywgYXBwLnJlbmRlcmVyKVxuICogXG4gKiBmcm9udC5pbnRlcmFjdGl2ZSA9IHRydWVcbiAqIGZyb250Lm9uKCdjbGljaycsIGV2ZW50ID0+IGZsaXBwYWJsZS50b2dnbGUoKSlcbiAqXG4gKiBAY2xhc3NcbiAqIEBleHRlbmRzIFBJWEkucHJvamVjdGlvbi5DYW1lcmEzZFxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3BpeGlqcy9waXhpLXByb2plY3Rpb258UGl4aUpTIFByb2plY3Rpb259XG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvZmxpcHBhYmxlLmh0bWx8RG9jVGVzdH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmxpcHBhYmxlIGV4dGVuZHMgUElYSS5wcm9qZWN0aW9uLkNhbWVyYTNkIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBGbGlwcGFibGUuXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1BJWEkuRGlzcGxheU9iamVjdH0gZnJvbnQgLSBUaGUgb2JqZWN0IHRvIHNob3cgaW5pdGlhbGx5LiBTaG91bGQgaGF2ZSBiZWVuIGFkZGVkIHRvIHRoZSBzY2VuZS5cbiAgICAgKiBAcGFyYW0ge1BJWEkuRGlzcGxheU9iamVjdH0gYmFjayAtIFRoZSBvYmplY3QgdG8gc2hvdyBvbiB0aGUgYmFja3NpZGUuIFNob3VsZCBoYXZlIG5vdCBiZWVuIGFkZGVkIHRvIHRoZSBzY2VuZS5cbiAgICAgKiBAcGFyYW0ge1BJWEkuV2ViR0xSZW5kZXJlcnxQSVhJLkNhbnZhc1JlbmRlcmVyfSByZW5kZXJlciAtIFRoZSByZW5kZXJlciBvZiB0aGUgYXBwbGljYXRpb24uXG4gICAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAtIEFuIG9wdGlvbnMgb2JqZWN0IHdoaWNoIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZHVyYXRpb249MV0gLSBUaGUgZHVyYXRpb24gb2YgdGhlIGZsaXAgYW5pbWF0aW9uIGluIHNlY29uZHMuXG4gICAgICogQHBhcmFtIHtHU0FQLkVhc2V9IFtvcHRzLmVhc2U9UG93ZXIyLmVhc2VPdXRdIC0gVGhlIGVhc2Ugb2YgdGhlIGZsaXAgYW5pbWF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuc2hhZG93PWZhbHNlXSAtIFNob3VsZCBiZSBhIHNoYWRvdyBiZWVuIGRpc3BsYXkgZHVyaW5nIHRoZSBhbmltYXRpb24/XG4gICAgICogQHBhcmFtIHtudW1lcn0gW29wdHMuZXVsZXJYPTBdIC0gVGhlIHNoaWZ0IG9mIHRoZSB4LWF4aXMgZHVyaW5nIHRoZSBhbmltYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1lcn0gW29wdHMuZXVsZXJZPTBdIC0gVGhlIHNoaWZ0IG9mIHRoZSB5LWF4aXMgZHVyaW5nIHRoZSBhbmltYXRpb24uXG4gICAgICogQHBhcmFtIHtHU0FQLkVhc2V9IFtvcHRzLmV1bGVyRWFzZT1TaW5lLmVhc2VPdXRdIC0gVGhlIGVhc2Ugb2YgdGhlIHNoaWZ0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudXNlQmFja1RyYW5zZm9ybXM9ZmFsc2VdIC0gV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIGZsaXAgYW5pbWF0aW9uIGFsc28gYW5pbWF0ZXMgdG8gdGhlIHRyYW5zZm9ybSBwYXJhbWV0ZXJzIG9mIHRoZSBiYWNrLW9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0dTQVAuRWFzZX0gW29wdHMudHJhbnNmb3JtRWFzZT1Qb3dlcjIuZWFzZU91dF0gLSBUaGUgZWFzZSBvZiB0aGUgdHJhbnNmb3JtLlxuICAgICAqIEBwYXJhbSB7bnVtZXJ9IFtvcHRzLmZvY3VzPTgwMF0gLSBUaGUgdmFsdWUgb2YgdGhlIGZvY3VzIG9mIHRoZSAzRCBjYW1lcmEgKHNlZSBwaXhpLXByb2plY3Rpb24pLlxuICAgICAqIEBwYXJhbSB7bnVtZXJ9IFtvcHRzLm5lYXI9MTBdIC0gVGhlIG5lYXIgdmFsdWUgb2YgdGhlIDNEIGNhbWVyYSAoc2VlIHBpeGktcHJvamVjdGlvbikuXG4gICAgICogQHBhcmFtIHtudW1lcn0gW29wdHMuZmFyPTEwMDAwXSAtIFRoZSBmYXIgdmFsdWUgb2YgdGhlIDNEIGNhbWVyYSAoc2VlIHBpeGktcHJvamVjdGlvbikuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5vcnRob2dyYXBoaWM9ZmFsc2VdIC0gU2hvdWxkIHRoZSBmbGlwIGFuaW1hdGlvbiBiZSBhbiBvcnRob2dyYXBoaWMgYW5pbWF0aW9uP1xuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRzLm9uU3RhcnQ9bnVsbF0gLSBBIGNhbGxiYWNrIGV4ZWN1dGVkIG9uIHN0YXJ0IG9mIHRoZSBmbGlwIGFuaW1hdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vblVwZGF0ZT1udWxsXSAtIEEgY2FsbGJhY2sgZXhlY3V0ZWQgb24gZWFjaCBzdGVwIG9mIHRoZSBmbGlwIGFuaW1hdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb3B0cy5vbkNvbXBsZXRlPW51bGxdIC0gQSBjYWxsYmFjayBleGVjdXRlZCB3aGVuIHRoZSBmbGlwIGFuaW1hdGlvbiBpcyBmaW5pc2hlZC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihmcm9udCwgYmFjaywgcmVuZGVyZXIsIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHN1cGVyKClcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBmcm9udCxcbiAgICAgICAgICAgIGJhY2ssXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIGR1cmF0aW9uOiAxLFxuICAgICAgICAgICAgZWFzZTogUG93ZXIyLmVhc2VPdXQsXG4gICAgICAgICAgICBzaGFkb3c6IGZhbHNlLFxuICAgICAgICAgICAgZXVsZXJYOiAwLFxuICAgICAgICAgICAgZXVsZXJZOiAwLFxuICAgICAgICAgICAgZXVsZXJFYXNlOiBTaW5lLmVhc2VPdXQsXG4gICAgICAgICAgICB1c2VCYWNrVHJhbnNmb3JtczogZmFsc2UsXG4gICAgICAgICAgICB0cmFuc2Zvcm1FYXNlOiBQb3dlcjIuZWFzZU91dCxcbiAgICAgICAgICAgIGZvY3VzOiA4MDAsXG4gICAgICAgICAgICBuZWFyOiAxMCxcbiAgICAgICAgICAgIGZhcjogMTAwMDAsXG4gICAgICAgICAgICBvcnRob2dyYXBoaWM6IGZhbHNlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgLy8gcGxhbmVzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXRQbGFuZXModGhpcy5vcHRzLmZvY3VzLCB0aGlzLm9wdHMubmVhciwgdGhpcy5vcHRzLmZhciwgdGhpcy5vcHRzLm9ydGhvZ3JhcGhpYylcblxuICAgICAgICAvLyBmbGlwcGVkXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5fZmxpcHBlZCA9IGZhbHNlXG5cbiAgICAgICAgLy8gb2JqZWN0c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMub2JqZWN0cyA9IHt9XG5cbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNldHVwKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7RmxpcHBhYmxlfSBBIHJlZmVyZW5jZSB0byB0aGUgZmxpcHBhYmxlIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHtcblxuICAgICAgICBjb25zdCBzY2FsZSA9IC41XG5cbiAgICAgICAgLy8gZmlsdGVyc1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IGJsdXJGaWx0ZXIgPSBuZXcgUElYSS5maWx0ZXJzLkJsdXJGaWx0ZXIoKVxuICAgICAgICBibHVyRmlsdGVyLmJsdXIgPSAwLjJcbiAgICAgICAgdGhpcy5vYmplY3RzLmJsdXJGaWx0ZXIgPSBibHVyRmlsdGVyXG5cbiAgICAgICAgLy8gb3V0ZXJcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBvdXRlciA9IG5ldyBQSVhJLnByb2plY3Rpb24uQ29udGFpbmVyM2QoKVxuICAgICAgICBvdXRlci5zY2FsZTNkLnNldChzY2FsZSlcbiAgICAgICAgdGhpcy5hZGRDaGlsZChvdXRlcilcbiAgICAgICAgdGhpcy5vYmplY3RzLm91dGVyID0gb3V0ZXJcblxuICAgICAgICAvLyBzaGFkb3dcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBzaGFkb3cgPSBuZXcgUElYSS5wcm9qZWN0aW9uLlNwcml0ZTNkKFBJWEkuVGV4dHVyZS5mcm9tSW1hZ2UoJy4uLy4uL2Fzc2V0cy9pbWFnZXMvc2hhZG93LnBuZycpKVxuICAgICAgICBzaGFkb3cucmVuZGVyYWJsZSA9IGZhbHNlXG4gICAgICAgIHNoYWRvdy5hbmNob3Iuc2V0KDAuNSlcbiAgICAgICAgc2hhZG93LnNjYWxlM2Quc2V0KC45OClcbiAgICAgICAgc2hhZG93LmFscGhhID0gMC43XG4gICAgICAgIHNoYWRvdy5maWx0ZXJzID0gW2JsdXJGaWx0ZXJdXG4gICAgICAgIHNoYWRvdy52aXNpYmxlID0gdGhpcy5vcHRzLnNoYWRvd1xuICAgICAgICBvdXRlci5hZGRDaGlsZChzaGFkb3cpXG4gICAgICAgIHRoaXMub2JqZWN0cy5zaGFkb3cgPSBzaGFkb3dcbiAgICAgICAgXG4gICAgICAgIC8vIGlubmVyXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgaW5uZXIgPSBuZXcgUElYSS5wcm9qZWN0aW9uLkNvbnRhaW5lcjNkKClcbiAgICAgICAgaW5uZXIuZXVsZXIueSA9IE1hdGguUElcbiAgICAgICAgb3V0ZXIuYWRkQ2hpbGQoaW5uZXIpXG4gICAgICAgIHRoaXMub2JqZWN0cy5pbm5lciA9IGlubmVyXG5cbiAgICAgICAgLy8gZnJvbnRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBmcm9udCA9IG5ldyBQSVhJLnByb2plY3Rpb24uU3ByaXRlM2QoUElYSS5UZXh0dXJlLkVNUFRZKVxuICAgICAgICBmcm9udC5zY2FsZS5zZXQoLTEgLyBzY2FsZSwgMSAvIHNjYWxlKVxuICAgICAgICBmcm9udC5yZW5kZXJhYmxlID0gdHJ1ZVxuICAgICAgICBmcm9udC5hbmNob3Iuc2V0KC41KVxuICAgICAgICBpbm5lci5hZGRDaGlsZChmcm9udClcbiAgICAgICAgdGhpcy5vYmplY3RzLmZyb250ID0gZnJvbnRcblxuICAgICAgICAvLyBiYWNrXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgYmFjayA9IG5ldyBQSVhJLnByb2plY3Rpb24uU3ByaXRlM2QoUElYSS5UZXh0dXJlLkVNUFRZKVxuICAgICAgICBiYWNrLnNjYWxlLnNldCgxIC8gc2NhbGUsIDEgLyBzY2FsZSlcbiAgICAgICAgYmFjay5yZW5kZXJhYmxlID0gZmFsc2VcbiAgICAgICAgYmFjay5hbmNob3Iuc2V0KC41KVxuICAgICAgICBpbm5lci5hZGRDaGlsZChiYWNrKVxuICAgICAgICB0aGlzLm9iamVjdHMuYmFjayA9IGJhY2tcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgb3Igc2V0cyB0aGUgZmxpcHBlZCBzdGF0ZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXIge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IGZsaXBwZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mbGlwcGVkXG4gICAgfVxuICAgIHNldCBmbGlwcGVkKHRvQmFjaykge1xuXG4gICAgICAgIHRoaXMuX2ZsaXBwZWQgPSB0b0JhY2tcblxuICAgICAgICAvLyByZWZlcmVuY2VzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgZnJvbnQgPSB0aGlzLm9iamVjdHMuZnJvbnRcbiAgICAgICAgY29uc3QgYmFjayA9IHRoaXMub2JqZWN0cy5iYWNrXG4gICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5vYmplY3RzLmlubmVyXG4gICAgICAgIGNvbnN0IHNoYWRvdyA9IHRoaXMub2JqZWN0cy5zaGFkb3dcbiAgICAgICAgY29uc3QgYmx1ckZpbHRlciA9IHRoaXMub2JqZWN0cy5ibHVyRmlsdGVyXG5cbiAgICAgICAgY29uc3QgaGFsZiA9IHRoaXMub3B0cy5kdXJhdGlvbiAvIDJcbiAgICAgICAgY29uc3QgZWFzZSA9IHRoaXMub3B0cy5ldWxlckVhc2VcblxuICAgICAgICBjb25zdCBmcm9tT2JqZWN0ID0gdG9CYWNrID8gdGhpcy5vcHRzLmZyb250IDogdGhpcy5vcHRzLmJhY2tcbiAgICAgICAgY29uc3QgdG9PYmplY3QgPSB0b0JhY2sgPyB0aGlzLm9wdHMuYmFjayA6IHRoaXMub3B0cy5mcm9udFxuXG4gICAgICAgIC8vIHNldCB0ZXh0dXJlcyBmb3IgdmlydHVhbCBmcm9udCBhbmQgdmlydHVhbCBiYWNrXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgZnJvbnQudGV4dHVyZSA9IHRoaXMuZ2VuZXJhdGVUZXh0dXJlKHRoaXMub3B0cy5mcm9udClcbiAgICAgICAgYmFjay50ZXh0dXJlID0gdGhpcy5nZW5lcmF0ZVRleHR1cmUodGhpcy5vcHRzLmJhY2spXG4gICAgICAgIFxuICAgICAgICAvLyBzd2l0Y2ggb2JqZWN0cyBhbmQgc2V0IHBhcmFtcyBmb3IgdmlydHVhbCBvYmplY3RzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgZnJvbUNlbnRlciA9IHRoaXMuYW5jaG9yVG9DZW50ZXIoZnJvbU9iamVjdClcbiAgICAgICAgY29uc3QgdG9DZW50ZXIgPSB0aGlzLmFuY2hvclRvQ2VudGVyKHRvT2JqZWN0KVxuXG4gICAgICAgIC8vIGZyb20gdmFsdWVzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy54ID0gZnJvbUNlbnRlci54XG4gICAgICAgIHRoaXMueSA9IGZyb21DZW50ZXIueVxuICAgICAgICBmcm9udC53aWR0aCA9IGZyb21PYmplY3Qud2lkdGggKiAyXG4gICAgICAgIGZyb250LmhlaWdodCA9IGZyb21PYmplY3QuaGVpZ2h0ICogMlxuICAgICAgICBiYWNrLndpZHRoID0gZnJvbU9iamVjdC53aWR0aCAqIDJcbiAgICAgICAgYmFjay5oZWlnaHQgPSBmcm9tT2JqZWN0LmhlaWdodCAqIDJcbiAgICAgICAgdGhpcy5yb3RhdGlvbiA9IGZyb21PYmplY3Qucm90YXRpb25cbiAgICAgICAgdGhpcy5za2V3LnggPSBmcm9tT2JqZWN0LnNrZXcueFxuICAgICAgICB0aGlzLnNrZXcueSA9IGZyb21PYmplY3Quc2tldy55XG5cbiAgICAgICAgLy8gY2FsY3VsYXRlIHRvIHZhbHVlc1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IHRvID0ge1xuICAgICAgICAgICAgeDogdGhpcy5vcHRzLnVzZUJhY2tUcmFuc2Zvcm1zID8gdG9DZW50ZXIueCA6IGZyb21DZW50ZXIueCxcbiAgICAgICAgICAgIHk6IHRoaXMub3B0cy51c2VCYWNrVHJhbnNmb3JtcyA/IHRvQ2VudGVyLnkgOiBmcm9tQ2VudGVyLnksXG4gICAgICAgICAgICBhbmNob3JYOiB0aGlzLm9wdHMudXNlQmFja1RyYW5zZm9ybXMgPyB0b09iamVjdC54IDogZnJvbU9iamVjdC54LFxuICAgICAgICAgICAgYW5jaG9yWTogdGhpcy5vcHRzLnVzZUJhY2tUcmFuc2Zvcm1zID8gdG9PYmplY3QueSA6IGZyb21PYmplY3QueSxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLm9wdHMudXNlQmFja1RyYW5zZm9ybXMgPyB0b09iamVjdC53aWR0aCAqIDIgOiBmcm9tT2JqZWN0LndpZHRoICogMixcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5vcHRzLnVzZUJhY2tUcmFuc2Zvcm1zID8gdG9PYmplY3QuaGVpZ2h0ICogMiA6IGZyb21PYmplY3QuaGVpZ2h0ICogMixcbiAgICAgICAgICAgIHJvdGF0aW9uOiB0aGlzLm9wdHMudXNlQmFja1RyYW5zZm9ybXMgPyB0b09iamVjdC5yb3RhdGlvbiA6IGZyb21PYmplY3Qucm90YXRpb24sXG4gICAgICAgICAgICBza2V3WDogdGhpcy5vcHRzLnVzZUJhY2tUcmFuc2Zvcm1zID8gdG9PYmplY3Quc2tldy54IDogZnJvbU9iamVjdC5za2V3LngsXG4gICAgICAgICAgICBza2V3WTogdGhpcy5vcHRzLnVzZUJhY2tUcmFuc2Zvcm1zID8gdG9PYmplY3Quc2tldy55IDogZnJvbU9iamVjdC5za2V3LnlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNldCB0b09iamVjdCBlbmQgdmFsdWVzXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdG9PYmplY3QueCA9IHRvLmFuY2hvclhcbiAgICAgICAgdG9PYmplY3QueSA9IHRvLmFuY2hvcllcbiAgICAgICAgdG9PYmplY3Qud2lkdGggPSB0by53aWR0aCAvIDJcbiAgICAgICAgdG9PYmplY3QuaGVpZ2h0ID0gdG8uaGVpZ2h0IC8gMlxuICAgICAgICB0b09iamVjdC5yb3RhdGlvbiA9IHRvLnJvdGF0aW9uXG4gICAgICAgIHRvT2JqZWN0LnNrZXcueCA9IHRvLnNrZXdYXG4gICAgICAgIHRvT2JqZWN0LnNrZXcueSA9IHRvLnNrZXdZXG5cbiAgICAgICAgLy8gZmxpcFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIFR3ZWVuTGl0ZS50byhpbm5lci5ldWxlciwgdGhpcy5vcHRzLmR1cmF0aW9uLCB7XG4gICAgICAgICAgICB5OiB0b0JhY2sgPyAwIDogTWF0aC5QSSxcbiAgICAgICAgICAgIGVhc2U6IHRoaXMub3B0cy5lYXNlLFxuICAgICAgICAgICAgb25TdGFydDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3dpdGNoRGlzcGxheU9iamVjdChmcm9tT2JqZWN0LCB0aGlzKVxuICAgICAgICAgICAgICAgIHNoYWRvdy5yZW5kZXJhYmxlID0gdHJ1ZVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMub25TdGFydCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdHMub25TdGFydCh0aGlzLCB0aGlzKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvblVwZGF0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0KClcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLm9uVXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0cy5vblVwZGF0ZSh0aGlzLCB0aGlzKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zd2l0Y2hEaXNwbGF5T2JqZWN0KHRoaXMsIHRvT2JqZWN0KVxuICAgICAgICAgICAgICAgIHNoYWRvdy5yZW5kZXJhYmxlID0gZmFsc2VcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLm9uQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLm9uQ29tcGxldGUodGhpcywgdGhpcylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8geCAmIHlcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcywgdGhpcy5vcHRzLmR1cmF0aW9uLCB7XG4gICAgICAgICAgICB4OiB0by54LFxuICAgICAgICAgICAgeTogdG8ueSxcbiAgICAgICAgICAgIGVhc2U6IHRoaXMub3B0cy50cmFuc2Zvcm1FYXNlXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gd2lkdGggJiBoZWlnaHRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBUd2VlbkxpdGUudG8oW2Zyb250LCBiYWNrXSwgdGhpcy5vcHRzLmR1cmF0aW9uLCB7XG4gICAgICAgICAgICB3aWR0aDogdG8ud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRvLmhlaWdodCxcbiAgICAgICAgICAgIGVhc2U6IHRoaXMub3B0cy50cmFuc2Zvcm1FYXNlXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gcm90YXRpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcywgdGhpcy5vcHRzLmR1cmF0aW9uLCB7XG4gICAgICAgICAgICBkaXJlY3Rpb25hbFJvdGF0aW9uOiB7XG4gICAgICAgICAgICAgICAgcm90YXRpb246IGAke3RvLnJvdGF0aW9ufV9zaG9ydGAsXG4gICAgICAgICAgICAgICAgdXNlUmFkaWFuczogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVhc2U6IHRoaXMub3B0cy50cmFuc2Zvcm1FYXNlXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gc2tld1ggJiBza2V3WVxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLnNrZXcsIHRoaXMub3B0cy5kdXJhdGlvbiwge1xuICAgICAgICAgICAgeDogdG8uc2tld1gsXG4gICAgICAgICAgICB5OiB0by5za2V3WSxcbiAgICAgICAgICAgIGVhc2U6IHRoaXMub3B0cy50cmFuc2Zvcm1FYXNlXG4gICAgICAgIH0pXG5cbiAgICAgICAgLy8gY2FtZXJhXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgbmV3IFRpbWVsaW5lTWF4KClcbiAgICAgICAgICAgIC50byh0aGlzLmV1bGVyLCBoYWxmLCB7eDogdGhpcy5vcHRzLmV1bGVyWCwgeTogdGhpcy5vcHRzLmV1bGVyWSwgZWFzZX0pXG4gICAgICAgICAgICAudG8odGhpcy5ldWxlciwgaGFsZiwge3g6IDAsIHk6IDAsIGVhc2V9KVxuXG4gICAgICAgIC8vIHNoYWRvd1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIG5ldyBUaW1lbGluZU1heCgpXG4gICAgICAgICAgICAudG8oc2hhZG93LCBoYWxmLCB7YWxwaGE6IC4zLCBlYXNlfSlcbiAgICAgICAgICAgIC50byhzaGFkb3csIGhhbGYsIHthbHBoYTogLjcsIGVhc2V9KVxuICAgICAgICBcbiAgICAgICAgLy8gYmx1cmZpbHRlclxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIG5ldyBUaW1lbGluZU1heCgpXG4gICAgICAgICAgICAudG8oYmx1ckZpbHRlciwgaGFsZiwge2JsdXI6IDYsIGVhc2V9KVxuICAgICAgICAgICAgLnRvKGJsdXJGaWx0ZXIsIGhhbGYsIHtibHVyOiAuMiwgZWFzZX0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIGNhbWVyYS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0ZsaXBwYWJsZX0gQSByZWZlcmVuY2UgdG8gdGhlIGZsaXBwYWJsZSBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgbGF5b3V0KCkge1xuXG4gICAgICAgIGNvbnN0IGZyb250ID0gdGhpcy5vYmplY3RzLmZyb250XG4gICAgICAgIGNvbnN0IGJhY2sgPSB0aGlzLm9iamVjdHMuYmFja1xuICAgICAgICBjb25zdCBzaGFkb3cgPSB0aGlzLm9iamVjdHMuc2hhZG93XG4gICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5vYmplY3RzLmlubmVyXG4gICAgICAgIFxuICAgICAgICBpbm5lci5wb3NpdGlvbjNkLnogPSAtTWF0aC5zaW4oaW5uZXIuZXVsZXIueSkgKiBmcm9udC50ZXh0dXJlLmJhc2VUZXh0dXJlLndpZHRoICogMlxuXG4gICAgICAgIC8vdGhpcy5vYmplY3RzLnNoYWRvdy5ldWxlciA9IHRoaXMub2JqZWN0cy5pbm5lci5ldWxlclxuICAgICAgICBzaGFkb3cuZXVsZXIueCA9IC1pbm5lci5ldWxlci54XG4gICAgICAgIHNoYWRvdy5ldWxlci55ID0gLWlubmVyLmV1bGVyLnlcbiAgICAgICAgXG4gICAgICAgIGlmICh0aGlzLmZyb250U2lkZUluRnJvbnQpIHtcbiAgICAgICAgICAgIGZyb250LnJlbmRlcmFibGUgPSB0cnVlXG4gICAgICAgICAgICBiYWNrLnJlbmRlcmFibGUgPSBmYWxzZVxuICAgICAgICAgICAgc2hhZG93LndpZHRoID0gZnJvbnQud2lkdGhcbiAgICAgICAgICAgIHNoYWRvdy5oZWlnaHQgPSBmcm9udC5oZWlnaHRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb250LnJlbmRlcmFibGUgPSBmYWxzZVxuICAgICAgICAgICAgYmFjay5yZW5kZXJhYmxlID0gdHJ1ZVxuICAgICAgICAgICAgc2hhZG93LndpZHRoID0gYmFjay53aWR0aFxuICAgICAgICAgICAgc2hhZG93LmhlaWdodCA9IGJhY2suaGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZXMgdGhlIGZsaXBwYWJsZS4gU3dpdGNoZXMgdGhlIHNpZGVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtGbGlwcGFibGV9IEEgcmVmZXJlbmNlIHRvIHRoZSBmbGlwcGFibGUgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHRvZ2dsZSgpIHtcbiAgICAgICAgdGhpcy5mbGlwcGVkID0gIXRoaXMuZmxpcHBlZFxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYWxpZ25tZW50IHN0YXRlLiB0cnVlIGlmIHRoZSBmcm9udCBzaWRlIGlzIGluIGZyb250LCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBmcm9udFNpZGVJbkZyb250KCkge1xuICAgICAgICByZXR1cm4gIXRoaXMub2JqZWN0cy5pbm5lci5pc0Zyb250RmFjZSgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgY2VudGVyIHBvaW50IG9mIGFuIFBJWEkuRGlzcGxheU9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtQSVhJLkRpc3BsYXlPYmplY3R9IGRpc3BsYXlPYmplY3QgLSBUaGUgRGlzcGxheU9iamVjdCBmcm9tIHdoaWNoIHRvIGNhbGN1bGF0ZSB0aGUgY2VudGVyLlxuICAgICAqIEByZXR1cm4ge29iamVjdH0gUmV0dXJuIGFuIG9iamVjdCB3aXRoIHggYW5kIHkuXG4gICAgICovXG4gICAgYW5jaG9yVG9DZW50ZXIoZGlzcGxheU9iamVjdCkge1xuICAgICAgICBjb25zdCBib3VuZHMgPSBkaXNwbGF5T2JqZWN0LmdldEJvdW5kcygpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBib3VuZHMueCArIGJvdW5kcy53aWR0aCAvIDIsXG4gICAgICAgICAgICB5OiBib3VuZHMueSArIGJvdW5kcy5oZWlnaHQgLyAyXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtQSVhJLkRpc3BsYXlPYmplY3R9IGRpc3BsYXlPYmplY3QgLSBUaGUgRGlzcGxheU9iamVjdCBmcm9tIHdoaWNoIHRvIGdlbmVyYXRlIHRoZSB0ZXh0dXJlLlxuICAgICAqIEByZXR1cm4ge1BJWEkuVGV4dHVyZX0gVGhlIGdlbmVyYXRlZCBQSVhJLlRleHR1cmUuXG4gICAgICovXG4gICAgZ2VuZXJhdGVUZXh0dXJlKGRpc3BsYXlPYmplY3QpIHtcblxuICAgICAgICAvLyByZW5kZXJUZXh0dXJlXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgcmVuZGVyVGV4dHVyZSA9IFBJWEkuUmVuZGVyVGV4dHVyZS5jcmVhdGUoZGlzcGxheU9iamVjdC53aWR0aCwgZGlzcGxheU9iamVjdC5oZWlnaHQpXG5cbiAgICAgICAgLy8gc2F2ZSBwb3NpdGlvblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBbZGlzcGxheU9iamVjdC54LCBkaXNwbGF5T2JqZWN0LnksIGRpc3BsYXlPYmplY3Quc2NhbGUueCwgZGlzcGxheU9iamVjdC5zY2FsZS55LCBkaXNwbGF5T2JqZWN0LnJvdGF0aW9uLCBkaXNwbGF5T2JqZWN0LnNrZXcueCwgZGlzcGxheU9iamVjdC5za2V3LnksIGRpc3BsYXlPYmplY3QucGl2b3QueCwgZGlzcGxheU9iamVjdC5waXZvdC55XVxuXG4gICAgICAgIGRpc3BsYXlPYmplY3QucG9zaXRpb24uc2V0KDAsIDApXG4gICAgICAgIGRpc3BsYXlPYmplY3Quc2tldy5zZXQoMCwgMClcbiAgICAgICAgZGlzcGxheU9iamVjdC5yb3RhdGlvbiA9IDBcblxuICAgICAgICAvLyByZW5kZXJcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLm9wdHMucmVuZGVyZXIucmVuZGVyKGRpc3BsYXlPYmplY3QsIHJlbmRlclRleHR1cmUpXG4gICAgICAgIFxuICAgICAgICAvLyByZXN0b3JlIHBvc2l0aW9uXG4gICAgICAgIGRpc3BsYXlPYmplY3Quc2V0VHJhbnNmb3JtKC4uLnRyYW5zZm9ybSlcblxuICAgICAgICByZXR1cm4gcmVuZGVyVGV4dHVyZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZWQgdGhlIGZpcnN0IERpc3BsYXlPYmplY3QgYW5kIGFkZHMgdGhlIHNlY29uZCBvbmUgYXQgdGhlIGV4YWN0bHkgc2FtZSBwb3NpdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtQSVhJLkRpc3BsYXlPYmplY3R9IGZpcnN0IC0gVGhlIG9sZCBEaXNwbGF5T2JqZWN0LlxuICAgICAqIEBwYXJhbSB7UElYSS5EaXNwbGF5T2JqZWN0fSBzZWNvbmQgLSBUaGUgbmV3IERpc3BsYXlPYmplY3QuXG4gICAgICogQHJldHVybiB7RmxpcHBhYmxlfSBBIHJlZmVyZW5jZSB0byB0aGUgZmxpcHBhYmxlIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzd2l0Y2hEaXNwbGF5T2JqZWN0KGZpcnN0LCBzZWNvbmQpIHtcbiAgICAgICAgaWYgKGZpcnN0ICYmIHNlY29uZCAmJiBmaXJzdC5wYXJlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IGZpcnN0LnBhcmVudFxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwYXJlbnQuZ2V0Q2hpbGRJbmRleChmaXJzdClcbiAgICAgICAgICAgIHBhcmVudC5hZGRDaGlsZEF0KHNlY29uZCwgaW5kZXgpXG4gICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZmlyc3QpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cbiIsIi8qKlxuICogXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvcG92ZXIgZXh0ZW5kcyBQSVhJLkdyYXBoaWNzIHtcblxuICAgIGNvbnN0cnVjdG9yKHt0aXRsZSA9IG51bGwsIHRleHQgPSBudWxsLCB4ID0gMCwgeSA9IDAsIHBsYWNlbWVudCA9ICd0b3AnLCB3aWR0aCA9IDI1MCwgdGl0bGVTdHlsZSA9IHt9LCB0ZXh0U3R5bGUgPSB7Zm9udFNpemU6ICcxLjZlbSd9fSA9IHt9KSB7XG4gICAgICAgIHN1cGVyKClcblxuICAgICAgICB0aGlzLm9wdHMgPSB7dGl0bGUsIHRleHQsIHgsIHksIHBsYWNlbWVudCwgd2lkdGgsIHRpdGxlU3R5bGUsIHRleHRTdHlsZX1cbiAgICAgICAgXG4gICAgICAgIHRoaXMucGFkZGluZyA9IDEyXG5cbiAgICAgICAgbGV0IHN0eWxlID0ge1xuICAgICAgICAgICAgZm9udEZhbWlseTogJ0FyaWFsJyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMmVtJyxcbiAgICAgICAgICAgIHN0cm9rZTogJyNmNmY2ZjYnLFxuICAgICAgICAgICAgc3Ryb2tlVGhpY2tuZXNzOiAzLFxuICAgICAgICAgICAgd29yZFdyYXA6IHRydWUsXG4gICAgICAgICAgICB3b3JkV3JhcFdpZHRoOiB3aWR0aCAtICh0aGlzLnBhZGRpbmcgKiAyKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50aXRsZVRleHRTdHlsZSA9IG5ldyBQSVhJLlRleHRTdHlsZShPYmplY3QuYXNzaWduKHt9LCBzdHlsZSwgdGl0bGVTdHlsZSkpXG4gICAgICAgIHRoaXMudGV4dFRleHRTdHlsZSA9IG5ldyBQSVhJLlRleHRTdHlsZShPYmplY3QuYXNzaWduKHt9LCBzdHlsZSwgdGV4dFN0eWxlKSlcbiAgICAgICAgXG4gICAgICAgIGlmICh0aXRsZSB8fCB0ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwKClcbiAgICAgICAgICAgIHRoaXMuZHJhdygpXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldHVwKCkge1xuICAgICAgICB0aGlzLnJlbW92ZUNoaWxkcmVuKClcblxuICAgICAgICBpZiAodGhpcy5vcHRzLnRpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLnRpdGxlVGV4dCA9IG5ldyBQSVhJLlRleHQodGhpcy5vcHRzLnRpdGxlLCB0aGlzLnRpdGxlVGV4dFN0eWxlKVxuICAgICAgICAgICAgdGhpcy50aXRsZVRleHQucG9zaXRpb24uc2V0KHRoaXMucGFkZGluZywgdGhpcy5wYWRkaW5nKVxuICAgICAgICAgICAgdGhpcy5hZGRDaGlsZCh0aGlzLnRpdGxlVGV4dClcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudGl0bGVZID0gdGhpcy50aXRsZVRleHQgPyB0aGlzLnRpdGxlVGV4dC55IDogMFxuICAgICAgICB0aGlzLnRpdGxlSGVpZ2h0ID0gdGhpcy50aXRsZVRleHQgPyB0aGlzLnRpdGxlVGV4dC5oZWlnaHQgOiAwXG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy50ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLnRleHRUZXh0ID0gbmV3IFBJWEkuVGV4dCh0aGlzLm9wdHMudGV4dCwgdGhpcy50ZXh0VGV4dFN0eWxlKVxuICAgICAgICAgICAgdGhpcy50ZXh0VGV4dC5wb3NpdGlvbi5zZXQodGhpcy5wYWRkaW5nLCB0aGlzLnRpdGxlWSArIHRoaXMudGl0bGVIZWlnaHQgKyB0aGlzLnBhZGRpbmcpXG4gICAgICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMudGV4dFRleHQpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRleHRZID0gdGhpcy50ZXh0VGV4dCA/IHRoaXMudGV4dFRleHQueSA6IDBcbiAgICAgICAgdGhpcy50ZXh0SGVpZ2h0ID0gdGhpcy50ZXh0VGV4dCA/IHRoaXMudGV4dFRleHQuaGVpZ2h0IDogMFxuICAgIH1cblxuICAgIGNsb3NlKCkge1xuICAgICAgICB0aGlzLnBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKVxuICAgIH1cblxuICAgIGRyYXcoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKVxuICAgICAgICB0aGlzLmJlZ2luRmlsbCgweGZmZmZmZiwgMSlcbiAgICAgICAgdGhpcy5saW5lU3R5bGUoMSwgMHgyODI4MjgsIC41KVxuXG4gICAgICAgIC8vIERyYXcgcm91bmRlZCByZWN0YW5nbGVcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyB0aGlzLnBhZGRpbmdcbiAgICAgICAgdGhpcy5kcmF3Um91bmRlZFJlY3QoMCwgMCwgdGhpcy5vcHRzLndpZHRoLCBoZWlnaHQsIDgpXG5cbiAgICAgICAgLy8gRHJhdyBhbmNob3JcbiAgICAgICAgdGhpcy5kcmF3QW5jaG9yKHRoaXMub3B0cy5wbGFjZW1lbnQpXG5cbiAgICAgICAgLy8gRHJhdyB0aXRsZSBiYWNrZ3JvdW5kXG4gICAgICAgIGlmICh0aGlzLm9wdHMudGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMubGluZVN0eWxlKDApXG4gICAgICAgICAgICB0aGlzLmJlZ2luRmlsbCgweGY3ZjdmNywgMSlcbiAgICAgICAgICAgIGxldCB4ID0gMVxuICAgICAgICAgICAgbGV0IHkgPSB0aGlzLnRpdGxlVGV4dC54ICsgdGhpcy50aXRsZVRleHQuaGVpZ2h0ICsgKHRoaXMucGFkZGluZyAvIDIpXG4gICAgICAgICAgICB0aGlzLm1vdmVUbyh4LCB5KVxuICAgICAgICAgICAgeSA9IDlcbiAgICAgICAgICAgIHRoaXMubGluZVRvKHgsIHkpXG4gICAgICAgICAgICB0aGlzLnF1YWRyYXRpY0N1cnZlVG8oeCwgeSAtIDgsIHggKyA4LCB5IC0gOClcbiAgICAgICAgICAgIHggKz0gdGhpcy5vcHRzLndpZHRoIC0gN1xuICAgICAgICAgICAgeSAtPSA4XG4gICAgICAgICAgICB0aGlzLmxpbmVUbyh4LCB5KVxuICAgICAgICAgICAgdGhpcy5xdWFkcmF0aWNDdXJ2ZVRvKHggKyA1LCB5LCB4ICsgNSwgeSArIDgpXG4gICAgICAgICAgICB4ICs9IDVcbiAgICAgICAgICAgIHkgKz0gdGhpcy50aXRsZVRleHQueCArIHRoaXMudGl0bGVUZXh0LmhlaWdodCArICh0aGlzLnBhZGRpbmcgLyAyKVxuICAgICAgICAgICAgdGhpcy5saW5lVG8oeCwgeSlcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMudGV4dCkge1xuICAgICAgICAgICAgICAgIHggPSAxXG4gICAgICAgICAgICAgICAgdGhpcy5saW5lVG8oeCwgeSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHksIHggLSA1LCB5ICsgNClcbiAgICAgICAgICAgICAgICB4ID0gNlxuICAgICAgICAgICAgICAgIHkgKz0gNFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVRvKHgsIHkpXG4gICAgICAgICAgICAgICAgdGhpcy5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHksIHggLSA1LCB5IC0gNClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW5kRmlsbCgpXG4gICAgfVxuXG4gICAgZHJhd0FuY2hvcihwbGFjZW1lbnQpIHtcblxuICAgICAgICBsZXQgeCA9IDBcbiAgICAgICAgbGV0IHkgPSAwXG5cbiAgICAgICAgc3dpdGNoIChwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy50aXRsZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJlZ2luRmlsbCgweGY3ZjdmNywgMSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgeCA9ICh0aGlzLndpZHRoIC8gMikgLSAxMFxuICAgICAgICAgICAgICAgIHkgPSAxXG4gICAgICAgICAgICAgICAgdGhpcy5tb3ZlVG8oeCwgeSlcbiAgICAgICAgICAgICAgICB4ICs9IDEwXG4gICAgICAgICAgICAgICAgeSAtPSAxMFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVRvKHgsIHkpXG4gICAgICAgICAgICAgICAgeCArPSAxMFxuICAgICAgICAgICAgICAgIHkgKz0gMTBcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVUbyh4LCB5KVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgeCA9IDFcbiAgICAgICAgICAgICAgICB5ID0gKHRoaXMuaGVpZ2h0IC8gMikgLSAxMFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRpdGxlWSArIHRoaXMudGl0bGVIZWlnaHQgPiB5KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmVnaW5GaWxsKDB4ZjdmN2Y3LCAxKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1vdmVUbyh4LCB5KVxuICAgICAgICAgICAgICAgIHggLT0gMTBcbiAgICAgICAgICAgICAgICB5ICs9IDEwXG4gICAgICAgICAgICAgICAgdGhpcy5saW5lVG8oeCwgeSlcbiAgICAgICAgICAgICAgICB4ICs9IDEwXG4gICAgICAgICAgICAgICAgeSArPSAxMFxuICAgICAgICAgICAgICAgIHRoaXMubGluZVRvKHgsIHkpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgICAgICAgIHggPSB0aGlzLndpZHRoIC0gMlxuICAgICAgICAgICAgICAgIHkgPSAodGhpcy5oZWlnaHQgLyAyKSAtIDEwXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudGl0bGVZICsgdGhpcy50aXRsZUhlaWdodCA+IHkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iZWdpbkZpbGwoMHhmN2Y3ZjcsIDEpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubW92ZVRvKHgsIHkpXG4gICAgICAgICAgICAgICAgeCArPSAxMFxuICAgICAgICAgICAgICAgIHkgKz0gMTBcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVUbyh4LCB5KVxuICAgICAgICAgICAgICAgIHggLT0gMTBcbiAgICAgICAgICAgICAgICB5ICs9IDEwXG4gICAgICAgICAgICAgICAgdGhpcy5saW5lVG8oeCwgeSlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB4ID0gKHRoaXMud2lkdGggLyAyKSAtIDEwXG4gICAgICAgICAgICAgICAgeSA9IHRoaXMuaGVpZ2h0IC0gMlxuICAgICAgICAgICAgICAgIHRoaXMubW92ZVRvKHgsIHkpXG4gICAgICAgICAgICAgICAgeCArPSAxMFxuICAgICAgICAgICAgICAgIHkgKz0gMTBcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVUbyh4LCB5KVxuICAgICAgICAgICAgICAgIHggKz0gMTBcbiAgICAgICAgICAgICAgICB5IC09IDEwXG4gICAgICAgICAgICAgICAgdGhpcy5saW5lVG8oeCwgeSlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcG9zaXRpb25pbmcoKSB7XG5cbiAgICAgICAgY29uc3QgeCA9IHRoaXMub3B0cy54XG4gICAgICAgIGNvbnN0IHkgPSB0aGlzLm9wdHMueVxuXG4gICAgICAgIHN3aXRjaCAodGhpcy5vcHRzLnBsYWNlbWVudCkge1xuICAgICAgICAgICAgY2FzZSAnYm90dG9tJzpcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uLnNldCh4IC0gKHRoaXMud2lkdGggLyAyKSwgeSArIDEwKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbi5zZXQoeCwgeSAtICh0aGlzLmhlaWdodCAvIDIpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uLnNldCh4IC0gdGhpcy53aWR0aCwgeSAtICh0aGlzLmhlaWdodCAvIDIpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24uc2V0KHggLSAodGhpcy53aWR0aCAvIDIpLCB5IC0gdGhpcy5oZWlnaHQpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCBFdmVudHMgZnJvbSAnLi4vZXZlbnRzLmpzJ1xuaW1wb3J0IHsgQWJzdHJhY3RTY2F0dGVyIH0gZnJvbSAnLi4vc2NhdHRlci5qcydcbmltcG9ydCB7IEFuZ2xlLCBQb2ludHMsIFBvbHlnb24gfSBmcm9tICcuLi91dGlscy5qcydcbmltcG9ydCB7IEludGVyYWN0aW9uTWFwcGVyIH0gZnJvbSAnLi4vaW50ZXJhY3Rpb24uanMnXG5cbi8qKiBBIGNvbnRhaW5lciBmb3Igc2NhdHRlciBvYmplY3RzLCB3aGljaCB1c2VzIGEgc2luZ2xlIEludGVyYWN0aW9uTWFwcGVyXG4gKiBmb3IgYWxsIGNoaWxkcmVuLiBUaGlzIHJlZHVjZXMgdGhlIG51bWJlciBvZiByZWdpc3RlcmVkIGV2ZW50IGhhbmRsZXJzXG4gKiBhbmQgY292ZXJzIHRoZSBjb21tb24gdXNlIGNhc2UgdGhhdCBtdWx0aXBsZSBvYmplY3RzIGFyZSBzY2F0dGVyZWRcbiAqIG9uIHRoZSBzYW1lIGxldmVsLlxuICovXG5leHBvcnQgY2xhc3MgU2NhdHRlckNvbnRhaW5lciBleHRlbmRzIFBJWEkuR3JhcGhpY3Mge1xuXG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7UElYSS5SZW5kZXJlcn0gcmVuZGVyZXIgLSBQSVhJIHJlbmRlcmVyLCBuZWVkZWQgZm9yIGhpdCB0ZXN0aW5nXG4gICAgKiBAcGFyYW0ge0Jvb2x9IHN0b3BFdmVudHMgLSBXaGV0aGVyIGV2ZW50cyBzaG91bGQgYmUgc3RvcHBlZCBvciBwcm9wYWdhdGVkXG4gICAgKiBAcGFyYW0ge0Jvb2x9IGNsYWltRXZlbnRzIC0gV2hldGhlciBldmVudHMgc2hvdWxkIGJlIG1hcmtlZCBhcyBjbGFpbWVkXG4gICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmluZFRhcmdldCByZXR1cm4gYXMgbm9uLW51bGwgdmFsdWUuXG4gICAgKiBAcGFyYW0ge1BJWEkuQ29udGFpbmVyfSBjb250YWluZXIgLSBBIGNvbnRhaW5lciBmb3IgdGhlIHNjYXR0ZXJcbiAgICAqIEBwYXJhbSB7Qm9vbH0gc2hvd0JvdW5kcyAtIFNob3cgYm91bmRzIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuXG4gICAgKiBAcGFyYW0ge0Jvb2x9IHNob3dUb3VjaGVzIC0gU2hvdyB0b3VjaGVzIGFuZCBwb2ludGVyIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuXG4gICAgKiBAcGFyYW0ge0NvbG9yfSBiYWNrZ3JvdW5kQ29sb3IgLSBTZXQgYmFja2dyb3VuZCBjb2xvciBpZiBzcGVjaWZpZWQuXG4gICAgKiBAcGFyYW0ge1BJWElBcHB9IGFwcCAtIE5lZWRlZCBpZiBzaG93Qm91bmRzIGlzIHRydWUgdG8gcmVnaXN0ZXJcbiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUgaGFuZGxlci5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHJlbmRlcmVyLCB7XG4gICAgICAgIHN0b3BFdmVudHMgPSB0cnVlLFxuICAgICAgICBjbGFpbUV2ZW50cyA9IHRydWUsXG4gICAgICAgIGNvbnRhaW5lciA9IG51bGwsXG4gICAgICAgIHNob3dCb3VuZHMgPSBmYWxzZSxcbiAgICAgICAgc2hvd1BvbHlnb24gPSBmYWxzZSxcbiAgICAgICAgc2hvd1RvdWNoZXMgPSBmYWxzZSxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yID0gbnVsbCxcbiAgICAgICAgYXBwID0gd2luZG93LmFwcFxuICAgIH0gPSB7fSkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyXG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lcilcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyRGltZW5zaW9ucyA9IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLmNvbnRhaW5lci53aWR0aCxcbiAgICAgICAgICAgICAgICB5OiB0aGlzLmNvbnRhaW5lci5oZWlnaHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kV2lkdGggPSBudWxsXG4gICAgICAgIHRoaXMuYmFja2dyb3VuZEhlaWdodCA9IG51bGxcbiAgICAgICAgdGhpcy5hcHAgPSBhcHBcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyXG4gICAgICAgIHRoaXMuc3RvcEV2ZW50cyA9IHN0b3BFdmVudHNcbiAgICAgICAgdGhpcy5jbGFpbUV2ZW50cyA9IGNsYWltRXZlbnRzXG4gICAgICAgIHRoaXMuZGVsZWdhdGUgPSBuZXcgSW50ZXJhY3Rpb25NYXBwZXIodGhpcy5ldmVudFJlY2VpdmVyLCB0aGlzKVxuICAgICAgICB0aGlzLnNob3dCb3VuZHMgPSBzaG93Qm91bmRzXG4gICAgICAgIHRoaXMuc2hvd1RvdWNoZXMgPSBzaG93VG91Y2hlc1xuICAgICAgICB0aGlzLnNob3dQb2x5Z29uID0gc2hvd1BvbHlnb25cbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ29sb3IgPSBiYWNrZ3JvdW5kQ29sb3JcbiAgICAgICAgaWYgKHNob3dCb3VuZHMgfHwgc2hvd1RvdWNoZXMgfHwgc2hvd1BvbHlnb24pIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJTaG93IFRPVUNIRVMhISFcIilcbiAgICAgICAgICAgIHRoaXMuYXBwLnRpY2tlci5hZGQoKGRlbHRhKSA9PiB0aGlzLnVwZGF0ZShkZWx0YSksIHRoaXMpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJhY2tncm91bmRDb2xvcikge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVCYWNrZ3JvdW5kKClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZUJhY2tncm91bmQoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKVxuICAgICAgICBsZXQgcmVjdCA9IHRoaXMuYm91bmRzXG4gICAgICAgIHRoaXMuYmVnaW5GaWxsKHRoaXMuYmFja2dyb3VuZENvbG9yLCAxKVxuICAgICAgICB0aGlzLmRyYXdSZWN0KDAsIDAsIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KVxuICAgICAgICB0aGlzLmVuZEZpbGwoKVxuICAgIH1cblxuICAgIGdldCBldmVudFJlY2VpdmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5wbHVnaW5zLmludGVyYWN0aW9uLmludGVyYWN0aW9uRE9NRWxlbWVudFxuICAgIH1cblxuICAgIGdldCBib3VuZHMoKSB7XG4gICAgICAgIGxldCB4ID0gMFxuICAgICAgICBsZXQgeSA9IDBcbiAgICAgICAgLy8gQGNvbnRhaW5lcjogV2UgbmVlZCB0byBjYWxsIHRoZSBjb25zdGFudCB2YWx1ZXMsIGFzIHRoZSBjb250YWluZXJcbiAgICAgICAgLy8gZ2V0cyByZXNpemVkLCB3aGVuIGEgY2hpbGQgbW92ZXMgb3V0c2lkZSB0aGUgb3JpZ2luYWwgYm91bmRhcmllcy5cbiAgICAgICAgbGV0IHcgPSAodGhpcy5jb250YWluZXIpID8gdGhpcy5jb250YWluZXJEaW1lbnNpb25zLnggOiAodGhpcy5iYWNrZ3JvdW5kV2lkdGggfHwgdGhpcy5hcHAud2lkdGgpXG4gICAgICAgIGxldCBoID0gKHRoaXMuY29udGFpbmVyKSA/IHRoaXMuY29udGFpbmVyRGltZW5zaW9ucy55IDogKHRoaXMuYmFja2dyb3VuZEhlaWdodCB8fCB0aGlzLmFwcC5oZWlnaHQpXG5cbiAgICAgICAgaWYgKHRoaXMuYXBwLmZ1bGxzY3JlZW4gJiYgdGhpcy5hcHAubW9ua2V5UGF0Y2hNYXBwaW5nKSB7XG4gICAgICAgICAgICBsZXQgZml4ZWQgPSB0aGlzLm1hcFBvc2l0aW9uVG9Qb2ludCh7IHg6IHcsIHk6IDAgfSlcbiAgICAgICAgICAgIGlmIChmaXhlZC54IDwgdykge1xuICAgICAgICAgICAgICAgIHcgPSBmaXhlZC54XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZml4ZWQueSA+IDApIHtcbiAgICAgICAgICAgICAgICB5ICs9IGZpeGVkLnlcbiAgICAgICAgICAgICAgICBoIC09IGZpeGVkLnlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFBJWEkuUmVjdGFuZ2xlKHgsIHksIHcsIGgpXG4gICAgfVxuXG4gICAgZ2V0IGNlbnRlcigpIHtcbiAgICAgICAgbGV0IHIgPSB0aGlzLmJvdW5kc1xuICAgICAgICByZXR1cm4geyB4OiByLndpZHRoIC8gMiwgeTogci5oZWlnaHQgLyAyIH1cbiAgICB9XG5cbiAgICBnZXQgcG9seWdvbigpIHtcbiAgICAgICAgbGV0IHIgPSB0aGlzLmJvdW5kc1xuICAgICAgICBsZXQgdzIgPSByLndpZHRoIC8gMlxuICAgICAgICBsZXQgaDIgPSByLmhlaWdodCAvIDJcbiAgICAgICAgbGV0IGNlbnRlciA9IHsgeDogdzIsIHk6IGgyIH1cbiAgICAgICAgbGV0IHBvbHlnb24gPSBuZXcgUG9seWdvbihjZW50ZXIpXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiAtdzIsIHk6IC1oMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogdzIsIHk6IC1oMiB9KVxuICAgICAgICBwb2x5Z29uLmFkZFBvaW50KHsgeDogdzIsIHk6IGgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiAtdzIsIHk6IGgyIH0pXG4gICAgICAgIHJldHVybiBwb2x5Z29uXG4gICAgfVxuXG4gICAgdXBkYXRlKGR0KSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKVxuICAgICAgICB0aGlzLmxpbmVTdHlsZSgxLCAweDAwMDBGRilcbiAgICAgICAgaWYgKHRoaXMuc2hvd0JvdW5kcykge1xuICAgICAgICAgICAgZm9yIChsZXQgY2hpbGQgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5zY2F0dGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vbGV0IHt4LCB5LCB3aWR0aCwgaGVpZ2h0fSA9IGNoaWxkLnNjYXR0ZXIudGhyb3dCb3VuZHMoKVxuICAgICAgICAgICAgICAgICAgICAvLyBuZXcgUElYSS5SZWN0YW5nbGUoeCwgeSwgd2lkdGgsIGhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3U2hhcGUoY2hpbGQuc2NhdHRlci5ib3VuZHMpXG4gICAgICAgICAgICAgICAgICAgIGxldCBjZW50ZXIgPSBjaGlsZC5zY2F0dGVyLmNlbnRlclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdDaXJjbGUoY2VudGVyLngsIGNlbnRlci55LCA0KVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdDaXJjbGUoY2hpbGQuc2NhdHRlci54LCBjaGlsZC5zY2F0dGVyLnksIDQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5saW5lU3R5bGUoMiwgMHgwMDAwRkYpXG4gICAgICAgICAgICB0aGlzLmRyYXdTaGFwZSh0aGlzLmJvdW5kcylcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zaG93UG9seWdvbikge1xuICAgICAgICAgICAgdGhpcy5saW5lU3R5bGUoMiwgMHhGRjAwMDApXG4gICAgICAgICAgICBmb3IgKGxldCBjaGlsZCBvZiB0aGlzLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkLnNjYXR0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBvbHlnb24gPSBjaGlsZC5zY2F0dGVyLnBvbHlnb25cbiAgICAgICAgICAgICAgICAgICAgbGV0IHNoYXBlID0gbmV3IFBJWEkuUG9seWdvbihwb2x5Z29uLmZsYXRBYnNvbHV0ZVBvaW50cygpKVxuICAgICAgICAgICAgICAgICAgICBzaGFwZS5jbG9zZSgpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1NoYXBlKHNoYXBlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zaG93VG91Y2hlcykge1xuICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLmRlbGVnYXRlLmludGVyYWN0aW9uLmN1cnJlbnRcbiAgICAgICAgICAgIGZvciAobGV0IFtrZXksIHBvaW50XSBvZiBjdXJyZW50LmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgIGxldCBsb2NhbCA9IHRoaXMubWFwUG9zaXRpb25Ub1BvaW50KHBvaW50KVxuICAgICAgICAgICAgICAgIHRoaXMuZHJhd0NpcmNsZShsb2NhbC54LCBsb2NhbC55LCAxMilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RvcEV2ZW50cylcbiAgICAgICAgICAgIEV2ZW50cy5zdG9wKGV2ZW50KVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGZha2VJbnRlcmFjdGlvbkV2ZW50KHBvaW50LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHsgZGF0YTogeyBnbG9iYWw6IHBvaW50LCBrZXk6IGtleSB9IH1cbiAgICB9XG5cbiAgICBmaW5kSGl0U2NhdHRlcihkYXRhLCBkaXNwbGF5T2JqZWN0LCBoaXQpIHtcbiAgICAgICAgLy8gICAgIGlmIChoaXQpIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgY29uc29sZS5sb2coXCJmaW5kSGl0U2NhdHRlclwiLCBkaXNwbGF5T2JqZWN0KVxuICAgICAgICAvLyAgICAgICAgIH1cbiAgICAgICAgaWYgKGhpdCAmJiB0aGlzLmhpdFNjYXR0ZXIgPT09IG51bGwgJiYgdHlwZW9mIChkaXNwbGF5T2JqZWN0KSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaGl0U2NhdHRlciA9IChkaXNwbGF5T2JqZWN0LnNjYXR0ZXIpID8gZGlzcGxheU9iamVjdC5zY2F0dGVyIDogbnVsbFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbWFwUG9zaXRpb25Ub1BvaW50KHBvaW50LCBlbGVtZW50ID0gbnVsbCkge1xuICAgICAgICAvLyBJbiBjYXNlIG9mIG5lc3RlZCBzY2F0dGVycyB3ZSBnZXQgYW4gYWRkaXRpb25hbCBwYXJhbWV0ZXIgdGhhdFxuICAgICAgICAvLyBjb250YWlucyB0aGUgZm91bmQgc2NhdHRlclxuICAgICAgICBsZXQgbG9jYWwgPSBuZXcgUElYSS5Qb2ludCgpXG4gICAgICAgIGxldCBpbnRlcmFjdGlvbk1hbmFnZXIgPSB0aGlzLnJlbmRlcmVyLnBsdWdpbnMuaW50ZXJhY3Rpb25cbiAgICAgICAgaW50ZXJhY3Rpb25NYW5hZ2VyLm1hcFBvc2l0aW9uVG9Qb2ludChsb2NhbCwgcG9pbnQueCwgcG9pbnQueSlcbiAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBEaXNwbGF5T2JqZWN0U2NhdHRlciAmJiBlbGVtZW50LmRpc3BsYXlPYmplY3QucGFyZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmRpc3BsYXlPYmplY3QucGFyZW50LnRvTG9jYWwobG9jYWwpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxvY2FsXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTmV3IG1ldGhvZCBoaXRUZXN0IGltcGxlbWVudGVkIChpbiBJbnRlcmFjdGlvbk1hbmFnZXIsIHNpbmNlIDQuNS4wKS5cbiAgICAgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3BpeGlqcy9waXhpLmpzL3B1bGwvMzg3OFxuICAgICAqL1xuICAgIGZpbmRUYXJnZXQoZXZlbnQsIGxvY2FsLCBnbG9iYWwpIHtcbiAgICAgICAgaWYgKGV2ZW50LmNsYWltZWRCeVNjYXR0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5oaXRTY2F0dGVyID0gbnVsbFxuICAgICAgICBsZXQgaW50ZXJhY3Rpb25NYW5hZ2VyID0gdGhpcy5yZW5kZXJlci5wbHVnaW5zLmludGVyYWN0aW9uXG4gICAgICAgIGxldCBmYWtlRXZlbnQgPSB0aGlzLmZha2VJbnRlcmFjdGlvbkV2ZW50KGxvY2FsKVxuICAgICAgICBpbnRlcmFjdGlvbk1hbmFnZXIucHJvY2Vzc0ludGVyYWN0aXZlKGZha2VFdmVudCxcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICB0aGlzLmZpbmRIaXRTY2F0dGVyLmJpbmQodGhpcyksIHRydWUpXG4gICAgICAgIGlmICh0aGlzLmNsYWltRXZlbnRzKVxuICAgICAgICAgICAgZXZlbnQuY2xhaW1lZEJ5U2NhdHRlciA9IHRoaXMuaGl0U2NhdHRlclxuICAgICAgICByZXR1cm4gdGhpcy5oaXRTY2F0dGVyXG4gICAgfVxuXG4gICAgZmluZFRhcmdldE5ldyhldmVudCwgbG9jYWwsIGdsb2JhbCkge1xuICAgICAgICAvLyBVTzogc3RpbGwgcHJvYmxlbWF0aWMuIERvZXMgbm90IGZpbmQgbm9uIGludGVyYWN0aXZlIGVsZW1lbnRzXG4gICAgICAgIC8vIHdoaWNoIGFyZSBuZWVkZWQgZm9yIHNvbWUgc3R5bHVzIGFwcGxpY2F0aW9uc1xuICAgICAgICBpZiAoZXZlbnQuY2xhaW1lZEJ5U2NhdHRlcikge1xuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhpdFNjYXR0ZXIgPSBudWxsXG4gICAgICAgIGxldCBpbnRlcmFjdGlvbk1hbmFnZXIgPSB0aGlzLnJlbmRlcmVyLnBsdWdpbnMuaW50ZXJhY3Rpb25cbiAgICAgICAgbGV0IGRpc3BsYXlPYmplY3QgPSBpbnRlcmFjdGlvbk1hbmFnZXIuaGl0VGVzdChsb2NhbCwgdGhpcylcbiAgICAgICAgaWYgKGRpc3BsYXlPYmplY3QgIT0gbnVsbCAmJiBkaXNwbGF5T2JqZWN0LnNjYXR0ZXIgIT0gbnVsbClcbiAgICAgICAgICAgIHRoaXMuaGl0U2NhdHRlciA9IGRpc3BsYXlPYmplY3Quc2NhdHRlclxuICAgICAgICBpZiAodGhpcy5jbGFpbUV2ZW50cylcbiAgICAgICAgICAgIGV2ZW50LmNsYWltZWRCeVNjYXR0ZXIgPSB0aGlzLmhpdFNjYXR0ZXJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGl0U2NhdHRlclxuICAgIH1cblxuXG4gICAgb25TdGFydChldmVudCwgaW50ZXJhY3Rpb24pIHtcblxuICAgIH1cblxuICAgIG9uTW92ZShldmVudCwgaW50ZXJhY3Rpb24pIHtcblxuICAgIH1cblxuICAgIG9uRW5kKGV2ZW50LCBpbnRlcmFjdGlvbikge1xuICAgICAgICBmb3IgKGxldCBrZXkgb2YgaW50ZXJhY3Rpb24uZW5kZWQua2V5cygpKSB7XG4gICAgICAgICAgICBsZXQgcG9pbnQgPSBpbnRlcmFjdGlvbi5lbmRlZC5nZXQoa2V5KVxuICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uLmlzTG9uZ1ByZXNzKGtleSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uTG9uZ1ByZXNzKGtleSwgcG9pbnQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW50ZXJhY3Rpb24uaXNUYXAoa2V5KSkge1xuICAgICAgICAgICAgICAgIHRoaXMub25UYXAoa2V5LCBwb2ludClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVGFwKGtleSwgcG9pbnQpIHtcbiAgICAgICAgY29uc29sZS5pbmZvKCdTY2F0dGVyQ29udGFpbmVyLm9uVGFwJylcbiAgICB9XG5cbiAgICBvbkxvbmdQcmVzcyhrZXksIHBvaW50KSB7XG4gICAgICAgIGNvbnNvbGUuaW5mbygnU2NhdHRlckNvbnRhaW5lci5vbkxvbmdQcmVzcycpXG4gICAgfVxuXG4gICAgYnJpbmdUb0Zyb250KGRpc3BsYXlPYmplY3QpIHtcbiAgICAgICAgdGhpcy5hZGRDaGlsZChkaXNwbGF5T2JqZWN0KVxuICAgIH1cblxuICAgIGxheW91dCh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuYmFja2dyb3VuZFdpZHRoID0gd2lkdGhcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kSGVpZ2h0ID0gaGVpZ2h0XG4gICAgICAgIGlmICh0aGlzLmJhY2tncm91bmRDb2xvcikge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVCYWNrZ3JvdW5kKClcbiAgICAgICAgfVxuICAgICAgICBcbiAgICB9XG59XG5cbi8qKiBBIHdyYXBwZXIgZm9yIGNoaWxkIGVsZW1lbnRzIG9mIGEgU2NhdHRlckNvbnRhaW5lci4gQ2FuIGJlIHVzZWRcbiAqICB0byBjb21iaW5lIHNjYXR0ZXJlZCBvYmplY3RzIHdpdGggbm9uLXNjYXR0ZXJlZCBvYmplY3RzLiBBbnlcbiAqICBQSVhJLkRpc3BsYXlPYmplY3QgY2FuIGJlIHdyYXBwZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEaXNwbGF5T2JqZWN0U2NhdHRlciBleHRlbmRzIEFic3RyYWN0U2NhdHRlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihkaXNwbGF5T2JqZWN0LCByZW5kZXJlcixcbiAgICAgICAgeyB4ID0gbnVsbCwgeSA9IG51bGwsXG4gICAgICAgICAgICBtaW5TY2FsZSA9IDAuMSxcbiAgICAgICAgICAgIG1heFNjYWxlID0gMS4wLFxuICAgICAgICAgICAgc3RhcnRTY2FsZSA9IDEuMCxcbiAgICAgICAgICAgIGF1dG9CcmluZ1RvRnJvbnQgPSB0cnVlLFxuICAgICAgICAgICAgdHJhbnNsYXRhYmxlID0gdHJ1ZSwgc2NhbGFibGUgPSB0cnVlLCByb3RhdGFibGUgPSB0cnVlLCByZXNpemFibGUgPSBmYWxzZSxcbiAgICAgICAgICAgIG1vdmFibGVYID0gdHJ1ZSxcbiAgICAgICAgICAgIG1vdmFibGVZID0gdHJ1ZSxcbiAgICAgICAgICAgIHRocm93VmlzaWJpbGl0eSA9IDQ0LFxuICAgICAgICAgICAgdGhyb3dEYW1waW5nID0gMC45NSxcbiAgICAgICAgICAgIGF1dG9UaHJvdyA9IHRydWUsXG4gICAgICAgICAgICByb3RhdGlvbkRlZ3JlZXMgPSBudWxsLFxuICAgICAgICAgICAgcm90YXRpb24gPSBudWxsLFxuICAgICAgICAgICAgb3ZlcmRvU2NhbGluZyA9IDEuNSxcbiAgICAgICAgICAgIG9uVHJhbnNmb3JtID0gbnVsbCxcbiAgICAgICAgICAgIG9uVGhyb3dGaW5pc2hlZCA9IG51bGwgfSA9IHt9KSB7XG4gICAgICAgIC8vIEZvciB0aGUgc2ltdWxhdGlvbiBvZiBuYW1lZCBwYXJhbWV0ZXJzLFxuICAgICAgICAvLyBzZWU6IGh0dHA6Ly9leHBsb3Jpbmdqcy5jb20vZXM2L2NoX3BhcmFtZXRlci1oYW5kbGluZy5odG1sXG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIG92ZXJkb1NjYWxpbmcsXG4gICAgICAgICAgICBtaW5TY2FsZSwgbWF4U2NhbGUsXG4gICAgICAgICAgICBzdGFydFNjYWxlLFxuICAgICAgICAgICAgYXV0b0JyaW5nVG9Gcm9udCxcbiAgICAgICAgICAgIHRyYW5zbGF0YWJsZSwgc2NhbGFibGUsIHJvdGF0YWJsZSwgcmVzaXphYmxlLFxuICAgICAgICAgICAgbW92YWJsZVgsIG1vdmFibGVZLCB0aHJvd1Zpc2liaWxpdHksIHRocm93RGFtcGluZyxcbiAgICAgICAgICAgIGF1dG9UaHJvdyxcbiAgICAgICAgICAgIG9uVGhyb3dGaW5pc2hlZCxcbiAgICAgICAgICAgIHJvdGF0aW9uRGVncmVlcywgcm90YXRpb24sXG4gICAgICAgICAgICBvblRyYW5zZm9ybVxuICAgICAgICB9KVxuICAgICAgICB0aGlzLmRpc3BsYXlPYmplY3QgPSBkaXNwbGF5T2JqZWN0XG4gICAgICAgIHRoaXMuZGlzcGxheU9iamVjdC5zY2F0dGVyID0gdGhpc1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJcbiAgICAgICAgdGhpcy5zY2FsZSA9IHN0YXJ0U2NhbGVcbiAgICAgICAgdGhpcy5yb3RhdGlvbkRlZ3JlZXMgPSB0aGlzLnN0YXJ0Um90YXRpb25EZWdyZWVzXG5cbiAgICAgICAgLy8gT25seSBzZXQgeCBhbmQgeSBpZiB0aGV5IGFyZSBzcGVjaWZpZWQuXG4gICAgICAgIC8vIE90aGVyd2lzZSB0aGUgZGlzcGxheW9iamVjdCBnZXRzIGNvcnJ1cHRlZC5cbiAgICAgICAgaWYgKHggIT0gbnVsbCkgdGhpcy54ID0geFxuICAgICAgICBpZiAoeSAhPSBudWxsKSB0aGlzLnkgPSB5XG4gICAgfVxuXG4gICAgZ2V0V29ybGRTY2F0dGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIGdlb21ldHJ5IGRhdGEgYXMgb2JqZWN0LiAqKi9cbiAgICBnZXRTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNjYWxlOiB0aGlzLnNjYWxlLFxuICAgICAgICAgICAgeDogdGhpcy54LFxuICAgICAgICAgICAgeTogdGhpcy55LFxuICAgICAgICAgICAgcm90YXRpb246IHRoaXMucm90YXRpb25cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldHVwKCkge1xuICAgICAgICB0aGlzLnNldHVwTW91c2VXaGVlbEludGVyYWN0aW9uKClcbiAgICB9XG5cbiAgICByb3VuZFBpeGVsKHZhbHVlKSB7XG4gICAgICAgIC8vIFVPOiBTaG91bGQgYmUgb2Jzb2xldGUgYmVjYXVzZSBSZW5kZXJlciBzdXBwb3J0cyByb3VuZFBpeGVscyBieSBkZWZhdWx0XG4gICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICBsZXQgcmVzID0gdGhpcy5yZW5kZXJlci5yZXNvbHV0aW9uXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogcmVzKSAvIHJlc1xuICAgIH1cblxuICAgIGdldCBjb250YWluZXIoKSB7XG4gICAgICAgIC8vIHJldHVybiB0aGlzLmRpc3BsYXlPYmplY3QucGFyZW50XG4gICAgICAgIGxldCBvYmogPSB0aGlzLmRpc3BsYXlPYmplY3RcbiAgICAgICAgd2hpbGUgKG9iai5wYXJlbnQgIT0gbnVsbCAmJiAhKG9iai5wYXJlbnQgaW5zdGFuY2VvZiBTY2F0dGVyQ29udGFpbmVyKSlcbiAgICAgICAgICAgIG9iaiA9IG9iai5wYXJlbnRcbiAgICAgICAgcmV0dXJuIG9iai5wYXJlbnRcbiAgICB9XG5cbiAgICBnZXQgeCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24ueFxuICAgIH1cblxuICAgIHNldCB4KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb24ueCA9IHZhbHVlXG4gICAgfVxuXG4gICAgZ2V0IHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uLnlcbiAgICB9XG5cbiAgICBzZXQgeSh2YWx1ZSkge1xuICAgICAgICB0aGlzLnBvc2l0aW9uLnkgPSB2YWx1ZVxuICAgIH1cblxuICAgIGdldCBwb2x5Z29uKCkge1xuICAgICAgICBsZXQgcG9seWdvbiA9IG5ldyBQb2x5Z29uKHRoaXMuY2VudGVyKVxuICAgICAgICBsZXQgdzIgPSB0aGlzLndpZHRoIC8gMlxuICAgICAgICBsZXQgaDIgPSB0aGlzLmhlaWdodCAvIDJcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IC13MiwgeTogLWgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiB3MiwgeTogLWgyIH0pXG4gICAgICAgIHBvbHlnb24uYWRkUG9pbnQoeyB4OiB3MiwgeTogaDIgfSlcbiAgICAgICAgcG9seWdvbi5hZGRQb2ludCh7IHg6IC13MiwgeTogaDIgfSlcbiAgICAgICAgcG9seWdvbi5yb3RhdGUodGhpcy5yb3RhdGlvbilcbiAgICAgICAgcmV0dXJuIHBvbHlnb25cbiAgICB9XG5cbiAgICBnZXQgY29udGFpbmVyQm91bmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXIuYm91bmRzXG4gICAgfVxuXG4gICAgZ2V0IGNvbnRhaW5lclBvbHlnb24oKSB7XG4gICAgICAgIGxldCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lclxuICAgICAgICBpZiAoY29udGFpbmVyID09IG51bGwpIHJldHVybiBudWxsXG4gICAgICAgIHJldHVybiBjb250YWluZXIucG9seWdvblxuICAgIH1cblxuICAgIGdldCBwb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC5wb3NpdGlvblxuICAgIH1cblxuICAgIHNldCBwb3NpdGlvbih2YWx1ZSkge1xuICAgICAgICB0aGlzLmRpc3BsYXlPYmplY3QucG9zaXRpb24gPSB2YWx1ZVxuICAgIH1cblxuICAgIGdldCBzY2FsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC5zY2FsZS54XG4gICAgfVxuXG4gICAgc2V0IHNjYWxlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuZGlzcGxheU9iamVjdC5zY2FsZS54ID0gdmFsdWVcbiAgICAgICAgdGhpcy5kaXNwbGF5T2JqZWN0LnNjYWxlLnkgPSB2YWx1ZVxuICAgIH1cblxuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC53aWR0aFxuICAgIH1cblxuICAgIGdldCBoZWlnaHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpc3BsYXlPYmplY3QuaGVpZ2h0XG4gICAgfVxuXG4gICAgZ2V0IGJvdW5kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC5nZXRCb3VuZHMoKVxuICAgIH1cblxuICAgIGdldCBwaXZvdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC5waXZvdFxuICAgIH1cblxuICAgIGdldCByb3RhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheU9iamVjdC5yb3RhdGlvblxuICAgIH1cblxuICAgIHNldCByb3RhdGlvbih2YWx1ZSkge1xuICAgICAgICB0aGlzLmRpc3BsYXlPYmplY3Qucm90YXRpb24gPSB2YWx1ZVxuICAgIH1cblxuICAgIGdldCByb3RhdGlvbkRlZ3JlZXMoKSB7XG4gICAgICAgIHJldHVybiBBbmdsZS5yYWRpYW4yZGVncmVlKHRoaXMuZGlzcGxheU9iamVjdC5yb3RhdGlvbilcbiAgICB9XG5cbiAgICBzZXQgcm90YXRpb25EZWdyZWVzKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuZGlzcGxheU9iamVjdC5yb3RhdGlvbiA9IEFuZ2xlLmRlZ3JlZTJyYWRpYW4odmFsdWUpXG4gICAgfVxuXG4gICAgZ2V0IGNlbnRlcigpIHtcbiAgICAgICAgbGV0IHcyID0gdGhpcy53aWR0aCAvIDJcbiAgICAgICAgbGV0IGgyID0gdGhpcy5oZWlnaHQgLyAyXG4gICAgICAgIGxldCBkaXN0ID0gTWF0aC5zcXJ0KHcyICogdzIgKyBoMiAqIGgyKVxuICAgICAgICBsZXQgYW5nbGUgPSBQb2ludHMuYW5nbGUoeyB4OiB3MiwgeTogaDIgfSwgeyB4OiAwLCB5OiAwIH0pXG4gICAgICAgIGxldCBwID0gdGhpcy5kaXNwbGF5T2JqZWN0LnhcbiAgICAgICAgbGV0IGMgPSBQb2ludHMuYXJjKHRoaXMucG9zaXRpb24sIHRoaXMucm90YXRpb24gKyBhbmdsZSwgZGlzdClcbiAgICAgICAgcmV0dXJuIGMgLy8gUG9pbnRzLnN1YnRyYWN0KGMsIHRoaXMucGl2b3QpXG4gICAgfVxuXG4gICAgZ2V0IHJvdGF0aW9uT3JpZ2luKCkge1xuICAgICAgICAvLyBJbiBQSVhJIHRoZSBkZWZhdWx0IHJvdGF0aW9uIGFuZCBzY2FsZSBvcmlnaW4gaXMgdGhlIHBvc2l0aW9uXG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uIC8vIFBvaW50cy5hZGQodGhpcy5wb3NpdGlvbiwgdGhpcy5waXZvdClcbiAgICB9XG5cbiAgICBtYXBQb3NpdGlvblRvQ29udGFpbmVyUG9pbnQocG9pbnQpIHtcbiAgICAgICAgLy8gVU86IFdlIG5lZWQgdGhlIGNvb3JkaW5hdGVzIHJlbGF0ZWQgdG8gdGhpcyBzY2F0dGVyIGluIGNhc2VcbiAgICAgICAgLy8gb2YgbmVzdGVkIHNjYXR0ZXJzXG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lciAhPSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyLm1hcFBvc2l0aW9uVG9Qb2ludChwb2ludCwgdGhpcylcbiAgICAgICAgcmV0dXJuIHBvaW50XG4gICAgfVxuXG4gICAgY2FwdHVyZShldmVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGJyaW5nVG9Gcm9udCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXV0b0JyaW5nVG9Gcm9udCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU9iamVjdC5wYXJlbnQgaW5zdGFuY2VvZiBTY2F0dGVyQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgbGV0IHNjYXR0ZXJDb250YWluZXIgPSB0aGlzLmRpc3BsYXlPYmplY3QucGFyZW50XG4gICAgICAgICAgICAgICAgc2NhdHRlckNvbnRhaW5lci5icmluZ1RvRnJvbnQodGhpcy5kaXNwbGF5T2JqZWN0KVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRpc3BsYXlPYmplY3QucGFyZW50ICE9IG51bGwgJiYgdGhpcy5kaXNwbGF5T2JqZWN0LnBhcmVudC5zY2F0dGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5T2JqZWN0LnBhcmVudC5zY2F0dGVyLnRvRnJvbnQodGhpcy5kaXNwbGF5T2JqZWN0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG9Gcm9udChkaXNwbGF5T2JqZWN0KSB7XG4gICAgICAgIHRoaXMuZGlzcGxheU9iamVjdC5hZGRDaGlsZChkaXNwbGF5T2JqZWN0KVxuICAgIH1cblxuICAgIHZhbGlkU2NhbGUoc2NhbGUpIHtcbiAgICAgICAgc2NhbGUgPSBNYXRoLm1heChzY2FsZSwgdGhpcy5taW5TY2FsZSlcbiAgICAgICAgc2NhbGUgPSBNYXRoLm1pbihzY2FsZSwgdGhpcy5tYXhTY2FsZSlcbiAgICAgICAgcmV0dXJuIHNjYWxlXG4gICAgfVxufVxuIiwiaW1wb3J0IFBJWElBcHAgZnJvbSAnLi9hcHAuanMnXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBDb21tYW5kIGV4dGVuZHMgUElYSS5HcmFwaGljcyB7XG4gICAgLyoqKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciByZWNvcmQsIHBsYXksIGFuZCBzdG9wIGNvbW1hbmRzLiAqKiovXG4gICAgY29uc3RydWN0b3IodG9vbHMsIHNlbGVjdGVkQ29sb3IsIHNoYXBlKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy50b29scyA9IHRvb2xzXG4gICAgICAgIHRoaXMuc2hhcGUgPSBzaGFwZVxuICAgICAgICB0aGlzLnNlbGVjdGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGZhbHNlXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDb2xvciA9IHNlbGVjdGVkQ29sb3JcbiAgICAgICAgdGhpcy5kcmF3KClcbiAgICAgICAgdGhpcy5zZXR1cCgpXG4gICAgfVxuXG4gICAgc2V0dXAoKSB7XG4gICAgfVxuXG4gICAgZHJhdygpIHtcbiAgICAgICAgdGhpcy5jbGVhcigpXG4gICAgICAgIHZhciBjb2xvciA9ICh0aGlzLnNlbGVjdGVkKSA/IHRoaXMuc2VsZWN0ZWRDb2xvciA6IDB4RkZGRkZGXG4gICAgICAgIHRoaXMubGluZVN0eWxlKDApXG4gICAgICAgIHRoaXMuYmVnaW5GaWxsKGNvbG9yLCAxKVxuICAgICAgICB0aGlzLmRyYXdTaGFwZSh0aGlzLnNoYXBlKVxuICAgICAgICB0aGlzLmVuZEZpbGwoKVxuICAgIH1cblxuICAgIHNlbGVjdCgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZCA9IHRydWVcbiAgICAgICAgdGhpcy5kcmF3KClcbiAgICB9XG5cbiAgICBkZXNlbGVjdCgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZCA9IGZhbHNlXG4gICAgICAgIHRoaXMuZHJhdygpXG4gICAgfVxuXG4gICAgdG9nZ2xlKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gIXRoaXMuc2VsZWN0ZWRcbiAgICAgICAgdGhpcy5kcmF3KClcbiAgICB9XG5cbiAgICBzdG9wKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy5kcmF3KClcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBSZWNvcmRDb21tYW5kIGV4dGVuZHMgQ29tbWFuZCB7XG4gICAgLyoqKiBSZWNvcmRzIGV2ZW50cyBmb3IgbGF0ZXIgcmVwbGF5LiAqKiovXG4gICAgc2V0dXAoKSB7XG4gICAgICAgIHRoaXMucmVjb3JkZXIgPSBuZXcgRXZlbnRSZWNvcmRlcigpXG4gICAgfVxuXG4gICAgdG9nZ2xlKCkge1xuICAgICAgICBzdXBlci50b2dnbGUoKVxuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkZXIuc3RvcFJlY29yZGluZygpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZWNvcmRFdmVudChldmVudCkge1xuICAgICAgICB0aGlzLnJlY29yZGVyLnJlY29yZChldmVudClcbiAgICB9XG5cbiAgICBub3JtYWxpemUodmFsdWUsIGxpbWl0KSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAvIGxpbWl0XG4gICAgfVxuXG4gICAgbm9ybWFsaXplWCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemUodmFsdWUsIHdpbmRvdy5pbm5lcldpZHRoKVxuICAgIH1cblxuICAgIG5vcm1hbGl6ZVkodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplKHZhbHVlLCB3aW5kb3cuaW5uZXJIZWlnaHQpXG4gICAgfVxuXG4gICAgd2hpbGVOb3RTdG9wcGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b29scy5wbGF5LnNlbGVjdGVkXG4gICAgfVxuXG4gICAgc3RhcnRSZXBsYXkoKSB7XG4gICAgICAgIGxldCB3aGlsZUNvbmRpdGlvbiA9IHRoaXMud2hpbGVOb3RTdG9wcGVkLmJpbmQodGhpcylcbiAgICAgICAgdGhpcy5yZWNvcmRlci5zdGFydFJlcGxheSh3aGlsZUNvbmRpdGlvbiwgKCkgPT4gdGhpcy50b29scy5wbGF5LnN0b3AoKSlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQbGF5Q29tbWFuZCBleHRlbmRzIENvbW1hbmQge1xuICAgIC8qKiogUGxheXMgcmVjb3JkZWQgZXZlbnRzLiAqKiovXG4gICAgdG9nZ2xlKCkge1xuICAgICAgICBzdXBlci50b2dnbGUoKVxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZCAmJiB0aGlzLnRvb2xzLnJlY29yZC5yZWNvcmRlci5yZWNvcmRlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnRvb2xzLnN0YXJ0UmVwbGF5KClcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFN0b3BDb21tYW5kIGV4dGVuZHMgQ29tbWFuZCB7XG4gICAgLyoqKiBTdG9wcyByZWNvcmRpbmcgYW5kIHBsYXlpbmcuICoqKi9cbiAgICB0b2dnbGUoKSB7XG4gICAgICAgIHN1cGVyLnRvZ2dsZSgpXG4gICAgICAgIHRoaXMudG9vbHMucmVjb3JkLnN0b3AoKVxuICAgICAgICB0aGlzLnRvb2xzLnBsYXkuc3RvcCgpXG4gICAgICAgIHNldFRpbWVvdXQodGhpcy5kZXNlbGVjdC5iaW5kKHRoaXMpLCA1MDApXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVjb3JkZXJUb29scyBleHRlbmRzIFBJWEkuQ29udGFpbmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHJlbmRlcmVyKSB7XG4gICAgICAgIHN1cGVyKHJlbmRlcmVyKVxuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJcbiAgICAgICAgdGhpcy5zZXR1cFRvb2xiYXIoKVxuICAgICAgICB0aGlzLnJlcGxheVJhdGUgPSAxMDAuMFxuICAgICAgICB0aGlzLm9uUmVzZXQgPSBudWxsXG4gICAgICAgIHRoaXMudG91Y2hHcmFwaGljcyA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgdGhpcy5zaG93VG91Y2hlcygpXG4gICAgfVxuXG4gICAgc2V0dXAoY29udGFpbmVyKSB7XG4gICAgICAgIC8vIFNpbmNlIHRoaXMgZGVsZWdhdGUgbWlnaHQgc2hhZG93IGFub3RoZXIgZGVsZWdhdGUsIHdlIG11cyBhdm9pZFxuICAgICAgICAvLyBjYXB0dXJpbmcgUG9pbnRlckV2ZW50cy5cbiAgICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG5ldyBJbnRlcmFjdGlvbk1hcHBlcihjb250YWluZXIsIHRoaXMsIHsgY2FwdHVyZVBvaW50ZXJFdmVudHM6IGZhbHNlIH0pXG4gICAgfVxuXG4gICAgZmluZFRhcmdldChldmVudCwgbG9jYWwsIGdsb2JhbCkge1xuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHNldHVwVG9vbGJhcigpIHtcbiAgICAgICAgdGhpcy50b29sYmFyID0gbmV3IFBJWEkuR3JhcGhpY3MoKVxuICAgICAgICB0aGlzLnJlY29yZCA9IG5ldyBSZWNvcmRDb21tYW5kKHRoaXMsIDB4Q0MwMDAwLCBuZXcgUElYSS5DaXJjbGUoMCwgMCwgMTYpKVxuICAgICAgICB0aGlzLnBsYXkgPSBuZXcgUGxheUNvbW1hbmQodGhpcywgMHgwMDAwQ0MsIG5ldyBQSVhJLlBvbHlnb24oMCwgMTYsXG4gICAgICAgICAgICAzMiwgMTYgKyAxNixcbiAgICAgICAgICAgIDAsIDE2ICsgMzIsXG4gICAgICAgICAgICAwLCAxNikpXG4gICAgICAgIHRoaXMuc3RvcCA9IG5ldyBTdG9wQ29tbWFuZCh0aGlzLCAweDAwMDBDQyxcbiAgICAgICAgICAgIG5ldyBQSVhJLlJlY3RhbmdsZSgwLCAwLCAzMiwgMzIpKVxuICAgICAgICB0aGlzLnRvb2xiYXIuYWRkQ2hpbGQodGhpcy5yZWNvcmQpLnBvc2l0aW9uLnNldCg0NCwgNDgpXG4gICAgICAgIHRoaXMudG9vbGJhci5hZGRDaGlsZCh0aGlzLnBsYXkpLnBvc2l0aW9uLnNldCg0NCArIDQ0LCAxNilcbiAgICAgICAgdGhpcy50b29sYmFyLmFkZENoaWxkKHRoaXMuc3RvcCkucG9zaXRpb24uc2V0KDQ0ICsgNDQgKyA0NCArIDE2LCAzMilcbiAgICAgICAgdGhpcy51cGRhdGVUb29sYmFyKClcbiAgICAgICAgdGhpcy5hZGRDaGlsZCh0aGlzLnRvb2xiYXIpXG4gICAgfVxuXG4gICAgdXBkYXRlVG9vbGJhcigpIHtcbiAgICAgICAgdmFyIGdyYXBoaWNzID0gdGhpcy50b29sYmFyXG4gICAgICAgIGdyYXBoaWNzLmNsZWFyKClcbiAgICAgICAgZ3JhcGhpY3MuYmVnaW5GaWxsKDB4MDAwMDAwLCAwLjUpXG4gICAgICAgIGdyYXBoaWNzLmxpbmVTdHlsZSgyLCAweEZGRkZGRiwgMSlcbiAgICAgICAgZ3JhcGhpY3MuZHJhd1JvdW5kZWRSZWN0KDE2LCAxNiwgNDQgKiA0ICsgOCwgNjQsIDgpXG4gICAgICAgIGdyYXBoaWNzLmVuZEZpbGwoKVxuICAgIH1cblxuICAgIG9uTW91c2VXaGVlbChldmVudCkge1xuICAgICAgICBjb25zb2xlLmxvZygnb25Nb3VzZVdoZWVsIG1pc3NpbmcnKVxuICAgIH1cblxuICAgIG9uUHJlc3MocG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMucmVjb3JkLmNvbnRhaW5zUG9pbnQocG9pbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnJlY29yZC50b2dnbGUoKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBsYXkuY29udGFpbnNQb2ludChwb2ludCkpIHtcbiAgICAgICAgICAgIHRoaXMucGxheS50b2dnbGUoKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0b3AuY29udGFpbnNQb2ludChwb2ludCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcC50b2dnbGUoKVxuICAgICAgICAgICAgaWYgKHRoaXMub25SZXNldCkge1xuICAgICAgICAgICAgICAgIHRoaXMub25SZXNldCgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtYXBQb3NpdGlvblRvUG9pbnQocG9pbnQpIHtcbiAgICAgICAgbGV0IGxvY2FsID0gbmV3IFBJWEkuUG9pbnQoKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLnBsdWdpbnMuaW50ZXJhY3Rpb24ubWFwUG9zaXRpb25Ub1BvaW50KGxvY2FsLCBwb2ludC54LCBwb2ludC55KVxuICAgICAgICByZXR1cm4gbG9jYWxcbiAgICB9XG5cbiAgICBleHRyYWN0TG9jYWwoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwUG9zaXRpb25Ub1BvaW50KEV2ZW50cy5leHRyYWN0UG9pbnQoZXZlbnQpKVxuICAgIH1cblxuICAgIGNhcHR1cmUoZXZlbnQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudC5tb3VzZURvd25TdWJzdGl0dXRlICE9ICd1bmRlZmluZWQnKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgc3RhcnRSZXBsYXkoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uUmVzZXQpIHtcbiAgICAgICAgICAgIHRoaXMub25SZXNldCgpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWNvcmQuc3RhcnRSZXBsYXkoKVxuICAgIH1cblxuICAgIHNob3dUb3VjaGVzKCkge1xuICAgICAgICB0aGlzLmFkZENoaWxkKHRoaXMudG91Y2hHcmFwaGljcylcbiAgICB9XG5cbiAgICByZWNvcmRFdmVudChldmVudCkge1xuICAgICAgICBpZiAodGhpcy5yZWNvcmQuc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkLnJlY29yZEV2ZW50KGV2ZW50KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25TdGFydChldmVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgbGV0IGxvY2FsID0gdGhpcy5leHRyYWN0TG9jYWwoZXZlbnQpXG4gICAgICAgIGlmICghdGhpcy50b29sYmFyLmNvbnRhaW5zUG9pbnQobG9jYWwpKSB7XG4gICAgICAgICAgICB0aGlzLnJlY29yZEV2ZW50KGV2ZW50KVxuICAgICAgICAgICAgdGhpcy51cGRhdGVUb3VjaEdyYXBoaWNzKGludGVyYWN0aW9uKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3ZlKGV2ZW50LCBpbnRlcmFjdGlvbikge1xuICAgICAgICBsZXQgbG9jYWwgPSB0aGlzLmV4dHJhY3RMb2NhbChldmVudClcbiAgICAgICAgaWYgKCF0aGlzLnRvb2xiYXIuY29udGFpbnNQb2ludChsb2NhbCkpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkRXZlbnQoZXZlbnQpXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVRvdWNoR3JhcGhpY3MoaW50ZXJhY3Rpb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkVuZChldmVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgbGV0IGxvY2FsID0gdGhpcy5leHRyYWN0TG9jYWwoZXZlbnQpXG4gICAgICAgIGlmICh0aGlzLnRvb2xiYXIuY29udGFpbnNQb2ludChsb2NhbCkpIHtcbiAgICAgICAgICAgIHRoaXMub25QcmVzcyhsb2NhbClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkRXZlbnQoZXZlbnQpXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVRvdWNoR3JhcGhpY3MoaW50ZXJhY3Rpb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVUb3VjaEdyYXBoaWNzKGludGVyYWN0aW9uKSB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gaW50ZXJhY3Rpb24uY3VycmVudFxuICAgICAgICBsZXQgZ3JhcGhpY3MgPSB0aGlzLnRvdWNoR3JhcGhpY3NcbiAgICAgICAgaWYgKGdyYXBoaWNzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGdyYXBoaWNzLmNsZWFyKClcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBvZiBjdXJyZW50LmtleXMoKSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi5lbmRlZC5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgcCA9IGN1cnJlbnQuZ2V0KGtleSlcbiAgICAgICAgICAgICAgICBpZiAoa2V5ID09ICdtb3VzZScpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JhcGhpY3MuYmVnaW5GaWxsKDB4Q0MwMDAwLCAwLjUpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JhcGhpY3MuYmVnaW5GaWxsKDB4Q0NDQ0NDLCAwLjUpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGdyYXBoaWNzLmRyYXdDaXJjbGUocC54LCBwLnksIDIwKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ3JhcGhpY3MuZW5kRmlsbCgpXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcHBUZXN0IGV4dGVuZHMgUElYSUFwcCB7XG5cbiAgICBjb25zdHJ1Y3RvcihjYW52YXMsIGNvbnRhaW5lcikge1xuICAgICAgICBzdXBlcih7IHZpZXc6IGNhbnZhcywgYmFja2dyb3VuZENvbG9yOiAweDAwMDAwMCB9KVxuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lclxuICAgIH1cblxuICAgIHNjZW5lRmFjdG9yeSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWNvcmRlclRvb2xzKHRoaXMucmVuZGVyZXIpXG4gICAgfVxuXG4gICAgc2V0dXAoKSB7XG4gICAgICAgIHN1cGVyLnNldHVwKClcbiAgICAgICAgdGhpcy5zY2VuZS5zZXR1cCh0aGlzLmNvbnRhaW5lcilcbiAgICB9XG5cbiAgICBydW4ocmVzZXQgPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2NlbmUub25SZXNldCA9IHJlc2V0XG4gICAgICAgIGNvbnNvbGUubG9nKCdSdW5uaW5nIEFwcFRlc3QnKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cblxuXG5cblxuIiwiXG5cbi8qKlxuICogRGVmaW5lcyB1c2VmdWxsIGRlZmF1bHQgdGV4dCBzdHlsZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBGb250SW5mbyB7XG5cbiAgICBzdGF0aWMgZ2V0IHNtYWxsKCkge1xuICAgICAgICByZXR1cm4gYXBwLnRoZW1lLnRleHRTdHlsZVNtYWxsXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCBub3JtYWwoKSB7XG4gICAgICAgIHJldHVybiBhcHAudGhlbWUudGV4dFN0eWxlXG4gICAgfVxuXG4gICAgc3RhdGljIGdldCBjZW50ZXJlZCgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGFwcC50aGVtZS50ZXh0U3R5bGUsIHsgYWxpZ246ICdjZW50ZXInIH0pXG4gICAgfVxufVxuXG4vKipcbiAqIFN0YXRpYyBtZXRob2RzIHRvIHN1cHBvcnQgaHlwaGVuYXRpb24gb2YgbGluZXMuXG4gKiBcbiAqIEBjbGFzcyBIeXBlbmF0ZVxuICovXG5leHBvcnQgY2xhc3MgSHlwZW5hdGUge1xuXG4gICAgc3RhdGljIHNwbGl0UGFydChwYXJ0KSB7XG4gICAgICAgIGxldCBwYXJ0cyA9IHBhcnQuc3BsaXQoJy0nKVxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID09IDEpXG4gICAgICAgICAgICByZXR1cm4gW3BhcnRdXG4gICAgICAgIGxldCByZXN1bHQgPSBbXVxuICAgICAgICBsZXQgbGFzdCA9IHBhcnRzLnBvcCgpXG4gICAgICAgIGZvciAobGV0IHAgb2YgcGFydHMpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHAgKyAnLScpXG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnB1c2gobGFzdClcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5maWx0ZXIocCA9PiBwLmxlbmd0aCA+IDApXG4gICAgfVxuXG4gICAgc3RhdGljIHNwbGl0V29yZCh3b3JkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgKGxhbmd1YWdlKSA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgaWYgKHdvcmQuaW5kZXhPZignLScpID4gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gd29yZC5zcGxpdCgnLScpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gW3dvcmRdXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhcnRzID0gbGFuZ3VhZ2UuaHlwaGVuYXRlKHdvcmQpXG4gICAgICAgIGxldCByZXN1bHQgPSBbXVxuICAgICAgICBmb3IgKGxldCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBzcGxpdHRlZCBvZiB0aGlzLnNwbGl0UGFydChwYXJ0KSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHNwbGl0dGVkKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICBzdGF0aWMgYWJicmV2aWF0ZUxpbmUobGFiZWwsIHN0eWxlLCB3aWR0aCkge1xuICAgICAgICBjb25zdCBwaXhpU3R5bGUgPSBuZXcgUElYSS5UZXh0U3R5bGUoc3R5bGUpICAgXG4gICAgICAgIGxldCBtZXRyaWNzID0gUElYSS5UZXh0TWV0cmljcy5tZWFzdXJlVGV4dChsYWJlbCwgcGl4aVN0eWxlKVxuICAgICAgICB3aGlsZShtZXRyaWNzLndpZHRoID4gd2lkdGggJiYgbGFiZWwubGVuZ3RoID4gMykge1xuICAgICAgICAgICAgbGFiZWwgPSBsYWJlbC5zbGljZSgwLCBsYWJlbC5sZW5ndGgtMSlcbiAgICAgICAgICAgIG1ldHJpY3MgPSBQSVhJLlRleHRNZXRyaWNzLm1lYXN1cmVUZXh0KGxhYmVsLCBwaXhpU3R5bGUpXG4gICAgICAgIH1cbiAgICAgICAgbGFiZWwgPSBsYWJlbC5zbGljZSgwLCBsYWJlbC5sZW5ndGgtMSlcbiAgICAgICAgcmV0dXJuIGxhYmVsICsgJ+KApidcbiAgICB9XG5cbiAgICBzdGF0aWMgc3BsaXRMaW5lKGxpbmUsIHBpeGlTdHlsZSwgd2lkdGgsIHNwYWNlLCBtaW51cykge1xuICAgICAgICBsZXQgeCA9IDBcbiAgICAgICAgbGV0IHJlc3VsdCA9ICcnXG4gICAgICAgIGxldCB3b3JkcyA9IGxpbmUuc3BsaXQoJyAnKVxuICAgICAgICBmb3IgKGxldCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAgICAgICBsZXQgd29yZE1ldHJpY3MgPSBQSVhJLlRleHRNZXRyaWNzLm1lYXN1cmVUZXh0KHdvcmQsIHBpeGlTdHlsZSlcbiAgICAgICAgICAgIGlmICh4ICsgd29yZE1ldHJpY3Mud2lkdGggPj0gd2lkdGgpIHtcbiAgICAgICAgICAgICAgICBsZXQgcGFydHMgPSB0aGlzLnNwbGl0V29yZCh3b3JkKVxuICAgICAgICAgICAgICAgIGxldCBuZXdXb3JkID0gJydcbiAgICAgICAgICAgICAgICBpZiAocGFydHMubGVuZ3RoID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V29yZCArPSAnXFxuJyArIHdvcmQgKyAnICdcbiAgICAgICAgICAgICAgICAgICAgeCA9IHdvcmRNZXRyaWNzLndpZHRoICsgc3BhY2Uud2lkdGhcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxhc3RQYXJ0ID0gJydcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBhcnRNZXRyaWNzID0gUElYSS5UZXh0TWV0cmljcy5tZWFzdXJlVGV4dChwYXJ0LCBwaXhpU3R5bGUpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoeCArIHBhcnRNZXRyaWNzLndpZHRoICsgc3BhY2Uud2lkdGggPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1dvcmQgKz0gKChmaXJzdCB8fCBsYXN0UGFydC5lbmRzV2l0aCgnLScpKSA/ICdcXG4nIDogJy1cXG4nKSArIHBhcnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gcGFydE1ldHJpY3Mud2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1dvcmQgKz0gcGFydFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gcGFydE1ldHJpY3Mud2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYXJ0ID0gcGFydFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHggKz0gc3BhY2Uud2lkdGhcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IG5ld1dvcmQgKyAnICdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSB3b3JkICsgJyAnXG4gICAgICAgICAgICAgICAgeCArPSB3b3JkTWV0cmljcy53aWR0aCArIHNwYWNlLndpZHRoXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqICBNYWluIG1ldGhvZCBhbmQgZW50cnkgcG9pbnQgZm9yIHRleHQgaHlwaGVuYXRpb24gXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHsqfSB0ZXh0XG4gICAgICogQHBhcmFtIHsqfSBzdHlsZVxuICAgICAqIEBwYXJhbSB7Kn0gd2lkdGhcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqIEBtZW1iZXJvZiBIeXBlbmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBzcGxpdExpbmVzKHRleHQsIHN0eWxlLCB3aWR0aCkge1xuICAgICAgICBjb25zdCBwaXhpU3R5bGUgPSBuZXcgUElYSS5UZXh0U3R5bGUoc3R5bGUpXG4gICAgICAgIGNvbnN0IGxpbmVzID0gdGV4dC5zcGxpdCgnXFxuJylcbiAgICAgICAgY29uc3Qgc3BhY2UgPSBQSVhJLlRleHRNZXRyaWNzLm1lYXN1cmVUZXh0KCcgJywgcGl4aVN0eWxlKVxuICAgICAgICBjb25zdCBtaW51cyA9IFBJWEkuVGV4dE1ldHJpY3MubWVhc3VyZVRleHQoJy0nLCBwaXhpU3R5bGUpXG4gICAgICAgIGxldCByZXN1bHQgPSBbXVxuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh0aGlzLnNwbGl0TGluZShsaW5lLCBwaXhpU3R5bGUsIHdpZHRoLCBzcGFjZSwgbWludXMpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQuam9pbignXFxuJylcbiAgICB9XG59XG5cbi8qKlxuICogQSBzcGVjaWFsaXphdGlvbiBvZiB0aGUgUElYSS5HcmFwaGljcyBjbGFzcyB0aGF0IGFsbG93cyB0b1xuICogcmVzdXNlIGFuZCBwbGFjZSBsYWJlbHMgYWNyb3NzIGRpZmZlcmVudCBsYXlvdXQgdmFyaWFudHNcbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgTGFiZWxlZEdyYXBoaWNzXG4gKiBAZXh0ZW5kcyB7UElYSS5HcmFwaGljc31cbiAqL1xuZXhwb3J0IGNsYXNzIExhYmVsZWRHcmFwaGljcyBleHRlbmRzIFBJWEkuR3JhcGhpY3Mge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMYWJlbGVkR3JhcGhpY3MgYW5kIGRlZmluZXMgYSBsb2NhbCBsYWJlbCBjYWNoZS5cbiAgICAgKiBcbiAgICAgKiBAbWVtYmVyb2YgTGFiZWxlZEdyYXBoaWNzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgdGhpcy5sYWJlbHMgPSBuZXcgTWFwKClcbiAgICB9XG5cbiAgICBfY3JlYXRlVGV4dChsYWJlbCwgZm9udEluZm8pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQSVhJLlRleHQobGFiZWwsIGZvbnRJbmZvKVxuICAgIH1cblxuICAgIFxuICAgIC8qKlxuICAgICAqIE1haW4gYWRkaXRpb25hbCBtZXRob2QuIEVuc3VyZXMgdGhhdCBhIHRleHQgb2JqZWN0IGlzIGNyZWF0ZWQgdGhhdCBpcyBjYWNoZWRcbiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4ga2V5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBrZXkgLSBUaGUgY2FjaGUga2V5XG4gICAgICogQHBhcmFtIHsqfSBsYWJlbCAtIFRoZSBsYWJlbCB0byBzaG93XG4gICAgICogQHBhcmFtIHsqfSBbYXR0cnM9e31dIC0gRGVmaW5lcyBhdHRyaWJ1dGVzIG9mIHRoZSB0ZXh0IG9iamVjdC4gXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ246ICdyaWdodCcsICdsZWZ0Jywgb3IgJ2NlbnRlcidcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqdXN0aWZ5OiAndG9wJywgJ2JvdHRvbScsIG9yICdjZW50ZXInXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4TGluZXM6IHtpbnRlZ2VyfSB0cnVuY2F0ZXMgdGhlIHRleHQgYW5kIGFkZHMgZWxsaXBzaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IHtudW1iZXJ9IHRydW5jYXRlcyB0ZXh0IHRoYXQgbmVlZHMgbW9yZSBzcGFjZSBhbmQgYWRkcyBlbGxpcHNpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFdpZHRoOiB7bnVtYmVyfSB3b3JkIHdyYXBzIHRleHQgdXNpbmcgaHlwaGVuYXRpb24gaWYgcG9zc2libGVcbiAgICAgKiBAcGFyYW0geyp9IFtmb250SW5mbz1Gb250SW5mby5ub3JtYWxdIC0gRGVmaW5lcyBQSVhJLlRleHRTdHlsZSBhdHRyaWJ1dGVzXG4gICAgICogQHJldHVybnMge1BJWEkuVGV4dH0gaW5zdGFuY2VcbiAgICAgKiBAbWVtYmVyb2YgTGFiZWxlZEdyYXBoaWNzXG4gICAgICovXG4gICAgZW5zdXJlTGFiZWwoa2V5LCBsYWJlbCwgYXR0cnMgPSB7fSwgZm9udEluZm8gPSBGb250SW5mby5ub3JtYWwpIHtcblxuICAgICAgICBpZiAoYXR0cnMubWF4V2lkdGggJiYgYXR0cnMubWF4TGluZXMgPT0gMSkge1xuICAgICAgICAgICAgbGFiZWwgPSBIeXBlbmF0ZS5hYmJyZXZpYXRlTGluZShsYWJlbCwgZm9udEluZm8sIGF0dHJzLm1heFdpZHRoKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGF0dHJzLm1heFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSBIeXBlbmF0ZS5zcGxpdExpbmVzKGxhYmVsLCBmb250SW5mbywgYXR0cnMubWF4V2lkdGgpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYXR0cnMubWF4TGluZXMpIHtcbiAgICAgICAgICAgICAgICBsYWJlbCA9IHRoaXMudHJ1bmNhdGVMYWJlbChsYWJlbCwgZm9udEluZm8sIGF0dHJzLm1heExpbmVzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGF0dHJzLm1heEhlaWdodCkge1xuICAgICAgICAgICAgICAgIGxldCBzdHlsZUluZm8gPSBuZXcgUElYSS5UZXh0U3R5bGUoZm9udEluZm8pXG4gICAgICAgICAgICAgICAgbGV0IG1ldHJpY3MgPSBQSVhJLlRleHRNZXRyaWNzLm1lYXN1cmVUZXh0KGxhYmVsLCBzdHlsZUluZm8pXG4gICAgICAgICAgICAgICAgbGV0IG1heExpbmVzID0gTWF0aC5tYXgoYXR0cnMubWF4SGVpZ2h0IC8gbWV0cmljcy5saW5lSGVpZ2h0LCAxKVxuICAgICAgICAgICAgICAgIGxhYmVsID0gdGhpcy50cnVuY2F0ZUxhYmVsKGxhYmVsLCBmb250SW5mbywgbWF4TGluZXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICBcbiAgICAgICAgaWYgKCF0aGlzLmxhYmVscy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgbGV0IHRleHQgPSB0aGlzLl9jcmVhdGVUZXh0KGxhYmVsLCBmb250SW5mbylcbiAgICAgICAgICAgIHRoaXMubGFiZWxzLnNldChrZXksIHRleHQpXG4gICAgICAgICAgICB0aGlzLmFkZENoaWxkKHRleHQpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRleHQgPSB0aGlzLmxhYmVscy5nZXQoa2V5KVxuICAgICAgICBmb3IgKGxldCBrIGluIGF0dHJzKSB7XG4gICAgICAgICAgICB0ZXh0W2tdID0gYXR0cnNba11cbiAgICAgICAgfVxuICAgICAgICBpZiAobGFiZWwgIT0gdGV4dC50ZXh0KVxuICAgICAgICAgICAgdGV4dC50ZXh0ID0gbGFiZWxcbiAgICAgICAgLy8gV2UgZG8gbm90IGZvbGxvdyB0aGUgZmxleGJveCBqYXJnb24gYW5kIHVzZSBhbGlnbiBmb3IgeCBhbmQganVzdGlmeSBmb3IgeSBheGlzXG4gICAgICAgIC8vIFRoaXMgZGV2aWF0aW9uIGlzIG5lZWRlZCB0byBlbnN1cmUgYmFja3dhcmQgY29tcGF0YWJpbGl0eVxuICAgICAgICBzd2l0Y2ggKGF0dHJzLmp1c3RpZnkgfHwgbnVsbCkge1xuICAgICAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgICAgICB0ZXh0LmFuY2hvci55ID0gMFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgICAgIHRleHQuYW5jaG9yLnggPSAxXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGV4dC5hbmNob3IueSA9IDAuNVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChhdHRycy5hbGlnbikge1xuICAgICAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAgICAgIHRleHQuYW5jaG9yLnggPSAxXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgICAgICAgICAgdGV4dC5hbmNob3IueCA9IDAuNVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRleHQuYW5jaG9yLnggPSAwXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICB0ZXh0LnZpc2libGUgPSB0cnVlXG4gICAgICAgIHJldHVybiB0ZXh0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJpdmF0ZSBtZXRob2QgdGhhdCB0cnVuY2F0ZXMgdGhlIHRleHQgYW5kIGFkZHMgYW4gZWxsaXBzaXMgaWYgdGhlcmUgYXJlIG1vcmUgbGluZXNcbiAgICAgKiB0aGFuIHdhbnRlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSB0ZXh0XG4gICAgICogQHBhcmFtIHsqfSBzdHlsZVxuICAgICAqIEBwYXJhbSB7Kn0gW21heExpbmVzPUluZmluaXR5XVxuICAgICAqIEByZXR1cm5zXG4gICAgICogQG1lbWJlcm9mIExhYmVsZWRHcmFwaGljc1xuICAgICAqL1xuICAgIHRydW5jYXRlTGFiZWwodGV4dCwgc3R5bGUsIG1heExpbmVzID0gSW5maW5pdHkpIHtcbiAgICAgICAgaWYgKG1heExpbmVzID09PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHRcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHdvcmRXcmFwV2lkdGggfSA9IHN0eWxlXG4gICAgICAgIGNvbnN0IHBpeGlTdHlsZSA9IG5ldyBQSVhJLlRleHRTdHlsZShzdHlsZSlcbiAgICAgICAgY29uc3QgeyBsaW5lcyB9ID0gUElYSS5UZXh0TWV0cmljcy5tZWFzdXJlVGV4dCh0ZXh0LCBwaXhpU3R5bGUpXG4gICAgICAgIGxldCBuZXdUZXh0ID0gdGV4dFxuICAgICAgICBpZiAobGluZXMubGVuZ3RoID4gbWF4TGluZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRydW5jYXRlZExpbmVzID0gbGluZXMuc2xpY2UoMCwgbWF4TGluZXMpXG4gICAgICAgICAgICBjb25zdCBsYXN0TGluZSA9IHRydW5jYXRlZExpbmVzW3RydW5jYXRlZExpbmVzLmxlbmd0aCAtIDFdXG4gICAgICAgICAgICBjb25zdCB3b3JkcyA9IGxhc3RMaW5lLnNwbGl0KCcgJylcbiAgICAgICAgICAgIGNvbnN0IHdvcmRNZXRyaWNzID0gUElYSS5UZXh0TWV0cmljcy5tZWFzdXJlVGV4dChgXFx1MDBBMFxcbi4uLlxcbiR7d29yZHMuam9pbignXFxuJyl9YCwgcGl4aVN0eWxlKVxuICAgICAgICAgICAgY29uc3QgW3NwYWNlTGVuZ3RoLCBkb3RzTGVuZ3RoLCAuLi53b3JkTGVuZ3Roc10gPSB3b3JkTWV0cmljcy5saW5lV2lkdGhzXG4gICAgICAgICAgICBjb25zdCB7IHRleHQ6IG5ld0xhc3RMaW5lIH0gPSB3b3JkTGVuZ3Rocy5yZWR1Y2UoKGRhdGEsIHdvcmRMZW5ndGgsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggKyB3b3JkTGVuZ3RoICsgc3BhY2VMZW5ndGggPj0gd29yZFdyYXBXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5kYXRhLCBsZW5ndGg6IHdvcmRXcmFwV2lkdGggfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBgJHtkYXRhLnRleHR9JHtpID4gMCA/ICcgJyA6ICcnfSR7d29yZHNbaV19YCxcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiBkYXRhLmxlbmd0aCArIHdvcmRMZW5ndGggKyBzcGFjZUxlbmd0aCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSwgeyB0ZXh0OiAnJywgbGVuZ3RoOiBkb3RzTGVuZ3RoIH0pXG4gICAgICAgICAgICB0cnVuY2F0ZWRMaW5lc1t0cnVuY2F0ZWRMaW5lcy5sZW5ndGggLSAxXSA9IGAke25ld0xhc3RMaW5lfS4uLmBcbiAgICAgICAgICAgIG5ld1RleHQgPSB0cnVuY2F0ZWRMaW5lcy5qb2luKCdcXG4nKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdUZXh0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbGFiZWwgZm9yIHRoZSBnaXZlbiBrZXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGtleVxuICAgICAqIEByZXR1cm5zXG4gICAgICogQG1lbWJlcm9mIExhYmVsZWRHcmFwaGljc1xuICAgICAqL1xuICAgIGdldExhYmVsKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sYWJlbHMuZ2V0KGtleSlcbiAgICB9XG5cbiAgICAvKiogXG4gICAgICogSGlkZXMgdGhlIGxhYmVsIHdpdGggdGhlIGdpdmVuIGtleS5cbiAgICAgKiBAcGFyYW0geyp9IGtleVxuICAgICAqIEBtZW1iZXJvZiBMYWJlbGVkR3JhcGhpY3NcbiAgICAgKi9cbiAgICBoaWRlTGFiZWwoa2V5KSB7XG4gICAgICAgIGxldCBsYWJlbCA9IHRoaXMubGFiZWxzLmdldChrZXkpXG4gICAgICAgIGlmIChsYWJlbCkge1xuICAgICAgICAgICAgbGFiZWwudmlzaWJsZSA9IGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogXG4gICAgICogUmVtb3ZlcyB0aGUgbGFiZWwgd2l0aCB0aGUgZ2l2ZW4ga2V5LlxuICAgICAqIEBwYXJhbSB7Kn0ga2V5XG4gICAgICogQG1lbWJlcm9mIExhYmVsZWRHcmFwaGljc1xuICAgICAqL1xuICAgIHJlbW92ZUxhYmVsKGtleSkge1xuICAgICAgICBsZXQgbGFiZWwgPSB0aGlzLmxhYmVscy5nZXQoa2V5KVxuICAgICAgICB0aGlzLmxhYmVscy5kZWxldGUoa2V5KVxuICAgICAgICBsYWJlbC5kZXN0cm95KClcbiAgICB9XG5cbiAgIFxuICAgIC8qKlxuICAgICAqIEVuc3VyZXMgdGhhdCBsYWJlbHMgYXJlIGhpZGRlbiBvbiBjbGVhci5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBMYWJlbGVkR3JhcGhpY3NcbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgc3VwZXIuY2xlYXIoKVxuICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5sYWJlbHMua2V5cygpKSB7XG4gICAgICAgICAgICB0aGlzLmhpZGVMYWJlbChrZXkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2dzIGRlYnVnZ2luZyBpbmZvc1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mIExhYmVsZWRHcmFwaGljc1xuICAgICAqL1xuICAgIGRlYnVnSW5mb3MoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHsgc2l6ZTogdGhpcy5sYWJlbHMuc2l6ZSwgbGFiZWxzOiB0aGlzLmxhYmVscyB9KVxuICAgIH1cbn1cblxuXG5jb25zdCBsYWJlbENhY2hlID0gbmV3IE1hcCgpXG5cbmZ1bmN0aW9uIGdldFRleHR1cmUobGFiZWwsIGZvbnRJbmZvID0gRm9udEluZm8ubm9ybWFsKSB7XG4gICAgbGV0IGtleSA9IGxhYmVsICsgZm9udEluZm8uZm9udEZhbWlseSArIGZvbnRJbmZvLmZvbnRTaXplXG5cbiAgICBpZiAobGFiZWxDYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICByZXR1cm4gbGFiZWxDYWNoZS5nZXQoa2V5KVxuICAgIH1cbiAgICBsZXQgZXhwYW5kZWRGb250ID0gT2JqZWN0LmFzc2lnbih7fSwgZm9udEluZm8pXG4gICAgZXhwYW5kZWRGb250LmZvbnRTaXplICo9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvXG4gICAgbGV0IHRleHQgPSBuZXcgUElYSS5UZXh0KGxhYmVsLCBleHBhbmRlZEZvbnQpXG4gICAgdGV4dC51cGRhdGVUZXh0KClcbiAgICBsYWJlbENhY2hlLnNldChrZXksIHRleHQudGV4dHVyZSlcbiAgICByZXR1cm4gdGV4dC50ZXh0dXJlXG59XG5cbmNsYXNzIFNwcml0ZUxhYmVsIGV4dGVuZHMgUElYSS5TcHJpdGUge1xuXG4gICAgY29uc3RydWN0b3IobGFiZWwsIGZvbnRJbmZvKSB7XG4gICAgICAgIGxldCB0ZXh0dXJlID0gZ2V0VGV4dHVyZShsYWJlbCwgZm9udEluZm8pXG4gICAgICAgIHN1cGVyKHRleHR1cmUpXG4gICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbFxuICAgICAgICB0aGlzLmZvbnRJbmZvID0gZm9udEluZm9cbiAgICAgICAgdGhpcy5zY2FsZS5zZXQoMC44IC8gd2luZG93LmRldmljZVBpeGVsUmF0aW8pXG4gICAgfVxuXG4gICAgc2V0IHRleHQobGFiZWwpIHtcbiAgICAgICAgdGhpcy5sYWJlbCA9IGxhYmVsXG4gICAgICAgIHRoaXMudGV4dHVyZSA9IGdldFRleHR1cmUobGFiZWwsIHRoaXMuZm9udEluZm8pXG4gICAgfVxuXG4gICAgZ2V0IHRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhYmVsXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQml0bWFwTGFiZWxlZEdyYXBoaWNzIGV4dGVuZHMgTGFiZWxlZEdyYXBoaWNzIHtcblxuICAgIF9jcmVhdGVUZXh0KGxhYmVsLCBmb250SW5mbykge1xuICAgICAgICBsZXQgdGV4dHVyZSA9IGdldFRleHR1cmUobGFiZWwsIGZvbnRJbmZvKVxuICAgICAgICByZXR1cm4gbmV3IFNwcml0ZUxhYmVsKHRleHR1cmUpXG4gICAgfVxuXG59IiwiaW1wb3J0IHsgQ3ljbGUsIENvbG9ycywgRGF0ZXMsIGlzRW1wdHkgfSBmcm9tICcuLi91dGlscy5qcydcbmltcG9ydCB7IENhcGFiaWxpdGllcyB9IGZyb20gJy4uL2NhcGFiaWxpdGllcy5qcydcbmltcG9ydCB7IEJpdG1hcExhYmVsZWRHcmFwaGljcywgTGFiZWxlZEdyYXBoaWNzLCBGb250SW5mbyB9IGZyb20gJy4vbGFiZWxlZGdyYXBoaWNzLmpzJ1xuXG5cbmV4cG9ydCBjbGFzcyBUaWNrcyB7XG5cbiAgICBnZXQgcmVzZXJ2ZWRQcmVmaXhlcygpIHtcbiAgICAgICAgcmV0dXJuIFsnZGVjYWRlJywgJ3llYXInLCAnbW9udGgnLCAnZGF5JywgJ2hvdXInLCAnbWludXRlJywgJ3NlY29uZCddXG4gICAgfVxuXG4gICAgZ2V0IG1pbldpZHRoKCkge1xuICAgICAgICByZXR1cm4gMTBcbiAgICB9XG5cbiAgICBmb3JtYXQoYXZhaWxhYmxlKSB7XG4gICAgICAgIHJldHVybiB7IHllYXI6ICcyLWRpZ2l0JywgdGltZVpvbmU6ICdVVEMnIH1cbiAgICB9XG5cbiAgICBnZXQgbWluTGFiZWxXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIDQ0XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdEtleSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMua2V5XG4gICAgfVxuXG4gICAgZGF0ZUtleShkYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmtleSArIGRhdGUuZ2V0RnVsbFllYXIoKVxuICAgIH1cblxuICAgICppdGVyKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgbGV0IGRhdGUgPSB0aGlzLml0ZXJTdGFydChzdGFydClcbiAgICAgICAgd2hpbGUgKGRhdGUgPD0gZW5kKSB7XG4gICAgICAgICAgICB5aWVsZCBkYXRlXG4gICAgICAgICAgICBkYXRlID0gdGhpcy5uZXh0KGRhdGUpXG4gICAgICAgIH1cbiAgICAgICAgeWllbGQgZGF0ZVxuICAgIH1cblxuICAgICppdGVyUmFuZ2VzKHJhbmdlKSB7XG4gICAgICAgIGZvciAobGV0IGRhdGUgb2YgdGhpcy5pdGVyKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQpKSB7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IHRoaXMubmV4dChkYXRlKVxuICAgICAgICAgICAgeWllbGQgeyBzdGFydDogZGF0ZSwgZW5kOiBuZXh0IH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdGVkUmFuZ2UodGltZWxpbmUsIGluZm8pIHtcbiAgICAgICAgbGV0IGZpcnN0ID0gbnVsbFxuICAgICAgICBsZXQgbGFzdCA9IG51bGxcbiAgICAgICAgbGV0IHZpc2libGVGaXJzdCA9IG51bGxcbiAgICAgICAgbGV0IHZpc2libGVMYXN0ID0gbnVsbFxuICAgICAgICBsZXQgdW5pdHMgPSAwXG4gICAgICAgIGZvciAobGV0IHsgc3RhcnQsIGVuZCB9IG9mIHRoaXMuaXRlclJhbmdlcyhpbmZvKSkge1xuICAgICAgICAgICAgaWYgKHRpbWVsaW5lLnZpc2libGVSYW5nZShzdGFydCwgZW5kKSkge1xuICAgICAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gc3RhcnRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFzdCA9IGVuZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRpbWVsaW5lLnZpc2libGVEYXRlKHN0YXJ0KSAmJiB0aW1lbGluZS52aXNpYmxlRGF0ZShlbmQpKSB7XG4gICAgICAgICAgICAgICAgdW5pdHMgKz0gMVxuICAgICAgICAgICAgICAgIGlmICh2aXNpYmxlRmlyc3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlRmlyc3QgPSBzdGFydFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2aXNpYmxlTGFzdCA9IGVuZFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmaXJzdCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIGluZm9cbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IGZpcnN0LCBlbmQ6IGxhc3QsIHZpc2libGVTdGFydDogdmlzaWJsZUZpcnN0LCB2aXNpYmxlRW5kOiB2aXNpYmxlTGFzdCwgdW5pdHM6IHVuaXRzIH1cbiAgICB9XG5cbiAgICBkcmF3VGljayh0aW1lbGluZSwgeCwgeSwgZGF0ZSkge1xuICAgICAgICBsZXQgdmlzaWJsZSA9IGRhdGUgPiB0aW1lbGluZS5zdGFydCAmJiBkYXRlIDwgdGltZWxpbmUuZW5kXG4gICAgICAgIGlmICghdmlzaWJsZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB0aW1lbGluZS5kcmF3VGljayh4KVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHRvTG9jYWxlU3RyaW5nKGRhdGUsIGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcoJ2RlJywgZm9ybWF0KVxuICAgIH1cblxuICAgIGRyYXcodGltZWxpbmUsIHJhbmdlLCB3aWR0aCwgaGVpZ2h0LCBhdmFpbGFibGUsIGZvcm1hdCwgbmV4dEZvcm1hdCwgbGV2ZWwpIHtcbiAgICAgICAgbGV0IGZpcnN0ID0gbnVsbFxuICAgICAgICBsZXQgbGFzdCA9IG51bGxcbiAgICAgICAgbGV0IGtleWVkRm9ybWF0ID0gKGZvcm1hdCkgPyBmb3JtYXRbdGhpcy5mb3JtYXRLZXldIDogbnVsbFxuICAgICAgICBsZXQga2V5ZWROZXh0Rm9ybWF0ID0gKG5leHRGb3JtYXQpID8gbmV4dEZvcm1hdFt0aGlzLmZvcm1hdEtleV0gOiBudWxsXG4gICAgICAgIGxldCByZWR1bmRhbnQgPSAobmV4dEZvcm1hdCkgPyB0aGlzLmZvcm1hdEtleSBpbiBuZXh0Rm9ybWF0IDogZmFsc2VcbiAgICAgICAgbGV0IGZ1bGx5UmVkdW5kYW50ID0ga2V5ZWRGb3JtYXQgIT0gbnVsbCAmJiBrZXllZEZvcm1hdCA9PSBrZXllZE5leHRGb3JtYXRcbiAgICAgICAgbGV0IHkgPSB0aW1lbGluZS5nZXRZKClcblxuICAgICAgICBmb3IgKGxldCB7IHN0YXJ0LCBlbmQgfSBvZiB0aGlzLml0ZXJSYW5nZXMocmFuZ2UpKSB7XG4gICAgICAgICAgICBsZXQgeCA9IHRpbWVsaW5lLnRvWChzdGFydClcbiAgICAgICAgICAgIGxldCB4eCA9IHhcbiAgICAgICAgICAgIGxldCB5eSA9IHkgKyB0aW1lbGluZS50aWNrTGFiZWxPZmZzZXQoLTEpXG4gICAgICAgICAgICBpZiAodGhpcy5kcmF3VGljayh0aW1lbGluZSwgeCwgeSwgc3RhcnQpICYmIGZvcm1hdCkge1xuICAgICAgICAgICAgICAgIGxldCBrZXkgPSB0aGlzLmRhdGVLZXkoc3RhcnQpXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSB0aGlzLnRvTG9jYWxlU3RyaW5nKHN0YXJ0LCBmb3JtYXQpXG4gICAgICAgICAgICAgICAgbGV0IGFsaWduID0gJ2NlbnRlcidcbiAgICAgICAgICAgICAgICBsZXQgZG93blRpY2sgPSBmYWxzZVxuICAgICAgICAgICAgICAgIGlmIChuZXh0Rm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgICAgIHl5ID0geSArIHRpbWVsaW5lLnRpY2tMYWJlbE9mZnNldCgtMSwgMSlcbiAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAnbGVmdCdcbiAgICAgICAgICAgICAgICAgICAgdGltZWxpbmUuZHJhd1RpY2soeCwgNC4yKVxuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dFggPSB0aW1lbGluZS50b1goZW5kKSAtIDEwMFxuICAgICAgICAgICAgICAgICAgICBpZiAoeCA8IDAgJiYgbmV4dFggPiAtMTAwICYmICFyZWR1bmRhbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHh4ID0gTWF0aC5taW4oNCwgbmV4dFgpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4eCAtPSAyXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZG93blRpY2sgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxldmVsID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB4eCA9IHggKyBhdmFpbGFibGUgLyAyXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkb3duVGljayA9IHRydWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFmdWxseVJlZHVuZGFudCkge1xuICAgICAgICAgICAgICAgICAgICB0aW1lbGluZS5lbnN1cmVMYWJlbChrZXksIHRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHg6IHh4LCB5OiB5eSwgYWxpZ24gfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIEZvbnRJbmZvLnNtYWxsKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZG93blRpY2spIHRpbWVsaW5lLmRyYXdUaWNrKHgsIC0xKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRpbWVsaW5lLnZpc2libGVSYW5nZShzdGFydCwgZW5kKSkge1xuICAgICAgICAgICAgICAgIGlmIChmaXJzdCA9PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IHN0YXJ0XG4gICAgICAgICAgICAgICAgbGFzdCA9IGVuZFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmaXJzdCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IGZpcnN0LCBlbmQ6IGxhc3QgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIERlY2FkZVRpY2tzIGV4dGVuZHMgVGlja3Mge1xuXG4gICAgZ2V0IG1pbGxpc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIDEwICogMzY1ICogMjQgKiA2MCAqIDYwICogMTAwMFxuICAgIH1cblxuICAgIGZvcm1hdChhdmFpbGFibGUpIHtcbiAgICAgICAgcmV0dXJuIHsgeWVhcjogJ251bWVyaWMnLCB0aW1lWm9uZTogJ1VUQycgfVxuICAgIH1cblxuICAgIHNlbGVjdGlvbih0aW1lbGluZSwgZGF0ZXMsIHNlbGVjdGVkKSB7XG4gICAgICAgIHJldHVybiBkYXRlc1xuICAgIH1cblxuICAgIGdldCBrZXkoKSB7XG4gICAgICAgIHJldHVybiAnZGVjYWRlJ1xuICAgIH1cblxuICAgIGdldCBmb3JtYXRLZXkoKSB7XG4gICAgICAgIHJldHVybiAneWVhcidcbiAgICB9XG5cbiAgICBpdGVyU3RhcnQoc3RhcnQpIHtcbiAgICAgICAgbGV0IG1vZHVsbyA9IHN0YXJ0LmdldEZ1bGxZZWFyKCkgJSAxMFxuICAgICAgICBsZXQgeWVhciA9IHN0YXJ0LmdldEZ1bGxZZWFyKCkgLSBtb2R1bG9cbiAgICAgICAgcmV0dXJuIERhdGVzLmNyZWF0ZSh5ZWFyLCAwLCAxKVxuICAgIH1cblxuICAgIG5leHQoZGVjYWRlKSB7XG4gICAgICAgIHJldHVybiBEYXRlcy5uZXh0WWVhcihkZWNhZGUsIDEwKVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFllYXJUaWNrcyBleHRlbmRzIFRpY2tzIHtcblxuICAgIGdldCBtaWxsaXNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAzNjUgKiAyNCAqIDYwICogNjAgKiAxMDAwXG4gICAgfVxuXG4gICAgZm9ybWF0KGF2YWlsYWJsZSkge1xuICAgICAgICBpZiAoYXZhaWxhYmxlIDwgNDQpXG4gICAgICAgICAgICByZXR1cm4geyB5ZWFyOiAnMi1kaWdpdCcsIHRpbWVab25lOiAnVVRDJyB9XG4gICAgICAgIHJldHVybiB7IHllYXI6ICdudW1lcmljJywgdGltZVpvbmU6ICdVVEMnIH1cbiAgICB9XG5cbiAgICBnZXQgbWluTGFiZWxXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIDIyXG4gICAgfVxuXG4gICAgZ2V0IGtleSgpIHtcbiAgICAgICAgcmV0dXJuICd5ZWFyJ1xuICAgIH1cblxuICAgIGl0ZXJTdGFydChzdGFydCkge1xuICAgICAgICByZXR1cm4gRGF0ZXMuY3JlYXRlKHN0YXJ0LmdldEZ1bGxZZWFyKCksIDAsIDEpXG4gICAgfVxuXG4gICAgbmV4dCh5ZWFyKSB7XG4gICAgICAgIHJldHVybiBEYXRlcy5uZXh0WWVhcih5ZWFyKVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1vbnRoVGlja3MgZXh0ZW5kcyBUaWNrcyB7XG5cbiAgICBnZXQgbWlsbGlzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gKDM2NSAvIDEyKSAqIDI0ICogNjAgKiA2MCAqIDEwMDBcbiAgICB9XG5cbiAgICBmb3JtYXQoYXZhaWxhYmxlKSB7XG4gICAgICAgIGxldCBmb3JtYXQgPSB7IG1vbnRoOiAnbmFycm93JywgdGltZVpvbmU6ICdVVEMnIH1cbiAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDQ0KVxuICAgICAgICAgICAgZm9ybWF0Lm1vbnRoID0gJ3Nob3J0J1xuICAgICAgICBpZiAoYXZhaWxhYmxlID4gNjYpXG4gICAgICAgICAgICBmb3JtYXQueWVhciA9ICcyLWRpZ2l0J1xuICAgICAgICBpZiAoYXZhaWxhYmxlID4gMTAwKSB7XG4gICAgICAgICAgICBmb3JtYXQubW9udGggPSAnbG9uZydcbiAgICAgICAgICAgIGZvcm1hdC55ZWFyID0gJ251bWVyaWMnXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdFxuICAgIH1cblxuICAgIGdldCBtaW5MYWJlbFdpZHRoKCkge1xuICAgICAgICByZXR1cm4gMzJcbiAgICB9XG5cbiAgICBnZXQga2V5KCkge1xuICAgICAgICByZXR1cm4gJ21vbnRoJ1xuICAgIH1cblxuICAgIGRhdGVLZXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5rZXkgKyBkYXRlLmdldEZ1bGxZZWFyKCkgKyBkYXRlLmdldE1vbnRoKClcbiAgICB9XG5cbiAgICBpdGVyU3RhcnQoc3RhcnQpIHtcbiAgICAgICAgcmV0dXJuIERhdGVzLmNyZWF0ZShzdGFydC5nZXRGdWxsWWVhcigpLCBzdGFydC5nZXRNb250aCgpLCAxKVxuICAgIH1cblxuICAgIG5leHQobW9udGgpIHtcbiAgICAgICAgcmV0dXJuIERhdGVzLm5leHRNb250aChtb250aClcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEYXlUaWNrcyBleHRlbmRzIFRpY2tzIHtcblxuICAgIGdldCBtaWxsaXNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAyNCAqIDYwICogNjAgKiAxMDAwXG4gICAgfVxuXG4gICAgZm9ybWF0KGF2YWlsYWJsZSkge1xuICAgICAgICBsZXQgZm9ybWF0ID0geyBkYXk6ICdudW1lcmljJywgdGltZVpvbmU6ICdVVEMnIH1cbiAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDQ0KVxuICAgICAgICAgICAgZm9ybWF0Lm1vbnRoID0gJ3Nob3J0J1xuICAgICAgICBpZiAoYXZhaWxhYmxlID4gMTAwKSB7XG4gICAgICAgICAgICBmb3JtYXQubW9udGggPSAnbG9uZydcbiAgICAgICAgICAgIGZvcm1hdC55ZWFyID0gJzItZGlnaXQnXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDE1MCkge1xuICAgICAgICAgICAgZm9ybWF0LndlZWtkYXkgPSAnc2hvcnQnXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDIwMCkge1xuICAgICAgICAgICAgZm9ybWF0LnllYXIgPSAnbnVtZXJpYydcbiAgICAgICAgICAgIGZvcm1hdC53ZWVrZGF5ID0gJ2xvbmcnXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdFxuICAgIH1cblxuICAgIGdldCBrZXkoKSB7XG4gICAgICAgIHJldHVybiAnZGF5J1xuICAgIH1cblxuICAgIGRhdGVLZXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5rZXkgKyBkYXRlLmdldEZ1bGxZZWFyKCkgKyBkYXRlLmdldE1vbnRoKCkgKyBkYXRlLmdldERhdGUoKVxuICAgIH1cblxuICAgIGl0ZXJTdGFydChzdGFydCkge1xuICAgICAgICByZXR1cm4gRGF0ZXMuY3JlYXRlKHN0YXJ0LmdldEZ1bGxZZWFyKCksIHN0YXJ0LmdldE1vbnRoKCksIHN0YXJ0LmdldERhdGUoKSlcbiAgICB9XG5cbiAgICBuZXh0KGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIERhdGVzLm5leHREYXkoZGF0ZSlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBIb3VyVGlja3MgZXh0ZW5kcyBUaWNrcyB7XG5cbiAgICBnZXQgbWlsbGlzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gNjAgKiA2MCAqIDEwMDBcbiAgICB9XG5cbiAgICBmb3JtYXQoYXZhaWxhYmxlKSB7XG4gICAgICAgIGxldCBmb3JtYXQgPSB7fVxuICAgICAgICBpZiAoYXZhaWxhYmxlID4gNDQpIHtcbiAgICAgICAgICAgIGZvcm1hdC5ob3VyID0gJzItZGlnaXQnXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF2YWlsYWJsZSA+IDEwMCkge1xuICAgICAgICAgICAgZm9ybWF0LmRheSA9ICcyLWRpZ2l0J1xuICAgICAgICAgICAgZm9ybWF0Lm1vbnRoID0gJzItZGlnaXQnXG4gICAgICAgICAgICBmb3JtYXQueWVhciA9ICcyLWRpZ2l0J1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdmFpbGFibGUgPiAxNTApIHtcbiAgICAgICAgICAgIGZvcm1hdC53ZWVrZGF5ID0gJ3Nob3J0J1xuICAgICAgICAgICAgZm9ybWF0Lm1vbnRoID0gJ3Nob3J0J1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdmFpbGFibGUgPiAyMDApIHtcbiAgICAgICAgICAgIGZvcm1hdC5kYXkgPSAnbnVtZXJpYydcbiAgICAgICAgICAgIGZvcm1hdC55ZWFyID0gJ251bWVyaWMnXG4gICAgICAgICAgICBmb3JtYXQubW9udGggPSAnbG9uZydcbiAgICAgICAgICAgIGZvcm1hdC53ZWVrZGF5ID0gJ2xvbmcnXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdFxuICAgIH1cblxuICAgIGdldCBrZXkoKSB7XG4gICAgICAgIHJldHVybiAnaG91cidcbiAgICB9XG5cbiAgICBkYXRlS2V5KGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMua2V5ICsgZGF0ZS5nZXRGdWxsWWVhcigpXG4gICAgICAgICAgICArIGRhdGUuZ2V0TW9udGgoKVxuICAgICAgICAgICAgKyBkYXRlLmdldERhdGUoKVxuICAgICAgICAgICAgKyBkYXRlLmdldEhvdXJzKClcbiAgICB9XG5cbiAgICBpdGVyU3RhcnQoc3RhcnQpIHtcbiAgICAgICAgcmV0dXJuIERhdGVzLmNyZWF0ZShzdGFydC5nZXRGdWxsWWVhcigpLFxuICAgICAgICAgICAgc3RhcnQuZ2V0TW9udGgoKSxcbiAgICAgICAgICAgIHN0YXJ0LmdldERhdGUoKSxcbiAgICAgICAgICAgIHN0YXJ0LmdldEhvdXJzKCkpXG4gICAgfVxuXG4gICAgbmV4dChkYXRlKSB7XG4gICAgICAgIHJldHVybiBEYXRlcy5uZXh0SG91cihkYXRlKVxuICAgIH1cblxuICAgIHRvTG9jYWxlU3RyaW5nKGRhdGUsIGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZVRpbWVTdHJpbmcoJ2RlJywgZm9ybWF0KVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1pbnV0ZVRpY2tzIGV4dGVuZHMgVGlja3Mge1xuXG4gICAgZ2V0IG1pbGxpc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIDYwICogMTAwMFxuICAgIH1cblxuICAgIGZvcm1hdChhdmFpbGFibGUpIHtcbiAgICAgICAgbGV0IGZvcm1hdCA9IHsgbWludXRlOiAnbnVtZXJpYycsIHRpbWVab25lOiAnVVRDJyB9XG4gICAgICAgIGlmIChhdmFpbGFibGUgPiA0NCkge1xuICAgICAgICAgICAgZm9ybWF0LmhvdXIgPSAnbnVtZXJpYydcbiAgICAgICAgICAgIGZvcm1hdC5taW51dGUgPSAnbnVtZXJpYydcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXZhaWxhYmxlID4gMTAwKSB7XG4gICAgICAgICAgICBmb3JtYXQubW9udGggPSAnc2hvcnQnXG4gICAgICAgICAgICBmb3JtYXQueWVhciA9ICcyLWRpZ2l0J1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdmFpbGFibGUgPiAxNTApIHtcbiAgICAgICAgICAgIGZvcm1hdC53ZWVrZGF5ID0gJ3Nob3J0J1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdmFpbGFibGUgPiAyMDApIHtcbiAgICAgICAgICAgIGZvcm1hdC55ZWFyID0gJ251bWVyaWMnXG4gICAgICAgICAgICBmb3JtYXQud2Vla2RheSA9ICdsb25nJ1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb3JtYXRcbiAgICB9XG5cbiAgICBnZXQga2V5KCkge1xuICAgICAgICByZXR1cm4gJ21pbnV0ZSdcbiAgICB9XG5cbiAgICBkYXRlS2V5KGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMua2V5ICsgZGF0ZS5nZXRGdWxsWWVhcigpXG4gICAgICAgICAgICArIGRhdGUuZ2V0TW9udGgoKVxuICAgICAgICAgICAgKyBkYXRlLmdldERhdGUoKVxuICAgICAgICAgICAgKyBkYXRlLmdldEhvdXJzKClcbiAgICAgICAgICAgICsgZGF0ZS5nZXRNaW51dGVzKClcbiAgICB9XG5cbiAgICBpdGVyU3RhcnQoc3RhcnQpIHtcbiAgICAgICAgcmV0dXJuIERhdGVzLmNyZWF0ZShzdGFydC5nZXRGdWxsWWVhcigpLFxuICAgICAgICAgICAgc3RhcnQuZ2V0TW9udGgoKSxcbiAgICAgICAgICAgIHN0YXJ0LmdldERhdGUoKSxcbiAgICAgICAgICAgIHN0YXJ0LmdldEhvdXJzKCksXG4gICAgICAgICAgICBzdGFydC5nZXRNaW51dGVzKCkpXG4gICAgfVxuXG4gICAgbmV4dChkYXRlKSB7XG4gICAgICAgIHJldHVybiBEYXRlcy5uZXh0TWludXRlKGRhdGUpXG4gICAgfVxuXG4gICAgdG9Mb2NhbGVTdHJpbmcoZGF0ZSwgZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBkYXRlLnRvTG9jYWxlVGltZVN0cmluZygnZGUnLCBmb3JtYXQpXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgVGltZVRpY2tzIHtcblxuICAgIGNvbnN0cnVjdG9yKC4uLnRpY2tzKSB7XG4gICAgICAgIHRoaXMudGlja3MgPSB0aWNrc1xuICAgIH1cblxuICAgIHNlbGVjdGVkUmFuZ2UodGltZWxpbmUpIHtcbiAgICAgICAgbGV0IGluZm8gPSB7IHN0YXJ0OiB0aW1lbGluZS5zdGFydCwgZW5kOiB0aW1lbGluZS5lbmQsIHVuaXRzOiAwIH1cbiAgICAgICAgZm9yIChsZXQgdGlja3Mgb2YgdGhpcy50aWNrcykge1xuICAgICAgICAgICAgaW5mbyA9IHRpY2tzLnNlbGVjdGVkUmFuZ2UodGltZWxpbmUsIGluZm8pXG4gICAgICAgICAgICBpZiAoaW5mby51bml0cyA+IDEpIHtcbiAgICAgICAgICAgICAgICB0aW1lbGluZS5zZWxlY3Rpb24gPSBbaW5mby52aXNpYmxlU3RhcnQsIGluZm8udmlzaWJsZUVuZF1cbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aW1lbGluZS5zZWxlY3Rpb24gPSBbaW5mby5zdGFydCwgaW5mby5lbmRdXG4gICAgfVxuXG4gICAgZHJhdyh0aW1lbGluZSwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSB0aW1lbGluZVxuICAgICAgICBsZXQgc3RhcnQgPSB0aW1lbGluZS50b1gocmFuZ2Uuc3RhcnQpXG4gICAgICAgIGxldCBlbmQgPSB0aW1lbGluZS50b1gocmFuZ2UuZW5kKVxuICAgICAgICBsZXQgc2l6ZSA9IGVuZCAtIHN0YXJ0XG4gICAgICAgIGxldCBkdXJhdGlvbiA9IHRpbWVsaW5lLmVuZCAtIHRpbWVsaW5lLnN0YXJ0XG4gICAgICAgIGxldCBmb3JtYXRzID0gbmV3IE1hcCgpXG4gICAgICAgIGxldCBuZXh0Rm9ybWF0cyA9IG5ldyBNYXAoKVxuICAgICAgICBsZXQgYXZhaWxhYmxlcyA9IG5ldyBNYXAoKVxuICAgICAgICBsZXQgcHJldmlvdXMgPSBudWxsXG4gICAgICAgIGxldCB2aXNpYmxlID0gW11cbiAgICAgICAgZm9yIChsZXQgdGlja3Mgb2YgdGhpcy50aWNrcykge1xuICAgICAgICAgICAgbGV0IGFtb3VudCA9IHRpY2tzLm1pbGxpc2Vjb25kcyAvIGR1cmF0aW9uXG4gICAgICAgICAgICBsZXQgYXZhaWxhYmxlID0gYW1vdW50ICogc2l6ZVxuICAgICAgICAgICAgYXZhaWxhYmxlcy5zZXQodGlja3MsIGF2YWlsYWJsZSlcbiAgICAgICAgICAgIGlmIChhdmFpbGFibGUgPCB0aWNrcy5taW5XaWR0aClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZm9ybWF0cy5zZXQodGlja3MsIChhdmFpbGFibGUgPCB0aWNrcy5taW5MYWJlbFdpZHRoKSA/IG51bGwgOiB0aWNrcy5mb3JtYXQoYXZhaWxhYmxlKSlcbiAgICAgICAgICAgIG5leHRGb3JtYXRzLnNldChwcmV2aW91cywgZm9ybWF0cy5nZXQodGlja3MpKVxuICAgICAgICAgICAgcHJldmlvdXMgPSB0aWNrc1xuICAgICAgICAgICAgdmlzaWJsZS5wdXNoKHRpY2tzKVxuICAgICAgICB9XG4gICAgICAgIGxldCBsZXZlbCA9IDBcbiAgICAgICAgZm9yIChsZXQgdGlja3Mgb2YgdmlzaWJsZSkge1xuICAgICAgICAgICAgaWYgKHJhbmdlID09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICByYW5nZSA9IHRpY2tzLmRyYXcodGltZWxpbmUsIHJhbmdlLCB3aWR0aCwgaGVpZ2h0LFxuICAgICAgICAgICAgICAgIGF2YWlsYWJsZXMuZ2V0KHRpY2tzKSxcbiAgICAgICAgICAgICAgICBmb3JtYXRzLmdldCh0aWNrcyksXG4gICAgICAgICAgICAgICAgbmV4dEZvcm1hdHMuZ2V0KHRpY2tzKSwgbGV2ZWwpXG4gICAgICAgICAgICBsZXZlbCArPSAxXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBDb2xvclJhbmdlcyB7XG5cbiAgICBjb25zdHJ1Y3RvcihsYWJlbCwgY29sb3IsIHJhbmdlcykge1xuICAgICAgICB0aGlzLmxhYmVsID0gbGFiZWxcbiAgICAgICAgdGhpcy5jb2xvciA9IGNvbG9yXG4gICAgICAgIHRoaXMucmFuZ2VzID0gcmFuZ2VzXG4gICAgfVxuXG4gICAgZHJhdyh0aW1lbGluZSwgd2lkdGgsIGhlaWdodCwgc2l6ZSA9IDEyKSB7XG4gICAgICAgIGxldCBtaW5pbXVtID0gMSAvIENhcGFiaWxpdGllcy5kZXZpY2VQaXhlbFJhdGlvXG4gICAgICAgIGxldCBoMiA9IHNpemVcbiAgICAgICAgdGltZWxpbmUubGluZVN0eWxlKHNpemUsIHRoaXMuY29sb3IpXG4gICAgICAgIGZvciAobGV0IHJhbmdlIG9mIHRoaXMucmFuZ2VzKSB7XG4gICAgICAgICAgICBpZiAocmFuZ2UudG8gPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByYW5nZS50byA9IERhdGVzLm5leHREYXkocmFuZ2UuZnJvbSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRpbWVsaW5lLnRvWChyYW5nZS5mcm9tKVxuICAgICAgICAgICAgbGV0IGVuZCA9IHRpbWVsaW5lLnRvWChyYW5nZS50bylcbiAgICAgICAgICAgIGlmIChlbmQgPCBzdGFydCArIG1pbmltdW0pIHtcbiAgICAgICAgICAgICAgICBlbmQgPSBzdGFydCArIG1pbmltdW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRpbWVsaW5lLm1vdmVUbyhzdGFydCwgaDIpXG4gICAgICAgICAgICB0aW1lbGluZS5saW5lVG8oZW5kLCBoMilcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGltZWxpbmUgZXh0ZW5kcyBCaXRtYXBMYWJlbGVkR3JhcGhpY3Mge1xuXG4gICAgY29uc3RydWN0b3Iod2lkdGgsIGhlaWdodCwgeyB0aWNrcyA9IG51bGwsXG4gICAgICAgIGJhc2VMaW5lID0gMC41LCBzaG93UmFuZ2UgPSB0cnVlIH0gPSB7fSkge1xuICAgICAgICBzdXBlcigpXG4gICAgICAgIHRoaXMud2FudGVkV2lkdGggPSB3aWR0aFxuICAgICAgICB0aGlzLndhbnRlZEhlaWdodCA9IGhlaWdodFxuICAgICAgICB0aGlzLmV4dHJhTGVmdCA9IDBcbiAgICAgICAgdGhpcy5leHRyYVJpZ2h0ID0gMFxuICAgICAgICB0aGlzLmluc2V0ID0gNVxuICAgICAgICB0aGlzLnNob3dSYW5nZSA9IHNob3dSYW5nZVxuICAgICAgICB0aGlzLmJhc2VMaW5lID0gYmFzZUxpbmVcbiAgICAgICAgdGhpcy50aWNrSGVpZ2h0ID0gNFxuICAgICAgICB0aGlzLnpvb20gPSAxXG4gICAgICAgIHRoaXMubWluWm9vbSA9IDFcbiAgICAgICAgdGhpcy5tYXhab29tID0gMTIwMDBcbiAgICAgICAgdGhpcy5zY3JvbGwgPSAwXG4gICAgICAgIHRoaXMuZGVsdGFzID0gW11cbiAgICAgICAgdGhpcy5sYWJlbERhdGVzID0gW11cbiAgICAgICAgdGhpcy5jb2xvclJhbmdlcyA9IFtdXG4gICAgICAgIHRoaXMucmFuZ2VDb2xvcnMgPSBuZXcgQ3ljbGUoQ29sb3JzLmVtaW5lbmNlLFxuICAgICAgICAgICAgQ29sb3JzLnN0ZWVsYmx1ZSxcbiAgICAgICAgICAgIENvbG9ycy5vY2hyZSxcbiAgICAgICAgICAgIENvbG9ycy50dXJxdW9pc2UpXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gW11cbiAgICAgICAgdGhpcy5vblRhcENhbGxiYWNrcyA9IFtdXG4gICAgICAgIHRoaXMub25Eb3VibGVUYXBDYWxsYmFja3MgPSBbXVxuICAgICAgICB0aGlzLm9uTG9uZ1ByZXNzQ2FsbGJhY2tzID0gW11cbiAgICAgICAgdGhpcy5wcm9ncmVzcyA9IG51bGxcbiAgICAgICAgdGhpcy5zdGFydCA9IG51bGxcbiAgICAgICAgdGhpcy5lbmQgPSBudWxsXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uID0gbnVsbFxuICAgICAgICB0aGlzLmF1dG9TY3JvbGwgPSBmYWxzZVxuICAgICAgICB0aGlzLmRpcmVjdGlvbiA9IC0xXG4gICAgICAgIHRoaXMudGltZXRpY2tzID0gdGlja3MgfHwgbmV3IFRpbWVUaWNrcyhuZXcgRGVjYWRlVGlja3MoKSxcbiAgICAgICAgICAgIG5ldyBZZWFyVGlja3MoKSxcbiAgICAgICAgICAgIG5ldyBNb250aFRpY2tzKCksXG4gICAgICAgICAgICBuZXcgRGF5VGlja3MoKSlcbiAgICAgICAgdGhpcy5sYWJlbFByZWZpeCA9ICdfXydcbiAgICB9XG5cbiAgICB1cGRhdGVTZWxlY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLnZpc2libGVEYXRlKHRoaXMuc3RhcnQpICYmIHRoaXMudmlzaWJsZURhdGUodGhpcy5lbmQpKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IFt0aGlzLnN0YXJ0LCB0aGlzLmVuZF1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudGltZXRpY2tzLnNlbGVjdGVkUmFuZ2UodGhpcylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGlvblxuICAgIH1cblxuICAgIGFkZENhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spXG4gICAgfVxuXG4gICAgYWRkVGFiQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5vblRhcENhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIGFkZERvdWJsZVRhcENhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMub25Eb3VibGVUYXBDYWxsYmFja3MucHVzaChjYWxsYmFjaylcbiAgICB9XG5cbiAgICBhZGRMb25nUHJlc3NDYWxsYmFjayhjYWxsYmFjaykge1xuICAgICAgICB0aGlzLm9uTG9uZ1ByZXNzQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spXG4gICAgfVxuXG4gICAgYWRkTGFiZWxzKGxhYmVscykge1xuICAgICAgICB0aGlzLmxhYmVsRGF0ZXMgPSBsYWJlbHNcbiAgICB9XG5cbiAgICByYW5nZShzdGFydCwgZW5kKSB7XG4gICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydFxuICAgICAgICB0aGlzLmVuZCA9IGVuZFxuICAgIH1cblxuICAgIGRyYXcod2lkdGgsIGhlaWdodCkge1xuICAgICAgICB0aGlzLndhbnRlZFdpZHRoID0gd2lkdGhcbiAgICAgICAgdGhpcy53YW50ZWRIZWlnaHQgPSBoZWlnaHRcbiAgICAgICAgdGhpcy5yZWRyYXcoKVxuICAgIH1cblxuICAgIHVwZGF0ZUNvbG9yUmFuZ2VzKHcsIGgpIHtcbiAgICAgICAgbGV0IHh4ID0gdyAtIHRoaXMuaW5zZXRcbiAgICAgICAgbGV0IHNpemUgPSBGb250SW5mby5zbWFsbC5mb250U2l6ZVxuICAgICAgICBsZXQgeXkgPSBoIC0gc2l6ZVxuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5jb2xvclJhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IGNyID0gdGhpcy5jb2xvclJhbmdlc1tpXVxuICAgICAgICAgICAgbGV0IGxhYmVsID0gY3IubGFiZWxcbiAgICAgICAgICAgIGNyLmRyYXcodGhpcywgdywgaClcbiAgICAgICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5lbnN1cmVMYWJlbCgnY29sb3JSYW5nZTonICsgbGFiZWwsIGxhYmVsLFxuICAgICAgICAgICAgICAgIHsgeDogeHgsIHk6IHl5LCBhbGlnbjogJ3JpZ2h0JyB9LCBGb250SW5mby5zbWFsbClcbiAgICAgICAgICAgIGxldCByID0gY3VycmVudC5nZXRCb3VuZHMoKVxuICAgICAgICAgICAgeHggLT0gci53aWR0aCArIDE2XG5cbiAgICAgICAgICAgIHRoaXMubGluZVN0eWxlKHNpemUsIGNyLmNvbG9yKVxuICAgICAgICAgICAgdGhpcy5tb3ZlVG8oeHgsIHl5KVxuICAgICAgICAgICAgdGhpcy5saW5lVG8oeHggKyBzaXplLCB5eSlcbiAgICAgICAgICAgIHh4IC09IHNpemUgKyA0XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkcmF3U2VsZWN0ZWRSYW1nZShzZWxlY3RlZCkge1xuICAgICAgICB0aGlzLmxpbmVTdHlsZSgyLCBhcHAudGhlbWUucHJpbWFyeUNvbG9yKVxuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnRvWChzZWxlY3RlZFswXSlcbiAgICAgICAgbGV0IGVuZCA9IHRoaXMudG9YKHNlbGVjdGVkWzFdKVxuICAgICAgICB0aGlzLm1vdmVUbyhzdGFydCwgMClcbiAgICAgICAgdGhpcy5saW5lVG8oZW5kLCAwKVxuICAgICAgICB0aGlzLmRyYXdUaWNrKHN0YXJ0LCAtMS41LCAwKVxuICAgICAgICB0aGlzLmRyYXdUaWNrKGVuZCwgLTEuNSwgMClcbiAgICB9XG5cbiAgICByZWRyYXcoKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKVxuICAgICAgICBsZXQgaCA9IHRoaXMud2FudGVkSGVpZ2h0XG4gICAgICAgIGxldCB3ID0gdGhpcy53YW50ZWRXaWR0aFxuICAgICAgICBsZXQgeSA9IHRoaXMuZ2V0WSgpXG4gICAgICAgIHRoaXMucHJlcGFyZUxhYmVscygpXG4gICAgICAgIHRoaXMudXBkYXRlQ29sb3JSYW5nZXModywgaClcblxuICAgICAgICB0aGlzLmxpbmVTdHlsZSgyLCAweEZGRkZGRilcbiAgICAgICAgaWYgKHRoaXMuc3RhcnQgIT0gbnVsbCAmJiB0aGlzLmVuZCAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1vdmVUbyh0aGlzLnRvWCh0aGlzLnN0YXJ0KSwgeSlcbiAgICAgICAgICAgIHRoaXMubGluZVRvKHRoaXMudG9YKHRoaXMuZW5kKSwgeSlcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVGlja3NBbmRMYWJlbHModywgaClcbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uKClcbiAgICAgICAgICAgIGxldCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uXG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRbMF0gIT0gdGhpcy5zdGFydCAmJiBzZWxlY3RlZFsxXSAhPSB0aGlzLmVuZCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNob3dSYW5nZSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3U2VsZWN0ZWRSYW1nZShzZWxlY3RlZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGNhbGxiYWNrIG9mIHRoaXMuY2FsbGJhY2tzKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5zY3JvbGwsIHRoaXMuem9vbSwgdGhpcy5zZWxlY3Rpb24pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1vdmVUbyh0aGlzLmluc2V0LCB5KVxuICAgICAgICAgICAgdGhpcy5saW5lVG8odyAtIHRoaXMuaW5zZXQsIHkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wcm9ncmVzcyAhPSBudWxsICYmIHRoaXMucHJvZ3Jlc3MgPCAxKSB7XG4gICAgICAgICAgICB0aGlzLmxpbmVTdHlsZSgyLCAweENDQ0NGRilcbiAgICAgICAgICAgIHRoaXMubW92ZVRvKHRoaXMuaW5zZXQsIHkpXG4gICAgICAgICAgICB0aGlzLmxpbmVUbygodyAtIHRoaXMuaW5zZXQpICogdGhpcy5wcm9ncmVzcywgeSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvdGFsV2lkdGgoYm91bmRlZCA9IGZhbHNlKSB7XG4gICAgICAgIGxldCB3ID0gdGhpcy53YW50ZWRXaWR0aCAtICgyICogdGhpcy5pbnNldClcbiAgICAgICAgcmV0dXJuIHcgKiB0aGlzLnZhbGlkWm9vbSh0aGlzLnpvb20sIGJvdW5kZWQpXG4gICAgfVxuXG4gICAgdmFsaWRab29tKHpvb20sIGJvdW5kZWQgPSB0cnVlKSB7XG4gICAgICAgIGxldCBvdmVyc2hvb3QgPSAoYm91bmRlZCkgPyAxLjAgOiAyLjBcbiAgICAgICAgem9vbSA9IE1hdGgubWF4KHpvb20sIHRoaXMubWluWm9vbSAvIG92ZXJzaG9vdClcbiAgICAgICAgem9vbSA9IE1hdGgubWluKHpvb20sIHRoaXMubWF4Wm9vbSAqIG92ZXJzaG9vdClcbiAgICAgICAgcmV0dXJuIHpvb21cbiAgICB9XG5cbiAgICBnZXRZKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53YW50ZWRIZWlnaHQgKiB0aGlzLmJhc2VMaW5lXG4gICAgfVxuXG4gICAgdG9YKGRhdGUpIHtcbiAgICAgICAgbGV0IHRvdGFsID0gdGhpcy5lbmQgLSB0aGlzLnN0YXJ0XG4gICAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmluc2V0ICsgdGhpcy5zY3JvbGxcbiAgICAgICAgbGV0IHdpZHRoID0gdGhpcy50b3RhbFdpZHRoKClcbiAgICAgICAgbGV0IGRlbHRhID0gZGF0ZSAtIHRoaXMuc3RhcnRcbiAgICAgICAgbGV0IHJhdGlvID0gZGVsdGEgLyB0b3RhbFxuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgcmF0aW8gKiB3aWR0aFxuICAgIH1cblxuICAgIGZyb21YKHZhbHVlKSB7XG4gICAgICAgIGxldCB0b3RhbCA9IHRoaXMuZW5kIC0gdGhpcy5zdGFydFxuICAgICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5pbnNldCArIHRoaXMuc2Nyb2xsXG4gICAgICAgIGxldCB3aWR0aCA9IHRoaXMudG90YWxXaWR0aCgpXG4gICAgICAgIGxldCByYXRpbyA9ICh2YWx1ZSAtIG9mZnNldCkgLyB3aWR0aFxuICAgICAgICBsZXQgdGltZSA9IHRoaXMuc3RhcnQuZ2V0VGltZSgpICsgdG90YWwgKiByYXRpb1xuICAgICAgICBsZXQgZGF0ZSA9IG5ldyBEYXRlKHRpbWUpXG4gICAgICAgIHJldHVybiBkYXRlXG4gICAgfVxuXG4gICAgZHJhd1RpY2soeCwgZGlyZWN0aW9uID0gMSwgeSA9IG51bGwpIHtcbiAgICAgICAgaWYgKHkgPT0gbnVsbCkge1xuICAgICAgICAgICAgeSA9IHRoaXMuZ2V0WSgpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tb3ZlVG8oeCwgeSlcbiAgICAgICAgdGhpcy5saW5lVG8oeCwgeSAtICh0aGlzLnRpY2tIZWlnaHQgKiBkaXJlY3Rpb24gKiB0aGlzLmRpcmVjdGlvbikpXG4gICAgfVxuXG4gICAgcHJlcGFyZUxhYmVscygpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMubGFiZWxzLmtleXMoKSkge1xuICAgICAgICAgICAgaWYgKCFrZXkuc3RhcnRzV2l0aCh0aGlzLmxhYmVsUHJlZml4KSlcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVscy5nZXQoa2V5KS52aXNpYmxlID0gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZVRpY2tzQW5kTGFiZWxzKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAgICAgdGhpcy5kcmF3VGljayh0aGlzLnRvWCh0aGlzLnN0YXJ0KSlcbiAgICAgICAgdGhpcy5kcmF3VGljayh0aGlzLnRvWCh0aGlzLmVuZCkpXG4gICAgICAgIHRoaXMudGltZXRpY2tzLmRyYXcodGhpcywgd2lkdGgsIGhlaWdodClcbiAgICAgICAgdGhpcy51cGRhdGVMYWJlbHMod2lkdGgsIGhlaWdodClcbiAgICB9XG5cbiAgICB2aXNpYmxlRGF0ZShkYXRlLCBvZmZzZXQgPSAwKSB7XG4gICAgICAgIGlmIChkYXRlID49IHRoaXMuc3RhcnQgJiYgZGF0ZSA8PSB0aGlzLmVuZCkge1xuICAgICAgICAgICAgbGV0IHggPSB0aGlzLnRvWChkYXRlKSArIG9mZnNldFxuICAgICAgICAgICAgcmV0dXJuICh4ID4gMCAmJiB4IDwgdGhpcy53YW50ZWRXaWR0aClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICB2aXNpYmxlUmFuZ2Uoc3RhcnQsIGVuZCkge1xuICAgICAgICBsZXQgeCA9IHRoaXMudG9YKHN0YXJ0KVxuICAgICAgICBpZiAoeCA+IHRoaXMud2FudGVkV2lkdGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgeCA9IHRoaXMudG9YKGVuZClcbiAgICAgICAgaWYgKHggPCAwKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgdGlja0xhYmVsT2Zmc2V0KGRpcmVjdGlvbiA9IDEsIGxldmVsID0gMCkge1xuICAgICAgICBsZXQgZnMgPSBGb250SW5mby5zbWFsbC5mb250U2l6ZVxuICAgICAgICBsZXQgZGggPSBmcyArIChsZXZlbCAqIChmcyArIDIpKVxuICAgICAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb24gKiBkaXJlY3Rpb24gKiBkaFxuICAgIH1cblxuICAgIHVwZGF0ZUxhYmVscyh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIGxldCBoMiA9IGhlaWdodCAvIDJcbiAgICAgICAgaWYgKHRoaXMubGFiZWxEYXRlcykge1xuICAgICAgICAgICAgbGV0IGxhc3QgPSBudWxsXG4gICAgICAgICAgICBsZXQgeSA9IGgyICsgdGhpcy50aWNrTGFiZWxPZmZzZXQoKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMubGFiZWxEYXRlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGxldCBbbGFiZWwsIGRhdGVdID0gdGhpcy5sYWJlbERhdGVzW2ldXG4gICAgICAgICAgICAgICAgbGV0IGFsaWduID0gJ2NlbnRlcicgLy8gKGxhc3QgPT0gbnVsbCkgPyAncmlnaHQnIDogJ2xlZnQnXG4gICAgICAgICAgICAgICAgbGV0IHggPSB0aGlzLnRvWChkYXRlKVxuICAgICAgICAgICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5lbnN1cmVMYWJlbCh0aGlzLmxhYmVsUHJlZml4ICsgbGFiZWwsIGxhYmVsLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiB4LCB5OiB5LFxuICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgRm9udEluZm8uc21hbGwpXG4gICAgICAgICAgICAgICAgbGV0IHIgPSBjdXJyZW50LmdldEJvdW5kcygpXG4gICAgICAgICAgICAgICAgY3VycmVudC52aXNpYmxlID0gIShsYXN0ICE9IG51bGwgJiYgci54ICsgci53aWR0aCA+IGxhc3QueClcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudC52aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhd1RpY2soeCwgLTEpXG4gICAgICAgICAgICAgICAgICAgIGxhc3QgPSByXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5zdGFydC50b0xvY2FsZURhdGVTdHJpbmcoJ2RlJywgeyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnbnVtZXJpYycsIGRheTogJ251bWVyaWMnIH0pXG4gICAgICAgICAgICBsZXQgZW5kID0gdGhpcy5lbmQudG9Mb2NhbGVEYXRlU3RyaW5nKCdkZScsIHsgeWVhcjogJ251bWVyaWMnLCBtb250aDogJ251bWVyaWMnLCBkYXk6ICdudW1lcmljJyB9KVxuICAgICAgICAgICAgdGhpcy5lbnN1cmVMYWJlbCh0aGlzLmxhYmVsUHJlZml4ICsgJ3N0YXJ0Jywgc3RhcnQsIHsgeDogdGhpcy50b1godGhpcy5zdGFydCksIHk6IGgyIH0pXG4gICAgICAgICAgICB0aGlzLmVuc3VyZUxhYmVsKHRoaXMubGFiZWxQcmVmaXggKyAnZW5kJywgZW5kLCB7IHg6IHRoaXMudG9YKHRoaXMuZW5kKSwgeTogaDIsIGFsaWduOiAncmlnaHQnIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblpvb20oem9vbSwgYW5jaG9yKSB7XG4gICAgICAgIGxldCBkYXRlID0gdGhpcy5mcm9tWChhbmNob3IueClcbiAgICAgICAgbGV0IG5ld1pvb20gPSB0aGlzLnZhbGlkWm9vbSh0aGlzLnpvb20gKiB6b29tLCBmYWxzZSlcbiAgICAgICAgdGhpcy56b29tID0gbmV3Wm9vbVxuICAgICAgICBsZXQgbmV3WCA9IHRoaXMudG9YKGRhdGUpXG4gICAgICAgIHRoaXMuc2Nyb2xsICs9IGFuY2hvci54IC0gbmV3WFxuICAgIH1cblxuICAgIG9uU3RhcnQoZXZlbnQsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIHRoaXMua2lsbFR3ZWVucygpXG4gICAgICAgIHRoaXMuZGVsdGFzID0gW11cbiAgICAgICAgdGhpcy52YWxpZFNjcm9sbCgpXG4gICAgICAgIFRocm93UHJvcHNQbHVnaW4udHJhY2sodGhpcywgJ2RlbHRhJylcbiAgICB9XG5cbiAgICBvbk1vdmUoZXZlbnQsIGludGVyYWN0aW9uKSB7XG4gICAgICAgIGxldCBkZWx0YSA9IGludGVyYWN0aW9uLmRlbHRhKClcbiAgICAgICAgdGhpcy5zY3JvbGwgKz0gZGVsdGEueFxuICAgICAgICB3aGlsZSAodGhpcy5kZWx0YXMubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgIHRoaXMuZGVsdGFzLnBvcCgwKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVsdGFzLnB1c2goZGVsdGEueClcbiAgICAgICAgaWYgKGludGVyYWN0aW9uLmN1cnJlbnQuc2l6ZSA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMub25ab29tKGRlbHRhLnpvb20sIGRlbHRhLmFib3V0KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVkcmF3KClcbiAgICB9XG5cbiAgICBvbkVuZChldmVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgbGV0IHZlbCA9IFRocm93UHJvcHNQbHVnaW4uZ2V0VmVsb2NpdHkodGhpcywgJ2RlbHRhJylcbiAgICAgICAgVGhyb3dQcm9wc1BsdWdpbi51bnRyYWNrKHRoaXMpXG5cbiAgICAgICAgdGhpcy5raWxsVHdlZW5zKClcbiAgICAgICAgdGhpcy5yZWRyYXcoKVxuICAgICAgICBsZXQgZGVsdGEgPSAwXG4gICAgICAgIGZvciAobGV0IGQgb2YgdGhpcy5kZWx0YXMpIHtcbiAgICAgICAgICAgIGRlbHRhICs9IGRcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kZWx0YXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZGVsdGEgLz0gdGhpcy5kZWx0YXMubGVuZ3RoXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hdXRvU2Nyb2xsID0gdHJ1ZVxuICAgICAgICBsZXQgYW5jaG9yID0gaW50ZXJhY3Rpb24uY3VycmVudC5tZWFuKClcbiAgICAgICAgdGhpcy5rZWVwSW5Cb3VuZHMoZGVsdGEsIGFuY2hvcilcblxuICAgICAgICBmb3IobGV0IGtleSBvZiBpbnRlcmFjdGlvbi5lbmRlZC5rZXlzKCkpIHtcbiAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi5pc0RvdWJsZVRhcChrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkRvdWJsZVRhcChldmVudCwgaW50ZXJhY3Rpb24sIGtleSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGludGVyYWN0aW9uLmlzVGFwKGtleSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uVGFwKGV2ZW50LCBpbnRlcmFjdGlvbiwga2V5KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaW50ZXJhY3Rpb24uaXNMb25nUHJlc3Moa2V5KSkge1xuICAgICAgICAgICAgICAgIHRoaXMub25Mb25nUHJlc3MoZXZlbnQsIGludGVyYWN0aW9uLCBrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkxvbmdQcmVzcyhldmVudCwgaW50ZXJhY3Rpb24sIGtleSkge1xuICAgICAgICBmb3IobGV0IGNhbGxiYWNrIG9mIHRoaXMub25Mb25nUHJlc3NDYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LCBpbnRlcmFjdGlvbiwga2V5KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25UYXAoZXZlbnQsIGludGVyYWN0aW9uLCBrZXkpIHtcbiAgICAgICAgZm9yKGxldCBjYWxsYmFjayBvZiB0aGlzLm9uVGFwQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudCwgaW50ZXJhY3Rpb24sIGtleSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uRG91YmxlVGFwKGV2ZW50LCBpbnRlcmFjdGlvbiwga2V5KSB7XG4gICAgICAgIGZvcihsZXQgY2FsbGJhY2sgb2YgdGhpcy5vbkRvdWJsZVRhcENhbGxiYWNrcykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQsIGludGVyYWN0aW9uLCBrZXkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc2Nyb2xsTWluaW11bShib3VuZGVkKSB7XG4gICAgICAgIGxldCB0b3RhbCA9IHRoaXMudG90YWxXaWR0aChib3VuZGVkKVxuICAgICAgICByZXR1cm4gLXRvdGFsICsgdGhpcy53YW50ZWRXaWR0aCAtIDIgKiB0aGlzLmluc2V0XG4gICAgfVxuXG4gICAgX3Njcm9sbE1heGltdW0oYm91bmRlZCkge1xuICAgICAgICBsZXQgdG90YWwgPSB0aGlzLnRvdGFsV2lkdGgoYm91bmRlZClcbiAgICAgICAgbGV0IGxpbWl0ID0gdGhpcy53YW50ZWRXaWR0aFxuICAgICAgICBpZiAodG90YWwgPiBsaW1pdClcbiAgICAgICAgICAgIHJldHVybiAwXG4gICAgICAgIGxldCB3ID0gbGltaXQgLSAyICogdGhpcy5pbnNldFxuICAgICAgICByZXR1cm4gKHcgLSB0b3RhbCkgLyAyXG4gICAgfVxuXG4gICAgc2Nyb2xsTWluaW11bShib3VuZGVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY3JvbGxNaW5pbXVtKGJvdW5kZWQpIC0gdGhpcy5leHRyYVJpZ2h0XG4gICAgfVxuXG4gICAgc2Nyb2xsTWF4aW11bShib3VuZGVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY3JvbGxNYXhpbXVtKGJvdW5kZWQpICsgdGhpcy5leHRyYUxlZnRcbiAgICB9XG5cbiAgICBraWxsVHdlZW5zKCkge1xuICAgICAgICBUd2VlbkxpdGUua2lsbFR3ZWVuc09mKHRoaXMpXG4gICAgICAgIHRoaXMuYXV0b1Njcm9sbCA9IGZhbHNlXG4gICAgfVxuXG5cbiAgICB2YWxpZFNjcm9sbChib3VuZGVkID0gdHJ1ZSkge1xuICAgICAgICBsZXQgbWluaW11bSA9IHRoaXMuc2Nyb2xsTWluaW11bShib3VuZGVkKVxuICAgICAgICBsZXQgbWF4aW11bSA9IHRoaXMuc2Nyb2xsTWF4aW11bShib3VuZGVkKVxuICAgICAgICBpZiAodGhpcy5zY3JvbGwgPCBtaW5pbXVtKSB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbCA9IG1pbmltdW1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zY3JvbGwgPiBtYXhpbXVtKSB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbCA9IG1heGltdW1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGtlZXBJbkJvdW5kcyhkZWx0YSwgYW5jaG9yKSB7XG4gICAgICAgIGxldCBib3VuZGVkID0gdHJ1ZVxuICAgICAgICBsZXQgbWluaW11bSA9IHRoaXMuc2Nyb2xsTWluaW11bShib3VuZGVkKVxuICAgICAgICBsZXQgbWF4aW11bSA9IHRoaXMuc2Nyb2xsTWF4aW11bShib3VuZGVkKVxuICAgICAgICBsZXQgdHdlZW5zID0ge31cbiAgICAgICAgaWYgKHRoaXMuem9vbSA+IHRoaXMubWF4Wm9vbSkge1xuICAgICAgICAgICAgdHdlZW5zLnpvb20gPSB0aGlzLm1heFpvb21cbiAgICAgICAgICAgIGxldCBkYXRlID0gdGhpcy5mcm9tWChhbmNob3IueClcbiAgICAgICAgICAgIGxldCBvbGRab29tID0gdGhpcy56b29tXG4gICAgICAgICAgICB0aGlzLnpvb20gPSB0aGlzLm1heFpvb21cbiAgICAgICAgICAgIGxldCBuZXdYID0gdGhpcy50b1goZGF0ZSlcbiAgICAgICAgICAgIHR3ZWVucy5zY3JvbGwgPSB0aGlzLnNjcm9sbCArIGFuY2hvci54IC0gbmV3WFxuICAgICAgICAgICAgdGhpcy56b29tID0gb2xkWm9vbVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuem9vbSA8IHRoaXMubWluWm9vbSkge1xuICAgICAgICAgICAgICAgIHR3ZWVucy56b29tID0gdGhpcy5taW5ab29tXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zY3JvbGwgPiBtYXhpbXVtKSB7XG4gICAgICAgICAgICAgICAgdHdlZW5zLnNjcm9sbCA9IG1heGltdW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNjcm9sbCA8IG1pbmltdW0pIHtcbiAgICAgICAgICAgICAgICB0d2VlbnMuc2Nyb2xsID0gbWluaW11bVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghaXNFbXB0eSh0d2VlbnMpKSB7XG4gICAgICAgICAgICB0d2VlbnMub25VcGRhdGUgPSAoKSA9PiB7IHRoaXMucmVkcmF3KCkgfVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMsIDAuNSwgdHdlZW5zKS5kZWxheSgwLjEpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNjcm9sbCArPSBkZWx0YVxuICAgICAgICBkZWx0YSAqPSAwLjk4NVxuICAgICAgICB0aGlzLnJlZHJhdygpXG4gICAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPiAxICYmIHRoaXMuYXV0b1Njcm9sbCkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmtlZXBJbkJvdW5kcyhkZWx0YSwgYW5jaG9yKSwgMTAwMCAvIDEwMClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTW91c2VXaGVlbChldmVudCkge1xuICAgICAgICB0aGlzLmtpbGxUd2VlbnMoKVxuICAgICAgICBsZXQgZGlyZWN0aW9uID0gZXZlbnQuZGV0YWlsIDwgMCB8fCBldmVudC53aGVlbERlbHRhID4gMFxuICAgICAgICBsZXQgYW5jaG9yID0geyB4OiBldmVudC5jbGllbnRYLCB5OiBldmVudC5jbGllbnRZIH1cbiAgICAgICAgY29uc3Qgem9vbUZhY3RvciA9IDEuNVxuICAgICAgICB0aGlzLm9uWm9vbSgoZGlyZWN0aW9uKSA/IHpvb21GYWN0b3IgOiAxIC8gem9vbUZhY3RvciwgYW5jaG9yKVxuICAgICAgICB0aGlzLnJlZHJhdygpXG4gICAgICAgIHRoaXMua2VlcEluQm91bmRzKDAsIGFuY2hvcilcbiAgICB9XG5cbiAgICBzaG93UmFuZ2VzKHJhbmdlcywgbGFiZWwgPSBcIlVudGl0bGVkXCIsIGNvbG9yID0gbnVsbCkge1xuICAgICAgICBmb3IgKGxldCBjciBvZiB0aGlzLmNvbG9yUmFuZ2VzKSB7XG4gICAgICAgICAgICBpZiAoY3IubGFiZWwgPT0gbGFiZWwpXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuY29sb3JSYW5nZXMubGVuZ3RoID49IHRoaXMucmFuZ2VDb2xvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmNvbG9yUmFuZ2VzLnNoaWZ0KClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbG9yUmFuZ2VzLnB1c2gobmV3IENvbG9yUmFuZ2VzKGxhYmVsLCBjb2xvciwgcmFuZ2VzKSlcbiAgICAgICAgdGhpcy5yZWRyYXcoKVxuICAgIH1cbn1cblxuIiwiaW1wb3J0IFRoZW1lIGZyb20gJy4vdGhlbWUuanMnXG5pbXBvcnQgVG9vbHRpcCBmcm9tICcuL3Rvb2x0aXAuanMnXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBzbGlkZXIgYWN0aW9uIG9uU3RhcnQuXG4gKlxuICogQGNhbGxiYWNrIG9uU3RhcnRDYWxsYmFja1xuICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7U2xpZGVyfSBzbGlkZXIgLSBBIHJlZmVyZW5jZSB0byB0aGUgc2xpZGVyIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBzbGlkZXIpLlxuICovXG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBzbGlkZXIgYWN0aW9uIG9uVXBkYXRlLlxuICpcbiAqIEBjYWxsYmFjayBvblVwZGF0ZUNhbGxiYWNrXG4gKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBUaGUgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtTbGlkZXJ9IHNsaWRlciAtIEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgKGFsc28gdGhpcyByZWZlcnMgdG8gdGhlIHNsaWRlcikuXG4gKi9cblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIHNsaWRlciBhY3Rpb24gb25Db21wbGV0ZS5cbiAqXG4gKiBAY2FsbGJhY2sgb25Db21wbGV0ZUNhbGxiYWNrXG4gKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBUaGUgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtTbGlkZXJ9IHNsaWRlciAtIEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgKGFsc28gdGhpcyByZWZlcnMgdG8gdGhlIHNsaWRlcikuXG4gKi9cblxuLyoqXG4gKiBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBQaXhpSlMgU2xpZGVyLlxuICogXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIHRoZSBhcHBcbiAqIGNvbnN0IGFwcCA9IG5ldyBQSVhJQXBwKHtcbiAqICAgICB2aWV3OiBjYW52YXMsXG4gKiAgICAgd2lkdGg6IDkwMCxcbiAqICAgICBoZWlnaHQ6IDI1MFxuICogfSkuc2V0dXAoKS5ydW4oKVxuICogXG4gKiAvLyBDcmVhdGUgdGhlIHNsaWRlclxuICogY29uc3Qgc2xpZGVyID0gbmV3IFNsaWRlcih7XG4gKiAgICAgeDogMTAsXG4gKiAgICAgeTogMjBcbiAqIH0pXG4gKlxuICogLy8gQWRkIHRoZSBzbGlkZXIgdG8gYSBEaXNwbGF5T2JqZWN0XG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQoc2xpZGVyKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5Db250YWluZXJcbiAqIEBzZWUge0BsaW5rIGh0dHA6Ly9waXhpanMuZG93bmxvYWQvZGV2L2RvY3MvUElYSS5Db250YWluZXIuaHRtbHxQSVhJLkNvbnRhaW5lcn1cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS9zbGlkZXIuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTbGlkZXIgZXh0ZW5kcyBQSVhJLkNvbnRhaW5lciB7XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFNsaWRlci5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBzbGlkZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmlkPWF1dG8gZ2VuZXJhdGVkXSAtIFRoZSBpZCBvZiB0aGUgc2xpZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy54PTBdIC0gVGhlIHggcG9zaXRpb24gb2YgdGhlIHNsaWRlci4gQ2FuIGJlIGFsc28gc2V0IGFmdGVyIGNyZWF0aW9uIHdpdGggc2xpZGVyLnggPSAwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy55PTBdIC0gVGhlIHkgcG9zaXRpb24gb2YgdGhlIHNsaWRlci4gQ2FuIGJlIGFsc28gc2V0IGFmdGVyIGNyZWF0aW9uIHdpdGggc2xpZGVyLnkgPSAwLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFRoZW1lfSBbb3B0cy50aGVtZT1kYXJrXSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHRoaXMgc2xpZGVyLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGRhcmssIGxpZ2h0LCByZWRcbiAgICAgKiAgICAgb3IgYSBUaGVtZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLndpZHRoPTI1MF0gLSBUaGUgd2lkdGggb2YgdGhlIHNsaWRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaGVpZ2h0PTJdIC0gVGhlIGhlaWdodCBvZiB0aGUgc2xpZGVyLlxuICAgICAqIEBwYXJhbSB7UElYSS5EaXNwbGF5T2JqZWN0fSBbb3B0cy5jb250YWluZXI9d2luZG93LmFwcHxvYmplY3RdIC0gVGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgc2xpZGVyIGV2ZW50cyBzaG91bGQgYmUgYXR0YWNoZWQgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGw9VGhlbWUuZmlsbF0gLSBUaGUgY29sb3Igb2YgdGhlIHNsaWRlciBiYWNrZ3JvdW5kIGFzIGEgaGV4IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsQWxwaGE9VGhlbWUuZmlsbEFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlPVRoZW1lLnN0cm9rZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlV2lkdGg9VGhlbWUuc3Ryb2tlV2lkdGhdIC0gVGhlIHdpZHRoIG9mIHRoZSBib3JkZXIgaW4gcGl4ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sRmlsbD1UaGVtZS5zdHJva2VdIC0gVGhlIGNvbG9yIG9mIHRoZSBzbGlkZXIgY29udHJvbCBiYWNrZ3JvdW5kIGFzIGEgaGV4IHZhbHVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sRmlsbEFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29udHJvbFN0cm9rZT1UaGVtZS5zdHJva2VdIC0gVGhlIGNvbG9yIG9mIHRoZSBib3JkZXIgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNvbnRyb2xTdHJva2VXaWR0aD1UaGVtZS5zdHJva2VXaWR0aCAqIDAuOF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29udHJvbFN0cm9rZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sUmFkaXVzPTE2XSAtIFRoZSByYWRpdXMgb2YgdGhlIHNsaWRlciBjb250cm9sLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZGlzYWJsZWQ9ZmFsc2VdIC0gSXMgdGhlIHNsaWRlciBkaXNhYmxlZD8gV2hlbiBkaXNhYmxlZCwgdGhlIHNsaWRlciBoYXMgYSBsb3dlciBhbHBoYSB2YWx1ZVxuICAgICAqICAgICBhbmQgY2Fubm90IGJlIGNsaWNrZWQgKGludGVyYWN0aXZlIGlzIHNldCB0byBmYWxzZSkuXG4gICAgICogQHBhcmFtIHtvblN0YXJ0Q2FsbGJhY2t9IFtvcHRzLm9uU3RhcnRdIC0gRXhlY3V0ZWQgd2hlbiB0aGUgc2xpZGVyIGNvbnRyb2wgc3RhcnRzIHRvIG1vdmUuXG4gICAgICogQHBhcmFtIHtvblVwZGF0ZUNhbGxiYWNrfSBbb3B0cy5vblVwZGF0ZV0gLSBFeGVjdXRlZCB3aGVuIHRoZSBzbGlkZXIgY29udHJvbCBpcyBtb3ZlZC5cbiAgICAgKiBAcGFyYW0ge29uQ29tcGxldGVDYWxsYmFja30gW29wdHMub25Db21wbGV0ZV0gLSBFeGVjdXRlZCB3aGVuIHRoZSBzbGlkZXIgY29udHJvbCB3YXMgZHJvcHBlZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IFtvcHRzLnRvb2x0aXBdIC0gQSBzdHJpbmcgZm9yIHRoZSBsYWJlbCBvZiB0aGUgdG9vbHRpcCBvciBhbiBvYmplY3QgdG8gY29uZmlndXJlIHRoZSB0b29sdGlwXG4gICAgICogICAgIHRvIGRpc3BsYXkuIFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudmlzaWJsZT10cnVlXSAtIElzIHRoZSBzbGlkZXIgaW5pdGlhbGx5IHZpc2libGUgKHByb3BlcnR5IHZpc2libGUpP1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICB0aGlzLnRoZW1lID0gdGhlbWVcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBpZDogUElYSS51dGlscy51aWQoKSxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgd2lkdGg6IDI1MCxcbiAgICAgICAgICAgIGhlaWdodDogMixcbiAgICAgICAgICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIHN0cm9rZTogdGhlbWUuc3Ryb2tlLFxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoZW1lLnN0cm9rZVdpZHRoLFxuICAgICAgICAgICAgc3Ryb2tlQWxwaGE6IHRoZW1lLnN0cm9rZUFscGhhLFxuICAgICAgICAgICAgY29udHJvbEZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBjb250cm9sRmlsbEFscGhhOiAuNSxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2U6IHRoZW1lLnByaW1hcnlDb2xvcixcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VXaWR0aDogMixcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VBbHBoYTogdGhlbWUuc3Ryb2tlQWxwaGEsXG4gICAgICAgICAgICBjb250cm9sUmFkaXVzOiAxNixcbiAgICAgICAgICAgIG9yaWVudGF0aW9uOiAnaG9yaXpvbnRhbCcsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgb25TdGFydDogbnVsbCxcbiAgICAgICAgICAgIG9uVXBkYXRlOiBudWxsLFxuICAgICAgICAgICAgb25Db21wbGV0ZTogbnVsbCxcbiAgICAgICAgICAgIHRvb2x0aXA6IG51bGwsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG4gICAgICAgIFxuICAgICAgICB0aGlzLm9wdHMuY29udGFpbmVyID0gdGhpcy5vcHRzLmNvbnRhaW5lciB8fCB0aGlzXG5cbiAgICAgICAgLy8gVmFsaWRhdGlvblxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMuaGVpZ2h0ID4gdGhpcy5vcHRzLndpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLm9wdHMuaGVpZ2h0ID0gdGhpcy5vcHRzLndpZHRoXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5vcHRzLnZhbHVlIDwgdGhpcy5vcHRzLm1pbikge1xuICAgICAgICAgICAgdGhpcy5vcHRzLnZhbHVlID0gdGhpcy5vcHRzLm1pblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3B0cy52YWx1ZSA+IHRoaXMub3B0cy5tYXgpIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy52YWx1ZSA9IHRoaXMub3B0cy5tYXhcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb3BlcnRpZXNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmlkID0gdGhpcy5vcHRzLmlkXG4gICAgICAgIHRoaXMucmFkaXVzID0gdGhpcy5vcHRzLmhlaWdodCAvIDJcblxuICAgICAgICB0aGlzLl92YWx1ZSA9IHRoaXMub3B0cy52YWx1ZVxuICAgICAgICB0aGlzLl9kaXNhYmxlZCA9IG51bGxcblxuICAgICAgICB0aGlzLnNsaWRlck9iaiA9IG51bGxcbiAgICAgICAgdGhpcy5jb250cm9sID0gbnVsbFxuICAgICAgICB0aGlzLnRvb2x0aXAgPSBudWxsXG4gICAgICAgIFxuICAgICAgICB0aGlzLnZpc2libGUgPSB0aGlzLm9wdHMudmlzaWJsZVxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG5cbiAgICAgICAgLy8gbGF5b3V0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGNoaWxkcmVuIGFuZCBpbnN0YW50aWF0ZXMgZXZlcnl0aGluZy5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1NsaWRlcn0gQSByZWZlcmVuY2UgdG8gdGhlIHNsaWRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG5cbiAgICAgICAgLy8gQ29udGFpbmVyIGV2ZW50c1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMub3B0cy5jb250YWluZXJcblxuICAgICAgICB0aGlzLm9uKCdwb2ludGVybW92ZScsIGUgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udHJvbC5kcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1vdmVYID0gdGhpcy5jb250cm9sLmV2ZW50LmRhdGEuZ2V0TG9jYWxQb3NpdGlvbih0aGlzLmNvbnRyb2wucGFyZW50KS54XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB0aGlzLnBpeGVsVG9WYWx1ZShtb3ZlWCAtIHRoaXMuY29udHJvbC5kZWx0YSAtIHRoaXMub3B0cy5jb250cm9sUmFkaXVzKVxuICAgICAgICAgICAgICAgIGxldCB4ID0gdGhpcy52YWx1ZVRvUGl4ZWwodGhpcy5fdmFsdWUpICsgdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRyb2wueCA9IHhcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMub25VcGRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLm9uVXBkYXRlLmNhbGwodGhpcywgZSwgdGhpcylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYgKGNvbnRhaW5lciBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlID0+IHRoaXMub25FbmQoZSksIGZhbHNlKVxuICAgICAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBlID0+IHRoaXMub25FbmQoZSksIGZhbHNlKVxuICAgICAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJsZWF2ZScsIGUgPT4gdGhpcy5vbkVuZChlKSwgZmFsc2UpXG4gICAgICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm91dCcsIGUgPT4gdGhpcy5vbkVuZChlKSwgZmFsc2UpXG4gICAgICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIGUgPT4gdGhpcy5vbkVuZChlKSwgZmFsc2UpXG4gICAgICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VjYW5jZWwnLCBlID0+IHRoaXMub25FbmQoZSksIGZhbHNlKVxuICAgICAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBlID0+IHRoaXMub25FbmQoZSksIGZhbHNlKVxuICAgICAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgZSA9PiB0aGlzLm9uRW5kKGUpLCBmYWxzZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgICAgIGNvbnRhaW5lci5vbigncG9pbnRlcnVwJywgZSA9PiB0aGlzLm9uRW5kKGUpKVxuICAgICAgICAgICAgY29udGFpbmVyLm9uKCdwb2ludGVyY2FuY2VsJywgZSA9PiB0aGlzLm9uRW5kKGUpKVxuICAgICAgICAgICAgY29udGFpbmVyLm9uKCdwb2ludGVybGVhdmUnLCBlID0+IHRoaXMub25FbmQoZSkpXG4gICAgICAgICAgICBjb250YWluZXIub24oJ3BvaW50ZXJvdXQnLCBlID0+IHRoaXMub25FbmQoZSkpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTbGlkZXJcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBsZXQgc2xpZGVyT2JqID0gbmV3IFBJWEkuR3JhcGhpY3MoKVxuICAgICAgICB0aGlzLnNsaWRlck9iaiA9IHNsaWRlck9ialxuICAgICAgICB0aGlzLmFkZENoaWxkKHNsaWRlck9iailcblxuICAgICAgICAvLyBDb250cm9sXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgbGV0IGNvbnRyb2wgPSBuZXcgUElYSS5HcmFwaGljcygpXG4gICAgICAgIGNvbnRyb2wueCA9IHRoaXMub3B0cy5jb250cm9sUmFkaXVzICsgdGhpcy52YWx1ZVRvUGl4ZWwodGhpcy5vcHRzLnZhbHVlKVxuICAgICAgICBjb250cm9sLnkgPSB0aGlzLm9wdHMuY29udHJvbFJhZGl1c1xuXG4gICAgICAgIC8vIHBvaW50ZXJkb3duIG9uIHRoZSBjb250cm9sIGZvciBkcmFnbmRyb3BcbiAgICAgICAgY29udHJvbC5vbigncG9pbnRlcmRvd24nLCBlID0+IHtcbiAgICAgICAgICAgIGNvbnRyb2wuZXZlbnQgPSBlXG4gICAgICAgICAgICBjb250cm9sLmRlbHRhID0gZS5kYXRhLmdldExvY2FsUG9zaXRpb24odGhpcy5jb250cm9sKS54XG4gICAgICAgICAgICBjb250cm9sLmRyYWdnaW5nID0gdHJ1ZVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLm9uU3RhcnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMub25TdGFydC5jYWxsKHRoaXMsIGUsIHRoaXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5jb250cm9sID0gY29udHJvbFxuXG4gICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5jb250cm9sKVxuICAgICAgICBcbiAgICAgICAgLy8gaW50ZXJhY3Rpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnNsaWRlck9iai5vbigncG9pbnRlcm92ZXInLCBlID0+IHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNvbnRyb2wsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAuODN9KVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLm9uKCdwb2ludGVyb3V0JywgZSA9PiB7XG4gICAgICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jb250cm9sLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogMX0pXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5zbGlkZXJPYmoub24oJ3BvaW50ZXJkb3duJywgZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNsaWRlck9iai5wb2ludGVyZG93bmVkID0gdHJ1ZVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuY29udHJvbCwgdGhpcy50aGVtZS5mYXN0LCB7YWxwaGE6IC43fSlcbiAgICAgICAgfSlcblxuICAgICAgICAvLyBDbGljayBvbiB0aGUgc2xpZGVyIGJhclxuICAgICAgICB0aGlzLnNsaWRlck9iai5vbigncG9pbnRlcnVwJywgZSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zbGlkZXJPYmoucG9pbnRlcmRvd25lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2xpZGVyT2JqLnBvaW50ZXJkb3duZWQgPSBmYWxzZVxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZS5kYXRhLmdldExvY2FsUG9zaXRpb24odGhpcy5jb250cm9sLnBhcmVudClcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5waXhlbFRvVmFsdWUocG9zaXRpb24ueCAtIHRoaXMub3B0cy5jb250cm9sUmFkaXVzKVxuICAgICAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNvbnRyb2wsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAuODN9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIC8vIGRpc2FibGVkXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IHRoaXMub3B0cy5kaXNhYmxlZFxuICAgICAgICBcbiAgICAgICAgLy8gdG9vbHRpcFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGlmICh0aGlzLm9wdHMudG9vbHRpcCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdHMudG9vbHRpcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvb2x0aXAgPSBuZXcgVG9vbHRpcCh7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdDogdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogdGhpcy5vcHRzLnRvb2x0aXBcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMudG9vbHRpcC5vYmplY3QgPSB0aGlzXG4gICAgICAgICAgICAgICAgdGhpcy50b29sdGlwID0gbmV3IFRvb2x0aXAodGhpcy5vcHRzLnRvb2x0aXApXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBTaG91bGQgYmUgY2FsbGVkIHRvIHJlZnJlc2ggdGhlIGxheW91dCBvZiB0aGUgc2xpZGVyLiBDYW4gYmUgdXNlZCBhZnRlciByZXNpemluZy5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9IEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcbiAgICAgICAgXG4gICAgICAgIC8vIHNldCBwb3NpdGlvblxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucG9zaXRpb24uc2V0KHRoaXMub3B0cy54LCB0aGlzLm9wdHMueSlcblxuICAgICAgICAvLyBkcmF3XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5kcmF3KClcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBEcmF3cyB0aGUgc2xpZGVyIHRvIHRoZSBjYW52YXMuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9IEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGRyYXcoKSB7XG5cbiAgICAgICAgY29uc3QgciA9IHRoaXMucmFkaXVzXG4gICAgICAgIGNvbnN0IGNyID0gdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNcbiAgICAgICAgY29uc3QgdyA9IHRoaXMub3B0cy53aWR0aFxuICAgICAgICBjb25zdCBoID0gdGhpcy5vcHRzLmhlaWdodFxuICAgICAgICBjb25zdCB4ID0gY3IgKyByXG4gICAgICAgIGNvbnN0IHkgPSBjciArIHIgLSBoXG5cbiAgICAgICAgdGhpcy5zbGlkZXJPYmouY2xlYXIoKVxuICAgICAgICB0aGlzLnNsaWRlck9iai5iZWdpbkZpbGwoMHhmZmZmZmYsIDApXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLmRyYXdSZWN0KDAsIDAsIHggKyB3ICsgY3IsIGNyICogMilcbiAgICAgICAgdGhpcy5zbGlkZXJPYmoubGluZVN0eWxlKHRoaXMub3B0cy5zdHJva2VXaWR0aCwgdGhpcy5vcHRzLnN0cm9rZSwgdGhpcy5vcHRzLnN0cm9rZUFscGhhKVxuICAgICAgICB0aGlzLnNsaWRlck9iai5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGwsIHRoaXMub3B0cy5maWxsQWxwaGEpXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLm1vdmVUbyh4LCB5KVxuICAgICAgICB0aGlzLnNsaWRlck9iai5saW5lVG8oeCArIHcsIHkpXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLmFyY1RvKHggKyB3ICsgciwgeSwgeCArIHcgKyByLCB5ICsgciwgcilcbiAgICAgICAgdGhpcy5zbGlkZXJPYmoubGluZVRvKHggKyB3ICsgciwgeSArIHIgKyAxKSAgICAgICAgICAgICAgICAgICAgIC8vIEJVR0ZJWDogSWYgbm90IHNwZWNpZmllZCwgdGhlcmUgaXMgYSBzbWFsbCBhcmVhIHdpdGhvdXQgYSBzdHJva2UuXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLmFyY1RvKHggKyB3ICsgciwgeSArIGgsIHggKyB3LCB5ICsgaCwgcilcbiAgICAgICAgdGhpcy5zbGlkZXJPYmoubGluZVRvKHgsIHkgKyBoKVxuICAgICAgICB0aGlzLnNsaWRlck9iai5hcmNUbyh4IC0gciwgeSArIGgsIHggLSByLCB5ICsgciwgcilcbiAgICAgICAgdGhpcy5zbGlkZXJPYmouYXJjVG8oeCAtIHIsIHksIHgsIHksIHIpXG4gICAgICAgIHRoaXMuc2xpZGVyT2JqLmVuZEZpbGwoKVxuXG4gICAgICAgIC8vIERyYXcgY29udHJvbFxuICAgICAgICB0aGlzLmNvbnRyb2wuY2xlYXIoKVxuICAgICAgICB0aGlzLmNvbnRyb2wubGluZVN0eWxlKHRoaXMub3B0cy5jb250cm9sU3Ryb2tlV2lkdGgsIHRoaXMub3B0cy5jb250cm9sU3Ryb2tlLCB0aGlzLm9wdHMuY29udHJvbFN0cm9rZUFscGhhKVxuICAgICAgICB0aGlzLmNvbnRyb2wuYmVnaW5GaWxsKHRoaXMub3B0cy5jb250cm9sRmlsbCwgdGhpcy5vcHRzLmNvbnRyb2xGaWxsQWxwaGEpXG4gICAgICAgIHRoaXMuY29udHJvbC5kcmF3Q2lyY2xlKDAsIDAsIGNyIC0gMSlcbiAgICAgICAgdGhpcy5jb250cm9sLmJlZ2luRmlsbCh0aGlzLm9wdHMuY29udHJvbFN0cm9rZSwgdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBbHBoYSlcbiAgICAgICAgdGhpcy5jb250cm9sLmRyYXdDaXJjbGUoMCwgMCwgY3IgLyA2KVxuICAgICAgICB0aGlzLmNvbnRyb2wuZW5kRmlsbCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlZCwgd2hlbiB0aGUgc2xpZGVyIGNvbnRyb2wgbW92ZW1lbnQgZW5kZWQuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9IEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIG9uRW5kKGUpIHtcblxuICAgICAgICBpZiAodGhpcy5jb250cm9sLmRyYWdnaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wuZXZlbnQgPSBudWxsXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wuZHJhZ2dpbmcgPSBmYWxzZVxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5vbkNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRzLm9uQ29tcGxldGUuY2FsbCh0aGlzLCBlLCB0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSB2YWx1ZSBmb3IgYSBnaXZlbiBwaXhlbC5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBcbiAgICAgKiBAcmV0dXJucyAge251bWJlcn0gVGhlIGNhbHVjYWx0ZWQgcGl4ZWwuXG4gICAgICovXG4gICAgdmFsdWVUb1BpeGVsKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA8IHRoaXMub3B0cy5taW4pIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5vcHRzLm1pblxuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID4gdGhpcy5vcHRzLm1heCkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLm9wdHMubWF4XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMub3B0cy53aWR0aCAqICh2YWx1ZSAtIHRoaXMub3B0cy5taW4pIC8gKHRoaXMub3B0cy5tYXggLSB0aGlzLm9wdHMubWluKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHBpeGVsIGZvciBhIGdpdmVuIHZhbHVlLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsIFxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBjYWx1Y2FsdGVkIHZhbHVlLlxuICAgICAqL1xuICAgIHBpeGVsVG9WYWx1ZShwaXhlbCkge1xuICAgICAgICBpZiAocGl4ZWwgPCAwKSB7XG4gICAgICAgICAgICBwaXhlbCA9IDBcbiAgICAgICAgfSBlbHNlIGlmIChwaXhlbCA+IHRoaXMub3B0cy53aWR0aCkge1xuICAgICAgICAgICAgcGl4ZWwgPSB0aGlzLm9wdHMud2lkdGhcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5vcHRzLm1pbiArICgodGhpcy5vcHRzLm1heCAtIHRoaXMub3B0cy5taW4pICogcGl4ZWwgLyB0aGlzLm9wdHMud2lkdGgpXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIEdldHMgb3Igc2V0cyB0aGUgdmFsdWUuXG4gICAgICogXG4gICAgICogQG1lbWJlciB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQodGhpcy5fdmFsdWUpXG4gICAgfVxuICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgPCB0aGlzLm9wdHMubWluKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMub3B0cy5taW5cbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA+IHRoaXMub3B0cy5tYXgpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5vcHRzLm1heFxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWVcblxuICAgICAgICBjb25zdCB4ID0gdGhpcy52YWx1ZVRvUGl4ZWwodmFsdWUpICsgdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNcblxuICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jb250cm9sLCB0aGlzLnRoZW1lLmZhc3QsIHt4fSlcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBkaXNhYmxlZCBzdGF0ZS4gV2hlbiBkaXNhYmxlZCwgdGhlIHNsaWRlciBjYW5ub3QgYmUgY2xpY2tlZC5cbiAgICAgKiBcbiAgICAgKiBAbWVtYmVyIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBkaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkXG4gICAgfVxuICAgIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuXG4gICAgICAgIHRoaXMuX2Rpc2FibGVkID0gdmFsdWVcbiAgICAgICAgXG4gICAgICAgIGlmICh0aGlzLl9kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLnNsaWRlck9iai5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wuaW50ZXJhY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5jb250cm9sLmJ1dHRvbk1vZGUgPSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5hbHBoYSA9IC41XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gdHJ1ZVxuICAgICAgICAgICAgdGhpcy5zbGlkZXJPYmouaW50ZXJhY3RpdmUgPSB0cnVlXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wuaW50ZXJhY3RpdmUgPSB0cnVlXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wuYnV0dG9uTW9kZSA9IHRydWVcbiAgICAgICAgICAgIHRoaXMuYWxwaGEgPSAxXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgc2xpZGVyIChzZXRzIGhpcyBhbHBoYSB2YWx1ZXMgdG8gMSkuXG4gICAgICogXG4gICAgICogQHJldHVybiB7U2xpZGVyfSBBIHJlZmVyZW5jZSB0byB0aGUgc2xpZGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzaG93KCkge1xuXG4gICAgICAgIHRoaXMub3B0cy5zdHJva2VBbHBoYSA9IDFcbiAgICAgICAgdGhpcy5vcHRzLmZpbGxBbHBoYSA9IDFcbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBbHBoYSA9IDFcbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xGaWxsQWxwaGEgPSAxXG5cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIEhpZGVzIHRoZSBzbGlkZXIgKHNldHMgaGlzIGFscGhhIHZhbHVlcyB0byAxKS5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9IEEgcmVmZXJlbmNlIHRvIHRoZSBzbGlkZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGhpZGUoKSB7XG5cbiAgICAgICAgdGhpcy5vcHRzLnN0cm9rZUFscGhhID0gMFxuICAgICAgICB0aGlzLm9wdHMuZmlsbEFscGhhID0gMFxuICAgICAgICB0aGlzLm9wdHMuY29udHJvbFN0cm9rZUFscGhhID0gMFxuICAgICAgICB0aGlzLm9wdHMuY29udHJvbEZpbGxBbHBoYSA9IDBcblxuICAgICAgICB0aGlzLmxheW91dCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG59XG4iLCJpbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCBUb29sdGlwIGZyb20gJy4vdG9vbHRpcC5qcydcblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIHN3aXRjaCBhY3Rpb24uXG4gKlxuICogQGNhbGxiYWNrIGFjdGlvbkNhbGxiYWNrXG4gKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBUaGUgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtTd2l0Y2h9IHN3aXRjaCAtIEEgcmVmZXJlbmNlIHRvIHRoZSBzd2l0Y2ggKGFsc28gdGhpcyByZWZlcnMgdG8gdGhlIHN3aXRjaCkuXG4gKi9cblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIHN3aXRjaCBhY3Rpb24uXG4gKlxuICogQGNhbGxiYWNrIGFjdGlvbkFjdGl2ZUNhbGxiYWNrXG4gKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBUaGUgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtTd2l0Y2h9IHN3aXRjaCAtIEEgcmVmZXJlbmNlIHRvIHRoZSBzd2l0Y2ggKGFsc28gdGhpcyByZWZlcnMgdG8gdGhlIHN3aXRjaCkuXG4gKi9cblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIHN3aXRjaCBiZWZvcmVBY3Rpb24uXG4gKlxuICogQGNhbGxiYWNrIGJlZm9yZUFjdGlvbkNhbGxiYWNrXG4gKiBAcGFyYW0ge29iamVjdH0gZXZlbnQgLSBUaGUgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtTd2l0Y2h9IHN3aXRjaCAtIEEgcmVmZXJlbmNlIHRvIHRoZSBzd2l0Y2ggKGFsc28gdGhpcyByZWZlcnMgdG8gdGhlIHN3aXRjaCkuXG4gKi9cblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgdGhlIHN3aXRjaCBhZnRlckFjdGlvbi5cbiAqXG4gKiBAY2FsbGJhY2sgYWZ0ZXJBY3Rpb25DYWxsYmFja1xuICogQHBhcmFtIHtvYmplY3R9IGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7U3dpdGNofSBzd2l0Y2ggLSBBIHJlZmVyZW5jZSB0byB0aGUgc3dpdGNoIChhbHNvIHRoaXMgcmVmZXJzIHRvIHRoZSBzd2l0Y2gpLlxuICovXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFN3aXRjaC5cbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSB0aGUgYXBwXG4gKiBjb25zdCBhcHAgPSBuZXcgUElYSUFwcCh7XG4gKiAgICAgdmlldzogY2FudmFzLFxuICogICAgIHdpZHRoOiA5MDAsXG4gKiAgICAgaGVpZ2h0OiAyNTBcbiAqIH0pLnNldHVwKCkucnVuKClcbiAqIFxuICogLy8gQ3JlYXRlIHRoZSBzd2l0Y2hcbiAqIGNvbnN0IHN3aXRjaDEgPSBuZXcgU3dpdGNoKHtcbiAqICAgICB4OiAxMCxcbiAqICAgICB5OiAyMFxuICogfSlcbiAqXG4gKiAvLyBBZGQgdGhlIHN3aXRjaCB0byBhIERpc3BsYXlPYmplY3RcbiAqIGFwcC5zY2VuZS5hZGRDaGlsZChzd2l0Y2gxKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5Db250YWluZXJcbiAqIEBzZWUge0BsaW5rIGh0dHA6Ly9waXhpanMuZG93bmxvYWQvZGV2L2RvY3MvUElYSS5Db250YWluZXIuaHRtbHxQSVhJLkNvbnRhaW5lcn1cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS9zd2l0Y2guaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTd2l0Y2ggZXh0ZW5kcyBQSVhJLkNvbnRhaW5lciB7XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFN3aXRjaC5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBzd2l0Y2guXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmlkPWF1dG8gZ2VuZXJhdGVkXSAtIFRoZSBpZCBvZiB0aGUgc3dpdGNoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy54PTBdIC0gVGhlIHggcG9zaXRpb24gb2YgdGhlIHN3aXRjaC4gQ2FuIGJlIGFsc28gc2V0IGFmdGVyIGNyZWF0aW9uIHdpdGggc3dpdGNoLnggPSAwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy55PTBdIC0gVGhlIHkgcG9zaXRpb24gb2YgdGhlIHN3aXRjaC4gQ2FuIGJlIGFsc28gc2V0IGFmdGVyIGNyZWF0aW9uIHdpdGggc3dpdGNoLnkgPSAwLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfFRoZW1lfSBbb3B0cy50aGVtZT1kYXJrXSAtIFRoZSB0aGVtZSB0byB1c2UgZm9yIHRoaXMgc3dpdGNoLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGRhcmssIGxpZ2h0LCByZWRcbiAgICAgKiAgICAgb3IgYSBUaGVtZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLndpZHRoPTQ0XSAtIFRoZSB3aWR0aCBvZiB0aGUgc3dpdGNoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5oZWlnaHQ9MjhdIC0gVGhlIGhlaWdodCBvZiB0aGUgc3dpdGNoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsPVRoZW1lLmZpbGxdIC0gVGhlIGNvbG9yIG9mIHRoZSBzd2l0Y2ggYmFja2dyb3VuZCBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuZmlsbEFscGhhPVRoZW1lLmZpbGxBbHBoYV0gLSBUaGUgYWxwaGEgdmFsdWUgb2YgdGhlIGJhY2tncm91bmQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmZpbGxBY3RpdmU9VGhlbWUuZmlsbEFjdGl2ZV0gLSBUaGUgY29sb3Igb2YgdGhlIHN3aXRjaCBiYWNrZ3JvdW5kIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5maWxsQWN0aXZlQWxwaGE9VGhlbWUuZmlsbEFjdGl2ZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlPVRoZW1lLnN0cm9rZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciBhcyBhIGhleCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlV2lkdGg9VGhlbWUuc3Ryb2tlV2lkdGhdIC0gVGhlIHdpZHRoIG9mIHRoZSBib3JkZXIgaW4gcGl4ZWwuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnN0cm9rZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmU9VGhlbWUuc3Ryb2tlQWN0aXZlXSAtIFRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5zdHJva2VBY3RpdmVXaWR0aD1UaGVtZS5zdHJva2VBY3RpdmVXaWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuc3Ryb2tlQWN0aXZlQWxwaGE9VGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNvbnRyb2xGaWxsPVRoZW1lLnN0cm9rZV0gLSBUaGUgY29sb3Igb2YgdGhlIHN3aXRjaCBjb250cm9sIGJhY2tncm91bmQgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNvbnRyb2xGaWxsQWxwaGE9VGhlbWUuc3Ryb2tlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sRmlsbEFjdGl2ZT1UaGVtZS5zdHJva2VdIC0gVGhlIGNvbG9yIG9mIHRoZSBzd2l0Y2ggY29udHJvbCBiYWNrZ3JvdW5kIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sRmlsbEFjdGl2ZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYmFja2dyb3VuZCB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29udHJvbFN0cm9rZT1UaGVtZS5zdHJva2VdIC0gVGhlIGNvbG9yIG9mIHRoZSBib3JkZXIgYXMgYSBoZXggdmFsdWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmNvbnRyb2xTdHJva2VXaWR0aD1UaGVtZS5zdHJva2VXaWR0aCAqIDAuOF0gLSBUaGUgd2lkdGggb2YgdGhlIGJvcmRlciBpbiBwaXhlbC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29udHJvbFN0cm9rZUFscGhhPVRoZW1lLnN0cm9rZUFscGhhXSAtIFRoZSBhbHBoYSB2YWx1ZSBvZiB0aGUgYm9yZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlPVRoZW1lLnN0cm9rZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJvcmRlciB3aGVuIGFjdGl2YXRlZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMuY29udHJvbFN0cm9rZUFjdGl2ZVdpZHRoPVRoZW1lLnN0cm9rZUFjdGl2ZVdpZHRoICogMC44XSAtIFRoZSB3aWR0aCBvZiB0aGUgYm9yZGVyIGluIHBpeGVsIHdoZW4gYWN0aXZhdGVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlQWxwaGE9VGhlbWUuc3Ryb2tlQWN0aXZlQWxwaGFdIC0gVGhlIGFscGhhIHZhbHVlIG9mIHRoZSBib3JkZXIgd2hlbiBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmR1cmF0aW9uPVRoZW1lLmZhc3RdIC0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gd2hlbiB0aGUgc3dpdGNoIGdldHMgYWN0aXZhdGVkIGluIHNlY29uZHMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmR1cmF0aW9uQWN0aXZlPVRoZW1lLmZhc3RdIC0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gd2hlbiB0aGUgc3dpdGNoIGdldHMgZGVhY3RpdmF0ZWQgaW4gc2Vjb25kcy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRpc2FibGVkPWZhbHNlXSAtIElzIHRoZSBzd2l0Y2ggZGlzYWJsZWQ/IFdoZW4gZGlzYWJsZWQsIHRoZSBzd2l0Y2ggaGFzIGEgbG93ZXIgYWxwaGEgdmFsdWVcbiAgICAgKiAgICAgYW5kIGNhbm5vdCBiZSBjbGlja2VkIChpbnRlcmFjdGl2ZSBpcyBzZXQgdG8gZmFsc2UpLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYWN0aXZlPWZhbHNlXSAtIElzIHRoZSBidXR0b24gaW5pdGlhbGx5IGFjdGl2ZT9cbiAgICAgKiBAcGFyYW0ge2FjdGlvbkNhbGxiYWNrfSBbb3B0cy5hY3Rpb25dIC0gRXhlY3V0ZWQgd2hlbiB0aGUgc3dpdGNoIHdhcyB0cmlnZ2VyZWQgaW4gaW5hY3RpdmUgc3RhdGUgKGJ5IHBvaW50ZXJ1cCkuXG4gICAgICogQHBhcmFtIHthY3Rpb25BY3RpdmVDYWxsYmFja30gW29wdHMuYWN0aW9uQWN0aXZlXSAtIEV4ZWN1dGVkIHdoZW4gdGhlIGJ1dHRvbiB3YXMgdHJpZ2dlcmVkIGluIGFjdGl2ZSBzdGF0ZSAoYnkgcG9pbnRlcnVwKS5cbiAgICAgKiBAcGFyYW0ge2JlZm9yZUFjdGlvbkNhbGxiYWNrfSBbb3B0cy5iZWZvcmVBY3Rpb25dIC0gRXhlY3V0ZWQgYmVmb3JlIGFuIGFjdGlvbiBpcyB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHthZnRlckFjdGlvbkNhbGxiYWNrfSBbb3B0cy5hZnRlckFjdGlvbl0gLSBFeGVjdXRlZCBhZnRlciBhbiBhY3Rpb24gd2FzIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IFtvcHRzLnRvb2x0aXBdIC0gQSBzdHJpbmcgZm9yIHRoZSBsYWJlbCBvZiB0aGUgdG9vbHRpcCBvciBhbiBvYmplY3QgdG8gY29uZmlndXJlIHRoZSB0b29sdGlwXG4gICAgICogICAgIHRvIGRpc3BsYXkuIFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudmlzaWJsZT10cnVlXSAtIElzIHRoZSBzd2l0Y2ggaW5pdGlhbGx5IHZpc2libGUgKHByb3BlcnR5IHZpc2libGUpP1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHN1cGVyKClcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICB0aGlzLnRoZW1lID0gdGhlbWVcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBpZDogUElYSS51dGlscy51aWQoKSxcbiAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgd2lkdGg6IDQ0LFxuICAgICAgICAgICAgaGVpZ2h0OiAyOCxcbiAgICAgICAgICAgIGZpbGw6IHRoZW1lLmZpbGwsXG4gICAgICAgICAgICBmaWxsQWxwaGE6IHRoZW1lLmZpbGxBbHBoYSxcbiAgICAgICAgICAgIGZpbGxBY3RpdmU6IHRoZW1lLnByaW1hcnlDb2xvcixcbiAgICAgICAgICAgIGZpbGxBY3RpdmVBbHBoYTogdGhlbWUuZmlsbEFjdGl2ZUFscGhhLFxuICAgICAgICAgICAgc3Ryb2tlOiB0aGVtZS5zdHJva2UsXG4gICAgICAgICAgICBzdHJva2VXaWR0aDogdGhlbWUuc3Ryb2tlV2lkdGgsXG4gICAgICAgICAgICBzdHJva2VBbHBoYTogdGhlbWUuc3Ryb2tlQWxwaGEsXG4gICAgICAgICAgICBzdHJva2VBY3RpdmU6IHRoZW1lLnByaW1hcnlDb2xvcixcbiAgICAgICAgICAgIHN0cm9rZUFjdGl2ZVdpZHRoOiB0aGVtZS5zdHJva2VBY3RpdmVXaWR0aCxcbiAgICAgICAgICAgIHN0cm9rZUFjdGl2ZUFscGhhOiB0aGVtZS5zdHJva2VBY3RpdmVBbHBoYSxcbiAgICAgICAgICAgIGNvbnRyb2xGaWxsOiB0aGVtZS5zdHJva2UsXG4gICAgICAgICAgICBjb250cm9sRmlsbEFscGhhOiB0aGVtZS5zdHJva2VBbHBoYSxcbiAgICAgICAgICAgIGNvbnRyb2xGaWxsQWN0aXZlOiB0aGVtZS5zdHJva2UsXG4gICAgICAgICAgICBjb250cm9sRmlsbEFjdGl2ZUFscGhhOiB0aGVtZS5zdHJva2VBbHBoYSxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2U6IHRoZW1lLnN0cm9rZSxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VXaWR0aDogdGhlbWUuc3Ryb2tlV2lkdGggKiAuOCxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VBbHBoYTogdGhlbWUuc3Ryb2tlQWxwaGEsXG4gICAgICAgICAgICBjb250cm9sU3Ryb2tlQWN0aXZlOiB0aGVtZS5zdHJva2UsXG4gICAgICAgICAgICBjb250cm9sU3Ryb2tlQWN0aXZlV2lkdGg6IHRoZW1lLnN0cm9rZUFjdGl2ZVdpZHRoICogLjgsXG4gICAgICAgICAgICBjb250cm9sU3Ryb2tlQWN0aXZlQWxwaGE6IHRoZW1lLnN0cm9rZUFjdGl2ZUFscGhhLFxuICAgICAgICAgICAgZHVyYXRpb246IHRoZW1lLmZhc3QsXG4gICAgICAgICAgICBkdXJhdGlvbkFjdGl2ZTogdGhlbWUuZmFzdCxcbiAgICAgICAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICAgICAgICAgIGFjdGl2ZTogZmFsc2UsXG4gICAgICAgICAgICBhY3Rpb246IG51bGwsXG4gICAgICAgICAgICBhY3Rpb25BY3RpdmU6IG51bGwsXG4gICAgICAgICAgICBiZWZvcmVBY3Rpb246IG51bGwsXG4gICAgICAgICAgICBhZnRlckFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIHRvb2x0aXA6IG51bGwsXG4gICAgICAgICAgICB2aXNpYmxlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXMgPSB0aGlzLm9wdHMuY29udHJvbFJhZGl1cyB8fCAodGhpcy5vcHRzLmhlaWdodCAvIDIpXG4gICAgICAgIHRoaXMub3B0cy5jb250cm9sUmFkaXVzQWN0aXZlID0gdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNBY3RpdmUgfHwgdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNcblxuICAgICAgICAvLyBWYWxpZGF0aW9uXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMub3B0cy5oZWlnaHQgPiB0aGlzLm9wdHMud2lkdGgpIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy5oZWlnaHQgPSB0aGlzLm9wdHMud2lkdGhcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb3BlcnRpZXNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmlkID0gdGhpcy5vcHRzLmlkXG4gICAgICAgIHRoaXMucmFkaXVzID0gdGhpcy5vcHRzLmhlaWdodCAvIDJcblxuICAgICAgICB0aGlzLl9hY3RpdmUgPSBudWxsXG4gICAgICAgIHRoaXMuX2Rpc2FibGVkID0gbnVsbFxuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqID0gbnVsbFxuICAgICAgICB0aGlzLmNvbnRyb2wgPSBudWxsXG4gICAgICAgIHRoaXMudG9vbHRpcCA9IG51bGxcbiAgICAgICAgXG4gICAgICAgIHRoaXMudmlzaWJsZSA9IHRoaXMub3B0cy52aXNpYmxlXG5cbiAgICAgICAgLy8gYW5pbWF0ZWRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnRlbXBBbmltYXRlZCA9IHtcbiAgICAgICAgICAgIGZpbGw6IHRoaXMub3B0cy5maWxsLFxuICAgICAgICAgICAgZmlsbEFscGhhOiB0aGlzLm9wdHMuZmlsbEFscGhhLFxuICAgICAgICAgICAgc3Ryb2tlOiB0aGlzLm9wdHMuc3Ryb2tlLFxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMub3B0cy5zdHJva2VXaWR0aCxcbiAgICAgICAgICAgIHN0cm9rZUFscGhhOiB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEsXG4gICAgICAgICAgICBjb250cm9sRmlsbDogdGhpcy5vcHRzLmNvbnRyb2xGaWxsLFxuICAgICAgICAgICAgY29udHJvbEZpbGxBbHBoYTogdGhpcy5vcHRzLmNvbnRyb2xGaWxsQWxwaGEsXG4gICAgICAgICAgICBjb250cm9sU3Ryb2tlOiB0aGlzLm9wdHMuY29udHJvbFN0cm9rZSxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VXaWR0aDogdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VXaWR0aCxcbiAgICAgICAgICAgIGNvbnRyb2xTdHJva2VBbHBoYTogdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBbHBoYSxcbiAgICAgICAgICAgIGNvbnRyb2xSYWRpdXM6IHRoaXMub3B0cy5jb250cm9sUmFkaXVzXG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXR1cFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuc2V0dXAoKVxuXG4gICAgICAgIC8vIGxheW91dFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMubGF5b3V0KClcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBjaGlsZHJlbiBhbmQgaW5zdGFudGlhdGVzIGV2ZXJ5dGhpbmcuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtTd2l0Y2h9IEEgcmVmZXJlbmNlIHRvIHRoZSBzd2l0Y2ggZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldHVwKCkge1xuXG4gICAgICAgIC8vIFN3aXRjaFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGxldCBzd2l0Y2hPYmogPSBuZXcgUElYSS5HcmFwaGljcygpXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqID0gc3dpdGNoT2JqXG4gICAgICAgIHRoaXMuYWRkQ2hpbGQoc3dpdGNoT2JqKVxuXG4gICAgICAgIC8vIENvbnRyb2xcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnhJbmFjdGl2ZSA9IHRoaXMub3B0cy5jb250cm9sUmFkaXVzXG4gICAgICAgIHRoaXMueEFjdGl2ZSA9IHRoaXMub3B0cy53aWR0aCAtIHRoaXMub3B0cy5jb250cm9sUmFkaXVzQWN0aXZlXG4gICAgICAgIFxuICAgICAgICBsZXQgY29udHJvbCA9IG5ldyBQSVhJLkdyYXBoaWNzKClcbiAgICAgICAgY29udHJvbC54ID0gdGhpcy5vcHRzLmFjdGl2ZSA/IHRoaXMueEFjdGl2ZSA6IHRoaXMueEluYWN0aXZlXG4gICAgICAgIGNvbnRyb2wueSA9IHRoaXMub3B0cy5oZWlnaHQgLyAyXG5cbiAgICAgICAgdGhpcy5jb250cm9sID0gY29udHJvbFxuXG4gICAgICAgIHRoaXMuYWRkQ2hpbGQodGhpcy5jb250cm9sKVxuICAgICAgICBcbiAgICAgICAgLy8gaW50ZXJhY3Rpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5vbigncG9pbnRlcm92ZXInLCBlID0+IHtcbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNvbnRyb2wsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAuODN9KVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLm9uKCdwb2ludGVyb3V0JywgZSA9PiB7XG4gICAgICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jb250cm9sLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogMX0pXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5zd2l0Y2hPYmoub24oJ3BvaW50ZXJkb3duJywgZSA9PiB7XG4gICAgICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jb250cm9sLCB0aGlzLnRoZW1lLmZhc3QsIHthbHBoYTogLjd9KVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLm9uKCdwb2ludGVydXAnLCBlID0+IHtcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5iZWZvcmVBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdHMuYmVmb3JlQWN0aW9uLmNhbGwodGhpcywgZSwgdGhpcylcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5hY3RpdmUgPSAhdGhpcy5hY3RpdmVcblxuICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5hY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLmFjdGlvbi5jYWxsKHRoaXMsIGUsIHRoaXMpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLmFjdGlvbkFjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdHMuYWN0aW9uQWN0aXZlLmNhbGwodGhpcywgZSwgdGhpcylcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFR3ZWVuTGl0ZS50byh0aGlzLmNvbnRyb2wsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAuODN9KVxuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLmFmdGVyQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRzLmFmdGVyQWN0aW9uLmNhbGwodGhpcywgZSwgdGhpcylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICAvLyBkaXNhYmxlZFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSB0aGlzLm9wdHMuZGlzYWJsZWRcblxuICAgICAgICAvLyBhY3RpdmVcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLmFjdGl2ZSA9IHRoaXMub3B0cy5hY3RpdmVcbiAgICAgICAgXG4gICAgICAgIC8vIHRvb2x0aXBcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLnRvb2x0aXApIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLnRvb2x0aXAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b29sdGlwID0gbmV3IFRvb2x0aXAoe1xuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHRoaXMub3B0cy50b29sdGlwXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRzLnRvb2x0aXAub2JqZWN0ID0gdGhpc1xuICAgICAgICAgICAgICAgIHRoaXMudG9vbHRpcCA9IG5ldyBUb29sdGlwKHRoaXMub3B0cy50b29sdGlwKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIGNhbGxlZCB0byByZWZyZXNoIHRoZSBsYXlvdXQgb2YgdGhlIHN3aXRjaC4gQ2FuIGJlIHVzZWQgYWZ0ZXIgcmVzaXppbmcuXG4gICAgICogXG4gICAgICogQHJldHVybiB7U3dpdGNofSBBIHJlZmVyZW5jZSB0byB0aGUgc3dpdGNoIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBsYXlvdXQoKSB7XG4gICAgICAgIFxuICAgICAgICAvLyBzZXQgcG9zaXRpb25cbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnBvc2l0aW9uLnNldCh0aGlzLm9wdHMueCwgdGhpcy5vcHRzLnkpXG5cbiAgICAgICAgLy8gZHJhd1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuZHJhdygpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIHN3aXRjaCB0byB0aGUgY2FudmFzLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7U3dpdGNofSBBIHJlZmVyZW5jZSB0byB0aGUgc3dpdGNoIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBkcmF3KCkge1xuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmNsZWFyKClcbiAgICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZUFjdGl2ZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlLCB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlQWxwaGEpXG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGxBY3RpdmUsIHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5saW5lU3R5bGUodGhpcy5vcHRzLnN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuc3Ryb2tlLCB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEpXG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5iZWdpbkZpbGwodGhpcy5vcHRzLmZpbGwsIHRoaXMub3B0cy5maWxsQWxwaGEpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zd2l0Y2hPYmoubW92ZVRvKHRoaXMucmFkaXVzLCAwKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5saW5lVG8odGhpcy5vcHRzLndpZHRoIC0gdGhpcy5yYWRpdXMsIDApXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmFyY1RvKHRoaXMub3B0cy53aWR0aCwgMCwgdGhpcy5vcHRzLndpZHRoLCB0aGlzLnJhZGl1cywgdGhpcy5yYWRpdXMpXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmxpbmVUbyh0aGlzLm9wdHMud2lkdGgsIHRoaXMucmFkaXVzICsgMSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJVR0ZJWDogSWYgbm90IHNwZWNpZmllZCwgdGhlcmUgaXMgYSBzbWFsbCBhcmVhIHdpdGhvdXQgYSBzdHJva2UuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmFyY1RvKHRoaXMub3B0cy53aWR0aCwgdGhpcy5vcHRzLmhlaWdodCwgdGhpcy5vcHRzLndpZHRoIC0gdGhpcy5yYWRpdXMsIHRoaXMub3B0cy5oZWlnaHQsIHRoaXMucmFkaXVzKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5saW5lVG8odGhpcy5yYWRpdXMsIHRoaXMub3B0cy5oZWlnaHQpXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmFyY1RvKDAsIHRoaXMub3B0cy5oZWlnaHQsIDAsIHRoaXMucmFkaXVzLCB0aGlzLnJhZGl1cylcbiAgICAgICAgdGhpcy5zd2l0Y2hPYmouYXJjVG8oMCwgMCwgdGhpcy5yYWRpdXMsIDAsIHRoaXMucmFkaXVzKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5lbmRGaWxsKClcblxuICAgICAgICAvLyBEcmF3IGNvbnRyb2xcbiAgICAgICAgdGhpcy5jb250cm9sLmNsZWFyKClcbiAgICAgICAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRyb2wubGluZVN0eWxlKHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlV2lkdGgsIHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlLCB0aGlzLm9wdHMuY29udHJvbFN0cm9rZUFjdGl2ZUFscGhhKVxuICAgICAgICAgICAgdGhpcy5jb250cm9sLmJlZ2luRmlsbCh0aGlzLm9wdHMuY29udHJvbEZpbGxBY3RpdmUsIHRoaXMub3B0cy5jb250cm9sRmlsbEFjdGl2ZUFscGhhKVxuICAgICAgICAgICAgdGhpcy5jb250cm9sLmRyYXdDaXJjbGUoMCwgMCwgdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNBY3RpdmUgLSAxKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb250cm9sLmxpbmVTdHlsZSh0aGlzLm9wdHMuY29udHJvbFN0cm9rZVdpZHRoLCB0aGlzLm9wdHMuY29udHJvbFN0cm9rZSwgdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBbHBoYSlcbiAgICAgICAgICAgIHRoaXMuY29udHJvbC5iZWdpbkZpbGwodGhpcy5vcHRzLmNvbnRyb2xGaWxsLCB0aGlzLm9wdHMuY29udHJvbEZpbGxBbHBoYSlcbiAgICAgICAgICAgIHRoaXMuY29udHJvbC5kcmF3Q2lyY2xlKDAsIDAsIHRoaXMub3B0cy5jb250cm9sUmFkaXVzIC0gMSlcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbnRyb2wuZW5kRmlsbCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogRHJhd3MgdGhlIGFuaW1hdGlvbi5cbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm4ge1N3aXRjaH0gQSByZWZlcmVuY2UgdG8gdGhlIHN3aXRjaCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgZHJhd0FuaW1hdGVkKCkge1xuXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmNsZWFyKClcbiAgICAgICAgdGhpcy5zd2l0Y2hPYmoubGluZVN0eWxlKHRoaXMudGVtcEFuaW1hdGVkLnN0cm9rZVdpZHRoLCB0aGlzLnRlbXBBbmltYXRlZC5zdHJva2UsIHRoaXMudGVtcEFuaW1hdGVkLnN0cm9rZUFscGhhKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5iZWdpbkZpbGwodGhpcy50ZW1wQW5pbWF0ZWQuZmlsbCwgdGhpcy50ZW1wQW5pbWF0ZWQuZmlsbEFscGhhKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5tb3ZlVG8odGhpcy5yYWRpdXMsIDApXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmxpbmVUbyh0aGlzLm9wdHMud2lkdGggLSB0aGlzLnJhZGl1cywgMClcbiAgICAgICAgdGhpcy5zd2l0Y2hPYmouYXJjVG8odGhpcy5vcHRzLndpZHRoLCAwLCB0aGlzLm9wdHMud2lkdGgsIHRoaXMucmFkaXVzLCB0aGlzLnJhZGl1cylcbiAgICAgICAgdGhpcy5zd2l0Y2hPYmoubGluZVRvKHRoaXMub3B0cy53aWR0aCwgdGhpcy5yYWRpdXMgKyAxKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQlVHRklYOiBJZiBub3Qgc3BlY2lmaWVkLCB0aGVyZSBpcyBhIHNtYWxsIGFyZWEgd2l0aG91dCBhIHN0cm9rZS5cbiAgICAgICAgdGhpcy5zd2l0Y2hPYmouYXJjVG8odGhpcy5vcHRzLndpZHRoLCB0aGlzLm9wdHMuaGVpZ2h0LCB0aGlzLm9wdHMud2lkdGggLSB0aGlzLnJhZGl1cywgdGhpcy5vcHRzLmhlaWdodCwgdGhpcy5yYWRpdXMpXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmxpbmVUbyh0aGlzLnJhZGl1cywgdGhpcy5vcHRzLmhlaWdodClcbiAgICAgICAgdGhpcy5zd2l0Y2hPYmouYXJjVG8oMCwgdGhpcy5vcHRzLmhlaWdodCwgMCwgdGhpcy5yYWRpdXMsIHRoaXMucmFkaXVzKVxuICAgICAgICB0aGlzLnN3aXRjaE9iai5hcmNUbygwLCAwLCB0aGlzLnJhZGl1cywgMCwgdGhpcy5yYWRpdXMpXG4gICAgICAgIHRoaXMuc3dpdGNoT2JqLmVuZEZpbGwoKVxuXG4gICAgICAgIHRoaXMuY29udHJvbC5jbGVhcigpXG4gICAgICAgIHRoaXMuY29udHJvbC5saW5lU3R5bGUodGhpcy50ZW1wQW5pbWF0ZWQuY29udHJvbFN0cm9rZVdpZHRoLCB0aGlzLnRlbXBBbmltYXRlZC5jb250cm9sU3Ryb2tlLCB0aGlzLnRlbXBBbmltYXRlZC5jb250cm9sU3Ryb2tlQWxwaGEpXG4gICAgICAgIHRoaXMuY29udHJvbC5iZWdpbkZpbGwodGhpcy50ZW1wQW5pbWF0ZWQuY29udHJvbEZpbGwsIHRoaXMudGVtcEFuaW1hdGVkLmNvbnRyb2xGaWxsQWxwaGEpXG4gICAgICAgIHRoaXMuY29udHJvbC5kcmF3Q2lyY2xlKDAsIDAsIHRoaXMudGVtcEFuaW1hdGVkLmNvbnRyb2xSYWRpdXMgLSAxKVxuICAgICAgICB0aGlzLmNvbnRyb2wuZW5kRmlsbCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBhY3RpdmUgc3RhdGUuXG4gICAgICogXG4gICAgICogQG1lbWJlciB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgYWN0aXZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlXG4gICAgfVxuXG4gICAgc2V0IGFjdGl2ZSh2YWx1ZSkge1xuXG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IHZhbHVlXG5cbiAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuXG4gICAgICAgICAgICBUd2VlbkxpdGUudG8odGhpcy5jb250cm9sLCB0aGlzLm9wdHMuZHVyYXRpb24sIHt4OiB0aGlzLnhBY3RpdmV9KVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMudGVtcEFuaW1hdGVkLCB0aGlzLm9wdHMuZHVyYXRpb24sIHtcbiAgICAgICAgICAgICAgICBjb2xvclByb3BzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoaXMub3B0cy5maWxsQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoaXMub3B0cy5zdHJva2VBY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWxsOiB0aGlzLm9wdHMuY29udHJvbEZpbGxBY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xTdHJva2U6IHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6ICdudW1iZXInXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmaWxsQWxwaGE6IHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMub3B0cy5zdHJva2VBY3RpdmVXaWR0aCxcbiAgICAgICAgICAgICAgICBzdHJva2VBbHBoYTogdGhpcy5vcHRzLnN0cm9rZUFjdGl2ZUFscGhhLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xGaWxsQWxwaGE6IHRoaXMub3B0cy5jb250cm9sRmlsbEFjdGl2ZUFscGhhLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xTdHJva2VXaWR0aDogdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBY3RpdmVXaWR0aCxcbiAgICAgICAgICAgICAgICBjb250cm9sU3Ryb2tlQWxwaGE6IHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlQWxwaGEsXG4gICAgICAgICAgICAgICAgY29udHJvbFJhZGl1czogdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXNBY3RpdmUsXG4gICAgICAgICAgICAgICAgb25VcGRhdGU6ICgpID0+IHRoaXMuZHJhd0FuaW1hdGVkKCksXG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZTogKCkgPT4gdGhpcy5kcmF3KClcbiAgICAgICAgICAgIH0pXG5cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMuY29udHJvbCwgdGhpcy5vcHRzLmR1cmF0aW9uQWN0aXZlLCB7eDogdGhpcy54SW5hY3RpdmV9KVxuICAgICAgICAgICAgVHdlZW5MaXRlLnRvKHRoaXMudGVtcEFuaW1hdGVkLCB0aGlzLm9wdHMuZHVyYXRpb25BY3RpdmUsIHtcbiAgICAgICAgICAgICAgICBjb2xvclByb3BzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IHRoaXMub3B0cy5maWxsLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6IHRoaXMub3B0cy5zdHJva2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWxsOiB0aGlzLm9wdHMuY29udHJvbEZpbGwsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xTdHJva2U6IHRoaXMub3B0cy5jb250cm9sU3Ryb2tlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6ICdudW1iZXInXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmaWxsQWxwaGE6IHRoaXMub3B0cy5maWxsQWxwaGEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IHRoaXMub3B0cy5zdHJva2VXaWR0aCxcbiAgICAgICAgICAgICAgICBzdHJva2VBbHBoYTogdGhpcy5vcHRzLnN0cm9rZUFscGhhLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xGaWxsQWxwaGE6IHRoaXMub3B0cy5jb250cm9sRmlsbEFscGhhLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xTdHJva2VXaWR0aDogdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VXaWR0aCxcbiAgICAgICAgICAgICAgICBjb250cm9sU3Ryb2tlQWxwaGE6IHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWxwaGEsXG4gICAgICAgICAgICAgICAgY29udHJvbFJhZGl1czogdGhpcy5vcHRzLmNvbnRyb2xSYWRpdXMsXG4gICAgICAgICAgICAgICAgb25VcGRhdGU6ICgpID0+IHRoaXMuZHJhd0FuaW1hdGVkKCksXG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZTogKCkgPT4gdGhpcy5kcmF3KClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBkaXNhYmxlZCBzdGF0ZS4gV2hlbiBkaXNhYmxlZCwgdGhlIHN3aXRjaCBjYW5ub3QgYmUgY2xpY2tlZC5cbiAgICAgKiBcbiAgICAgKiBAbWVtYmVyIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBkaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkXG4gICAgfVxuXG4gICAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG5cbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSB2YWx1ZVxuICAgICAgICBcbiAgICAgICAgaWYgKHRoaXMuX2Rpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5pbnRlcmFjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5idXR0b25Nb2RlID0gZmFsc2VcbiAgICAgICAgICAgIHRoaXMuc3dpdGNoT2JqLmFscGhhID0gLjVcbiAgICAgICAgICAgIHRoaXMuY29udHJvbC5hbHBoYSA9IC41XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgICAgIHRoaXMuc3dpdGNoT2JqLmJ1dHRvbk1vZGUgPSB0cnVlXG4gICAgICAgICAgICB0aGlzLnN3aXRjaE9iai5hbHBoYSA9IDFcbiAgICAgICAgICAgIHRoaXMuY29udHJvbC5hbHBoYSA9IDFcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBzd2l0Y2ggKHNldHMgaGlzIGFscGhhIHZhbHVlcyB0byAxKS5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJuIHtTd2l0Y2h9IEEgcmVmZXJlbmNlIHRvIHRoZSBzd2l0Y2ggZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNob3coKSB7XG5cbiAgICAgICAgdGhpcy5vcHRzLnN0cm9rZUFscGhhID0gMVxuICAgICAgICB0aGlzLm9wdHMuc3Ryb2tlQWN0aXZlQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5maWxsQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5maWxsQWN0aXZlQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5jb250cm9sU3Ryb2tlQWN0aXZlQWxwaGEgPSAxXG4gICAgICAgIHRoaXMub3B0cy5jb250cm9sRmlsbEFscGhhID0gMVxuICAgICAgICB0aGlzLm9wdHMuY29udHJvbEZpbGxBY3RpdmVBbHBoYSA9IDFcblxuICAgICAgICB0aGlzLmxheW91dCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIHN3aXRjaCAoc2V0cyBoaXMgYWxwaGEgdmFsdWVzIHRvIDEpLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge1N3aXRjaH0gQSByZWZlcmVuY2UgdG8gdGhlIHN3aXRjaCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgaGlkZSgpIHtcblxuICAgICAgICB0aGlzLm9wdHMuc3Ryb2tlQWxwaGEgPSAwXG4gICAgICAgIHRoaXMub3B0cy5zdHJva2VBY3RpdmVBbHBoYSA9IDBcbiAgICAgICAgdGhpcy5vcHRzLmZpbGxBbHBoYSA9IDBcbiAgICAgICAgdGhpcy5vcHRzLmZpbGxBY3RpdmVBbHBoYSA9IDBcbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBbHBoYSA9IDBcbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xTdHJva2VBY3RpdmVBbHBoYSA9IDBcbiAgICAgICAgdGhpcy5vcHRzLmNvbnRyb2xGaWxsQWxwaGEgPSAwXG4gICAgICAgIHRoaXMub3B0cy5jb250cm9sRmlsbEFjdGl2ZUFscGhhID0gMFxuXG4gICAgICAgIHRoaXMubGF5b3V0KClcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cbiIsImltcG9ydCBUaGVtZSBmcm9tICcuL3RoZW1lLmpzJ1xuaW1wb3J0IFBvcHVwIGZyb20gJy4vcG9wdXAuanMnXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIFBvcHVwTWVudS5cbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSB0aGUgYnV0dG9uIGFuZCB0aGUgbW9kYWwgd2hlbiBjbGlja2VkXG4gKiBjb25zdCBidXR0b24gPSBuZXcgQnV0dG9uKHtcbiAqICAgICBsYWJlbDogJ1Nob3cgUG9wdXBNZW51JyxcbiAqICAgICBhY3Rpb246IGUgPT4ge1xuICogICAgICAgICBjb25zdCBwb3B1cG1lbnUgPSBuZXcgUG9wdXBNZW51KHtcbiAqICAgICAgICAgICAgIGl0ZW1zOiBbXG4gKiAgICAgICAgICAgICAgICAge2xhYmVsOiAnU2F2ZScsIGFjdGlvbjogKCkgPT4gYWxlcnQoJ1NhdmVkJyl9LFxuICogICAgICAgICAgICAgICAgIHtsYWJlbDogJ0VkaXQnLCBhY3Rpb246ICgpID0+IGFsZXJ0KCdFZGl0ZWQnKX0sXG4gKiAgICAgICAgICAgICAgICAge2xhYmVsOiAnRGVsZXRlJywgYWN0aW9uOiAoKSA9PiBhbGVydCgnRGVsZXRlZCcpfVxuICogICAgICAgICAgICAgXVxuICogICAgICAgICB9KVxuICogICAgICAgICBhcHAuc2NlbmUuYWRkQ2hpbGQocG9wdXBtZW51KVxuICogICAgIH1cbiAqIH0pXG4gKlxuICogLy8gQWRkIHRoZSBidXR0b24gdG8gYSBEaXNwbGF5T2JqZWN0XG4gKiBhcHAuc2NlbmUuYWRkQ2hpbGQoYnV0dG9uKVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUG9wdXBcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3Lml3bS10dWViaW5nZW4uZGUvaXdtYnJvd3Nlci9saWIvcGl4aS9wb3B1cG1lbnUuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb3B1cE1lbnUgZXh0ZW5kcyBQb3B1cCB7XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFBvcHVwTWVudS5cbiAgICAgKiBcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3QgdG8gc3BlY2lmeSB0byBzdHlsZSBhbmQgYmVoYXZpb3VyIG9mIHRoZSBtb2RhbC5cbiAgICAgKiBAcGFyYW0ge29iamVjdFtdfSBbb3B0cy5pdGVtcz1bXV0gLSBBIGxpc3Qgb2YgdGhlIG1lbnUgaXRlbXMuIEVhY2ggaXRlbSBtdXN0IGJlIG9mIHR5cGUgb2JqZWN0LlxuICAgICAqICAgICBJZiBhbiBvYmplY3QgaGFzIGEgbGFiZWwgcHJvcGVydHksIGEgUElYSS5UZXh0IG9iamVjdCBpcyBjcmVhdGVkICh1c2luZyB0aGUgdGV4dFN0eWxlIHByb3BlcnR5KS5cbiAgICAgKiAgICAgSWYgYW4gb2JqZWN0IGhhc24ndCBhIGxhYmVsIHByb3BlcnR5LCBpdCBtdXN0IGNvbnRhaW4gYSBjb250ZW50IHByb3BlcnR5IHdoaWNoIGhhcyB0byBiZSBhXG4gICAgICogICAgIFBJWEkuRGlzcGxheU9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWFyZ2luPVRoZW1lLm1hcmdpbiAvIDJdIC0gVGhlIGFwcCB3aGVyZSB0aGUgbW9kYWwgYmVsb25ncyB0by5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHMudGV4dFN0eWxlPVRoZW1lLnRleHRTdHlsZV0gLSBUaGUgY29sb3Igb2YgdGhlIGJhY2tncm91bmQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5jbG9zZU9uUG9wdXA9dHJ1ZV0gLSBUaGUgb3BhY2l0eSBvZiB0aGUgYmFja2dyb3VuZC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRzID0ge30pIHtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZW1lID0gVGhlbWUuZnJvbVN0cmluZyhvcHRzLnRoZW1lKVxuICAgICAgICBcbiAgICAgICAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIHtcbiAgICAgICAgICAgIGl0ZW1zOiBbXSxcbiAgICAgICAgICAgIG1hcmdpbjogdGhlbWUubWFyZ2luIC8gMixcbiAgICAgICAgICAgIHRleHRTdHlsZTogdGhlbWUudGV4dFN0eWxlLFxuICAgICAgICAgICAgY2xvc2VPblBvcHVwOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgc3VwZXIob3B0cylcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBjaGlsZHJlbiBhbmQgaW5zdGFudGlhdGVzIGV2ZXJ5dGhpbmcuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtQb3B1cE1lbnV9IEEgcmVmZXJlbmNlIHRvIHRoZSBwb3B1cG1lbnUgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldHVwKCkge1xuXG4gICAgICAgIC8vIGNvbnRlbnRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBjb25zdCBjb250ZW50ID0gbmV3IFBJWEkuQ29udGFpbmVyKClcbiAgICAgICAgXG4gICAgICAgIGxldCB5ID0gMFxuICAgICAgICBmb3IgKGxldCBpdGVtIG9mIHRoaXMub3B0cy5pdGVtcykge1xuXG4gICAgICAgICAgICBsZXQgb2JqZWN0ID0gbnVsbFxuXG4gICAgICAgICAgICBpZiAoaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IG5ldyBQSVhJLlRleHQoaXRlbS5sYWJlbCwgaXRlbS50ZXh0U3R5bGUgfHwgdGhpcy5vcHRzLnRleHRTdHlsZSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gaXRlbS5jb250ZW50XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9iamVjdC55ID0geVxuXG4gICAgICAgICAgICBpZiAoaXRlbS5hY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuYWxwaGEgPSAuNVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnRlcmFjdGl2ZSA9IHRydWVcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmJ1dHRvbk1vZGUgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9iamVjdC5vbigncG9pbnRlcm92ZXInLCBlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgVHdlZW5MaXRlLnRvKG9iamVjdCwgdGhpcy50aGVtZS5mYXN0LCB7YWxwaGE6IC44Mywgb3ZlcndyaXRlOiAnbm9uZSd9KVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9uKCdwb2ludGVyb3V0JywgZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIFR3ZWVuTGl0ZS50byhvYmplY3QsIHRoaXMudGhlbWUuZmFzdCwge2FscGhhOiAxLCBvdmVyd3JpdGU6ICdub25lJ30pXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBvYmplY3Qub24oJ3BvaW50ZXJ1cCcsIGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLmFjdGlvbi5jYWxsKG9iamVjdCwgZSwgb2JqZWN0KVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRzLmNsb3NlT25BY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb250ZW50LmFkZENoaWxkKG9iamVjdClcblxuICAgICAgICAgICAgeSArPSBvYmplY3QuaGVpZ2h0ICsgdGhpcy5vcHRzLm1hcmdpblxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcHRzLmNvbnRlbnQgPSBjb250ZW50XG5cbiAgICAgICAgc3VwZXIuc2V0dXAoKVxuICAgIH1cbn1cbiIsIi8qIGdsb2JhbCBRdWFkICovXG5cbmltcG9ydCBUaGVtZSBmcm9tICcuL3RoZW1lLmpzJ1xuXG4vKipcbiAqIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhIFBpeGlKUyBWb2xhdGlsZS5cbiAqIFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGFwcCA9IG5ldyBQSVhJQXBwKHtcbiAqICAgICB2aWV3OiBjYW52YXMsXG4gKiAgICAgd2lkdGg6IDkwMCxcbiAqICAgICBoZWlnaHQ6IDI1MFxuICogfSkuc2V0dXAoKS5ydW4oKVxuICogXG4gKiBjb25zdCBidXR0b24gPSBuZXcgQnV0dG9uKHtcbiAqICAgICBsYWJlbDogJ1ZvbGF0aWxlIScsXG4gKiAgICAgYWN0aW9uOiAoKSA9PiB7XG4gKiAgICAgICAgIG5ldyBWb2xhdGlsZSh7XG4gKiAgICAgICAgICAgICBvYmplY3Q6IGJ1dHRvbixcbiAqICAgICAgICAgICAgIGRpcmVjdGlvbjogJ3JpZ2h0JyxcbiAqICAgICAgICAgICAgIGRlc3Ryb3lPbkNvbXBsZXRlOiBmYWxzZVxuICogICAgICAgICB9KVxuICogICAgIH1cbiAqIH0pXG4gKiBcbiAqIGFwcC5zY2VuZS5hZGRDaGlsZChidXR0b24pXG4gKlxuICogQGNsYXNzXG4gKiBAc2VlIHtAbGluayBodHRwczovL3d3dy5pd20tdHVlYmluZ2VuLmRlL2l3bWJyb3dzZXIvbGliL3BpeGkvdm9sYXRpbGUuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWb2xhdGlsZSB7XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFZvbGF0aWxlLlxuICAgICAqIFxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0c10gLSBBbiBvcHRpb25zIG9iamVjdCB0byBzcGVjaWZ5IHRvIHN0eWxlIGFuZCBiZWhhdmlvdXIgb2YgdGhlIG1vZGFsLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5pZD1hdXRvIGdlbmVyYXRlZF0gLSBUaGUgaWQgb2YgdGhlIHRvb2x0aXAuXG4gICAgICogQHBhcmFtIHtQSVhJLkRpc3BsYXlPYmplY3R8UElYSS5EaXNwbGF5T2JqZWN0W119IG9wdHMub2JqZWN0IC0gVGhlIG9iamVjdCB3aGVyZSB0aGUgdm9sYXRpbGUgc2hvdWxkIGJlIGFwcGxpZWQgdG8uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmRpcmVjdGlvbj10b3BdIC0gVGhlIGFuaW1hdGlvbiBkaXJlY3Rpb24uIFBvc3NpYmxlIHZhbHVlczogdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0LlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRzLm9uU3RhcnRdIC0gQSBmdW5jdGlvbiB3aGljaCBpcyBleGVjdXRlZCB3aGVuIHRoZSB2b2xhdGlsZSBhbmltYXRpb24gc3RhcnRzLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRzLm9uQ29tcGxldGVdIC0gQSBmdW5jdGlvbiB3aGljaCBpcyBleGVjdXRlZCB3aGVuIHRoZSB2b2xhdGlsZSBhbmltYXRpb24gZmluaXNoZXMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmRpc3RhbmNlPTE2MF0gLSBUaGUgYW5pbWF0aW9uIGRpc3RhbmNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5kdXJhdGlvbj0xLjVdIC0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gaW4gc2Vjb25kcy5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHMuZWFzZT1RdWFkLmVhc2VPdXRdIC0gVGhlIGVhc2luZyBvZiB0aGUgYW5pbWF0aW9uLCBzZWUge0BsaW5rIGh0dHBzOi8vZ3JlZW5zb2NrLmNvbS9kb2NzL0Vhc2luZ31cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRlc3Ryb3lPbkNvbXBsZXRlPXRydWVdIC0gU2hvdWxkIHRoZSBvYmplY3QgYmUgZGVzdHJveWVkIGFmdGVyIHRoZSB2b2xhdGlsZSBhbmltYXRpb24/XG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0cyA9IHt9KSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCB0aGVtZSA9IFRoZW1lLmZyb21TdHJpbmcob3B0cy50aGVtZSlcbiAgICAgICAgdGhpcy50aGVtZSA9IHRoZW1lXG5cbiAgICAgICAgdGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7fSwge1xuICAgICAgICAgICAgaWQ6IFBJWEkudXRpbHMudWlkKCksXG4gICAgICAgICAgICBvYmplY3Q6IG51bGwsXG4gICAgICAgICAgICBkaXJlY3Rpb246ICd0b3AnLCAgICAgICAgICAgICAgIC8vIHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFxuICAgICAgICAgICAgb25TdGFydDogbnVsbCxcbiAgICAgICAgICAgIG9uQ29tcGxldGU6IG51bGwsXG4gICAgICAgICAgICBkaXN0YW5jZTogMTYwLFxuICAgICAgICAgICAgZHVyYXRpb246IDEuNSxcbiAgICAgICAgICAgIGVhc2U6IFF1YWQuZWFzZU91dCxcbiAgICAgICAgICAgIGRlc3Ryb3lPbkNvbXBsZXRlOiB0cnVlXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5pZCA9IHRoaXMub3B0cy5pZFxuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLm9wdHMub2JqZWN0KSkge1xuICAgICAgICAgICAgdGhpcy5vcHRzLm9iamVjdCA9IFt0aGlzLm9wdHMub2JqZWN0XVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vYmplY3RzID0gdGhpcy5vcHRzLm9iamVjdFxuXG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5zZXR1cCgpXG5cbiAgICAgICAgLy8gbGF5b3V0XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5sYXlvdXQoKVxuXG4gICAgICAgIC8vIHJ1blxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucnVuKClcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBjaGlsZHJlbiBhbmQgaW5zdGFudGlhdGVzIGV2ZXJ5dGhpbmcuXG4gICAgICogXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtWb2xhdGlsZX0gQSByZWZlcmVuY2UgdG8gdGhlIHZvbGF0aWxlIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXR1cCgpIHtcblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBTaG91bGQgYmUgY2FsbGVkIHRvIHJlZnJlc2ggdGhlIGxheW91dCBvZiB0aGUgdm9sYXRpbGUuIENhbiBiZSB1c2VkIGFmdGVyIHJlc2l6aW5nLlxuICAgICAqIFxuICAgICAqIEByZXR1cm4ge1ZvbGF0aWxlfSBBIHJlZmVyZW5jZSB0byB0aGUgdm9sYXRpbGUgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAgIFxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgdm9sYXRpbGUgYW5pbWF0aW9uLlxuICAgICAqIFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiB7Vm9sYXRpbGV9IEEgcmVmZXJlbmNlIHRvIHRoZSB2b2xhdGlsZSBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcnVuKCkge1xuXG4gICAgICAgIGZvciAobGV0IG9iamVjdCBvZiB0aGlzLm9iamVjdHMpIHtcblxuICAgICAgICAgICAgbGV0IHggPSBvYmplY3QueFxuICAgICAgICAgICAgbGV0IHkgPSBvYmplY3QueVxuXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMub3B0cy5kaXJlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgICAgICAgICAgICB5IC09IHRoaXMub3B0cy5kaXN0YW5jZVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICAgICAgICAgICAgeCArPSB0aGlzLm9wdHMuZGlzdGFuY2VcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgICAgICAgICB5ICs9IHRoaXMub3B0cy5kaXN0YW5jZVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgICAgICAgICAgICB4IC09IHRoaXMub3B0cy5kaXN0YW5jZVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBUd2VlbkxpdGUudG8ob2JqZWN0LCB0aGlzLm9wdHMuZHVyYXRpb24sIHtcbiAgICAgICAgICAgICAgICB4LFxuICAgICAgICAgICAgICAgIHksXG4gICAgICAgICAgICAgICAgYWxwaGE6IDAsXG4gICAgICAgICAgICAgICAgZWFzZTogdGhpcy5vcHRzLmVhc2UsXG4gICAgICAgICAgICAgICAgb3ZlcndyaXRlOiAnYWxsJyxcbiAgICAgICAgICAgICAgICBvblN0YXJ0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdHMub25TdGFydCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRzLm9uU3RhcnQuY2FsbChvYmplY3QsIG9iamVjdClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25Db21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5vbkNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdHMub25Db21wbGV0ZS5jYWxsKG9iamVjdCwgb2JqZWN0KVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5kZXN0cm95T25Db21wbGV0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRlc3Ryb3koe2NoaWxkcmVuOiB0cnVlfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cbiIsIi8qIGdsb2JhbHMgKi9cblxuLyogSW1wb3J0cyAqL1xuaW1wb3J0IEV2ZW50cyBmcm9tICcuLi9ldmVudHMuanMnXG5cbi8qKlxuICogQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgUGl4aUpTIExpc3QuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGVsZXBoYW50MSA9IFBJWEkuU3ByaXRlLmZyb21JbWFnZSgnLi9hc3NldHMvZWxlcGhhbnQtMS5qcGcnKVxuICogY29uc3QgZWxlcGhhbnQyID0gUElYSS5TcHJpdGUuZnJvbUltYWdlKCcuL2Fzc2V0cy9lbGVwaGFudC0yLmpwZycpXG4gKiBcbiAqIC8vIENyZWF0ZSB0aGUgbGlzdFxuICogY29uc3QgbGlzdCA9IG5ldyBMaXN0KFtlbGVwaGFudDEsIGVsZXBoYW50Ml0pXG4gKiBcbiAqIGFwcC5zY2VuZS5hZGRDaGlsZChsaXN0KVxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgUElYSS5Db250YWluZXJcbiAqIEBzZWUge0BsaW5rIGh0dHA6Ly9waXhpanMuZG93bmxvYWQvZGV2L2RvY3MvUElYSS5Db250YWluZXIuaHRtbHxQaXhpSlMgQ29udGFpbmVyfVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cuaXdtLXR1ZWJpbmdlbi5kZS9pd21icm93c2VyL2xpYi9waXhpL2xpc3QuaHRtbHxEb2NUZXN0fVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0IGV4dGVuZHMgUElYSS5Db250YWluZXIge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIEZsaXBwYWJsZS5cbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7UElYSS5EaXNwbGF5T2JqZWN0W119IGl0ZW1zIC0gQW4gYXJyYXkgb2YgUElYSS5EaXNwbGF5T2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW29wdHNdIC0gQW4gb3B0aW9ucyBvYmplY3Qgd2hpY2ggY2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy53aWR0aF0gLSBUaGUgd2lkdGggb2YgdGhlIGxpc3QuIElmIHRoZSBpdGVtcyBhcmUgbGFyZ2VyIHRoYW4gdGhpcyB3aWR0aCwgdGhlIG92ZXJmbG93XG4gICAgICogICAgIHdpbGwgYmUgaGlkZGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5oZWlnaHRdIC0gVGhlIGhlaWdodCBvZiB0aGUgbGlzdC4gSWYgdGhlIGl0ZW1zIGFyZSBsYXJnZXIgdGhhbiB0aGlzIGhlaWdodCwgdGhlIG92ZXJmbG93XG4gICAgICogICAgIHdpbGwgYmUgaGlkZGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5wYWRkaW5nPTEwXSAtIFRoZSBpbm5lciBzcGFjaW5nIChkaXN0YW5jZSBmcm9tIG9uZSBpdGVtIHRvIHRoZSBwcmV2aW91cy9uZXh0IGl0ZW0pLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5tYXJnaW49MTBdIC0gVGhlIG91dGVyIHNwYWNpbmcgKGRpc3RhbmNlIGZyb20gb25lIGl0ZW0gdG8gdGhlIGJvcmRlcikuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm9yaWVudGF0aW9uPXZlcnRpY2FsXSAtIFRoZSBvcmllbnRhdGlvbiBvZiB0aGUgYnV0dG9uIGdyb3VwLiBDYW4gYmUgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuYWxpZ249bGVmdF0gLSBUaGUgaG9yaXpvbnRhbCBwb3NpdGlvbiBvZiB0aGUgaXRlbXMuIFBvc3NpYmxlIHZhbHVlcyBhcmVcbiAgICAgKiAgICAgbGVmdCwgY2VudGVyIGFuZCByaWdodC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudmVydGljYWxBbGlnbj1taWRkbGVdIC0gVGhlIHZlcnRpY2FsIHBvc2l0aW9uIG9mIHRoZSBpdGVtcy4gUG9zc2libGUgdmFsdWVzIGFyZVxuICAgICAqICAgICB0b3AsIG1pZGRsZSBhbmQgYm90dG9tLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGl0ZW1zID0gW10sIG9wdHMgPSB7fSkge1xuXG4gICAgICAgIHN1cGVyKClcblxuICAgICAgICB0aGlzLm9wdHMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG4gICAgICAgICAgICBwYWRkaW5nOiAxMCxcbiAgICAgICAgICAgIG1hcmdpbjogMTAsXG4gICAgICAgICAgICBvcmllbnRhdGlvbjogJ3ZlcnRpY2FsJyxcbiAgICAgICAgICAgIGFsaWduOiAnbGVmdCcsXG4gICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIHdpZHRoOiBudWxsLFxuICAgICAgICAgICAgaGVpZ2h0OiBudWxsXG4gICAgICAgIH0sIG9wdHMpXG5cbiAgICAgICAgdGhpcy5fX2l0ZW1zID0gaXRlbXNcbiAgICAgICAgdGhpcy5fX2RyYWdnaW5nID0gZmFsc2VcblxuICAgICAgICAvLyBzZXR1cFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuc2V0dXAoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgY2hpbGRyZW4gYW5kIGluc3RhbnRpYXRlcyBldmVyeXRoaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJuIHtMaXN0fSBBIHJlZmVyZW5jZSB0byB0aGUgbGlzdCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0dXAoKSB7XG5cbiAgICAgICAgLy8gaW5uZXIgY29udGFpbmVyXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gbmV3IFBJWEkuQ29udGFpbmVyKClcbiAgICAgICAgdGhpcy5hZGRDaGlsZChjb250YWluZXIpXG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyXG5cbiAgICAgICAgLy8gbWFza1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIGNvbnN0IG1hc2sgPSBuZXcgUElYSS5HcmFwaGljcygpXG4gICAgICAgIHRoaXMuYWRkQ2hpbGQobWFzaylcbiAgICAgICAgdGhpcy5fX21hc2sgPSBtYXNrXG5cbiAgICAgICAgLy8gYWRkIGl0ZW1zXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgZm9yKGxldCBpdGVtIG9mIHRoaXMuX19pdGVtcykge1xuICAgICAgICAgICAgY29udGFpbmVyLmFkZENoaWxkKGl0ZW0pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBpbnRlcmFjdGlvblxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuaW50ZXJhY3RpdmUgPSB0aGlzLm9wdHMud2lkdGggfHwgdGhpcy5vcHRzLmhlaWdodFxuICAgICAgICB0aGlzLm9uKCdwb2ludGVyZG93bicsIHRoaXMub25TdGFydC5iaW5kKHRoaXMpKVxuICAgICAgICB0aGlzLm9uKCdwb2ludGVybW92ZScsIHRoaXMub25Nb3ZlLmJpbmQodGhpcykpXG4gICAgICAgIHRoaXMub24oJ3BvaW50ZXJ1cCcsIHRoaXMub25FbmQuYmluZCh0aGlzKSlcbiAgICAgICAgdGhpcy5vbigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25FbmQuYmluZCh0aGlzKSlcbiAgICAgICAgdGhpcy5vbigncG9pbnRlcm91dCcsIHRoaXMub25FbmQuYmluZCh0aGlzKSlcbiAgICAgICAgdGhpcy5vbigncG9pbnRlcnVwb3V0c2lkZScsIHRoaXMub25FbmQuYmluZCh0aGlzKSlcblxuICAgICAgICB0aGlzLmxheW91dCgpXG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyB0aGUgZXhpc3RpbmcgaXRlbXMgYW5kIHJlbGF5b3V0cyB0aGUgbGlzdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UElYSS5EaXNwbGF5T2JqZWN0W119IGl0ZW1zIC0gQW4gYXJyYXkgb2YgUElYSS5EaXNwbGF5T2JqZWN0cy5cbiAgICAgKiBAcmV0dXJuIHtMaXN0fSBBIHJlZmVyZW5jZSB0byB0aGUgbGlzdCBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0SXRlbXMoaXRlbXMpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIucmVtb3ZlQ2hpbGRyZW4oKVxuICAgICAgICB0aGlzLl9faXRlbXMgPSBpdGVtc1xuICAgICAgICBmb3IobGV0IGl0ZW0gb2YgdGhpcy5fX2l0ZW1zKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRDaGlsZChpdGVtKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubGF5b3V0KClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG91bGQgYmUgY2FsbGVkIHRvIHJlZnJlc2ggdGhlIGxheW91dCBvZiB0aGUgbGlzdCAodGhlIHdpZHRoIG9yIHRoZSBoZWlnaHQpLlxuICAgICAqXG4gICAgICogQHJldHVybiB7TGlzdH0gQSByZWZlcmVuY2UgdG8gdGhlIGxpc3QgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGxheW91dCgpIHtcblxuICAgICAgICBjb25zdCBtYXJnaW4gPSB0aGlzLm9wdHMubWFyZ2luXG5cbiAgICAgICAgbGV0IHggPSBtYXJnaW5cbiAgICAgICAgbGV0IHkgPSBtYXJnaW5cblxuICAgICAgICBmb3IgKGxldCBpdGVtIG9mIHRoaXMuX19pdGVtcykge1xuXG4gICAgICAgICAgICBpdGVtLnggPSB4XG4gICAgICAgICAgICBpdGVtLnkgPSB5XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcpIHtcbiAgICAgICAgICAgICAgICB5ICs9IGl0ZW0uaGVpZ2h0ICsgdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgeCArPSBpdGVtLndpZHRoICsgdGhpcy5vcHRzLnBhZGRpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZlcnRpY2FsXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgaWYgKHRoaXMub3B0cy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLm9wdHMuYWxpZ24pIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9faXRlbXMuZm9yRWFjaChpdCA9PiBpdC54ID0gbWFyZ2luICsgdGhpcy53aWR0aCAvIDIgLSBpdC53aWR0aCAvIDIpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9faXRlbXMuZm9yRWFjaChpdCA9PiBpdC54ID0gbWFyZ2luICsgdGhpcy53aWR0aCAtIGl0LndpZHRoKVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX19pdGVtcy5mb3JFYWNoKGl0ID0+IGl0LnggPSBtYXJnaW4pXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWFzayA9IHRoaXMuX19tYXNrXG4gICAgICAgICAgICAgICAgbWFzay5jbGVhcigpXG4gICAgICAgICAgICAgICAgbWFzay5iZWdpbkZpbGwoMHgwMDApXG4gICAgICAgICAgICAgICAgbWFzay5kcmF3UmVjdCgwLCAwLCB0aGlzLndpZHRoICsgMiAqIG1hcmdpbiwgdGhpcy5vcHRzLmhlaWdodClcbiAgICAgICAgICAgICAgICB0aGlzLm1hc2sgPSBtYXNrXG5cbiAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0aXZlID0gdGhpcy5pbm5lckhlaWdodCA+IHRoaXMub3B0cy5oZWlnaHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhvcml6b250YWxcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICBpZiAodGhpcy5vcHRzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5vcHRzLnZlcnRpY2FsQWxpZ24pIHtcbiAgICAgICAgICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9faXRlbXMuZm9yRWFjaChpdCA9PiBpdC55ID0gbWFyZ2luKVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX19pdGVtcy5mb3JFYWNoKGl0ID0+IGl0LnkgPSBtYXJnaW4gKyB0aGlzLmhlaWdodCAtIGl0LmhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9faXRlbXMuZm9yRWFjaChpdCA9PiBpdC55ID0gbWFyZ2luICsgdGhpcy5oZWlnaHQgLyAyIC0gaXQuaGVpZ2h0IC8gMilcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy53aWR0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hc2sgPSB0aGlzLl9fbWFza1xuICAgICAgICAgICAgICAgIG1hc2suY2xlYXIoKVxuICAgICAgICAgICAgICAgIG1hc2suYmVnaW5GaWxsKDB4MDAwKVxuICAgICAgICAgICAgICAgIG1hc2suZHJhd1JlY3QoMCwgMCwgdGhpcy5vcHRzLndpZHRoLCB0aGlzLmhlaWdodCArIDIgKiBtYXJnaW4pXG4gICAgICAgICAgICAgICAgdGhpcy5tYXNrID0gbWFza1xuXG4gICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGl2ZSA9IHRoaXMuaW5uZXJXaWR0aCA+IHRoaXMub3B0cy53aWR0aFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKi9cbiAgICBnZXQgaW5uZXJXaWR0aCgpIHtcblxuICAgICAgICBsZXQgc2l6ZSA9IDBcblxuICAgICAgICB0aGlzLl9faXRlbXMuZm9yRWFjaChpdCA9PiBzaXplICs9IGl0LndpZHRoKVxuICAgICAgICBzaXplICs9IHRoaXMub3B0cy5wYWRkaW5nICogKHRoaXMuX19pdGVtcy5sZW5ndGggLSAxKVxuICAgICAgICBzaXplICs9IDIgKiB0aGlzLm9wdHMubWFyZ2luXG5cbiAgICAgICAgcmV0dXJuIHNpemVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKi9cbiAgICBnZXQgaW5uZXJIZWlnaHQoKSB7XG5cbiAgICAgICAgbGV0IHNpemUgPSAwXG5cbiAgICAgICAgdGhpcy5fX2l0ZW1zLmZvckVhY2goaXQgPT4gc2l6ZSArPSBpdC5oZWlnaHQpXG4gICAgICAgIHNpemUgKz0gdGhpcy5vcHRzLnBhZGRpbmcgKiAodGhpcy5fX2l0ZW1zLmxlbmd0aCAtIDEpXG4gICAgICAgIHNpemUgKz0gMiAqIHRoaXMub3B0cy5tYXJnaW5cblxuICAgICAgICByZXR1cm4gc2l6ZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2l6ZXMgdGhlIGxpc3QuXG4gICAgICogXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoT3JIZWlnaHQgLSBUaGUgbmV3IHdpZHRoIChpZiBvcmllbnRhdGlvbiBpcyBob3Jpem9udGFsKSBvciBoZWlnaHQgKGlmIG9yaWVudGF0aW9uIGlzIHZlcnRpY2FsKSBvZiB0aGUgbGlzdC5cbiAgICAgKi9cbiAgICByZXNpemUod2lkdGhPckhlaWdodCkge1xuXG4gICAgICAgIGlmICh0aGlzLm9wdHMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICAgICAgdGhpcy5vcHRzLndpZHRoID0gd2lkdGhPckhlaWdodFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vcHRzLmhlaWdodCA9IHdpZHRoT3JIZWlnaHRcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubGF5b3V0KClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gZXZlbnQgXG4gICAgICovXG4gICAgb25TdGFydChldmVudCkge1xuXG4gICAgICAgIHRoaXMuX19kcmFnZ2luZyA9IHRydWVcblxuICAgICAgICB0aGlzLmNhcHR1cmUoZXZlbnQpXG5cbiAgICAgICAgdGhpcy5fX2RlbHRhID0ge1xuICAgICAgICAgICAgeDogdGhpcy5jb250YWluZXIucG9zaXRpb24ueCAtIGV2ZW50LmRhdGEuZ2xvYmFsLngsXG4gICAgICAgICAgICB5OiB0aGlzLmNvbnRhaW5lci5wb3NpdGlvbi55IC0gZXZlbnQuZGF0YS5nbG9iYWwueVxuICAgICAgICB9XG5cbiAgICAgICAgVHdlZW5MaXRlLmtpbGxUd2VlbnNPZih0aGlzLmNvbnRhaW5lci5wb3NpdGlvbiwge3g6IHRydWUsIHk6IHRydWV9KVxuICAgICAgICBUaHJvd1Byb3BzUGx1Z2luLnRyYWNrKHRoaXMuY29udGFpbmVyLnBvc2l0aW9uLCAneCx5JylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gZXZlbnQgXG4gICAgICovXG4gICAgb25Nb3ZlKGV2ZW50KSB7XG5cbiAgICAgICAgaWYgKHRoaXMuX19kcmFnZ2luZykge1xuICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuY2FwdHVyZShldmVudClcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIucG9zaXRpb24ueCA9IGV2ZW50LmRhdGEuZ2xvYmFsLnggKyB0aGlzLl9fZGVsdGEueFxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5wb3NpdGlvbi55ID0gZXZlbnQuZGF0YS5nbG9iYWwueSArIHRoaXMuX19kZWx0YS55XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gZXZlbnQgXG4gICAgICovXG4gICAgb25FbmQoZXZlbnQpIHtcblxuICAgICAgICBpZiAodGhpcy5fX2RyYWdnaW5nKSB7XG4gICAgICAgICAgICB0aGlzLl9fZHJhZ2dpbmcgPSBmYWxzZVxuXG4gICAgICAgICAgICB0aGlzLmNhcHR1cmUoZXZlbnQpXG5cbiAgICAgICAgICAgIGNvbnN0IHRocm93UHJvcHMgPSB7fVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgICAgICBsZXQgbWluID0gdGhpcy5vcHRzLndpZHRoIC0gdGhpcy5pbm5lcldpZHRoXG4gICAgICAgICAgICAgICAgbWluID0gbWluID4gMCA/IDAgOiBtaW5cbiAgICAgICAgICAgICAgICB0aHJvd1Byb3BzLnggPSB7XG4gICAgICAgICAgICAgICAgICAgIHZlbG9jaXR5OiAnYXV0bycsXG4gICAgICAgICAgICAgICAgICAgIG1pbixcbiAgICAgICAgICAgICAgICAgICAgbWF4OiAwXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgbWluID0gdGhpcy5vcHRzLmhlaWdodCAtIHRoaXMuaW5uZXJIZWlnaHRcbiAgICAgICAgICAgICAgICBtaW4gPSBtaW4gPiAwID8gMCA6IG1pblxuICAgICAgICAgICAgICAgIHRocm93UHJvcHMueSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmVsb2NpdHk6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICAgICAgbWluLFxuICAgICAgICAgICAgICAgICAgICBtYXg6IDBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFRocm93UHJvcHNQbHVnaW4udG8odGhpcy5jb250YWluZXIucG9zaXRpb24sIHtcbiAgICAgICAgICAgICAgICB0aHJvd1Byb3BzLFxuICAgICAgICAgICAgICAgIGVhc2U6IFN0cm9uZy5lYXNlT3V0LFxuICAgICAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IFRocm93UHJvcHNQbHVnaW4udW50cmFjayh0aGlzLmNvbnRhaW5lci5wb3NpdGlvbilcbiAgICAgICAgICAgIH0sIC44LCAuNClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhcHR1cmVzIGFuIGV2ZW50IHRvIGluZm9ybSBJbnRlcmFjdGlvbk1hcHBlciBhYm91dCBwcm9jZXNzZWQgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtldmVudHxQSVhJLkludGVyYWN0aW9uRXZlbnR9IGV2ZW50IC0gVGhlIFBJWEkgZXZlbnQgdG8gY2FwdHVyZS5cbiAgICAgKi9cbiAgICBjYXB0dXJlKGV2ZW50KSB7XG4gICAgICAgIEV2ZW50cy5jYXB0dXJlZEJ5KGV2ZW50LmRhdGEub3JpZ2luYWxFdmVudCwgdGhpcylcbiAgICB9XG59XG4iLCJpbXBvcnQgUElYSUFwcCBmcm9tICcuL2FwcC5qcydcbmltcG9ydCBCbHVyRmlsdGVyIGZyb20gJy4vYmx1cmZpbHRlci5qcydcbmltcG9ydCBGbGlwRWZmZWN0IGZyb20gJy4vZmxpcGVmZmVjdC5qcydcbmltcG9ydCBGbGlwcGFibGUgZnJvbSAnLi9mbGlwcGFibGUuanMnXG5pbXBvcnQge0RlZXBab29tSW5mbywgRGVlcFpvb21JbWFnZX0gZnJvbSAnLi9kZWVwem9vbS9pbWFnZS5qcydcbmltcG9ydCBQb3BvdmVyIGZyb20gJy4vcG9wb3Zlci5qcydcbmltcG9ydCB7U2NhdHRlckNvbnRhaW5lciwgRGlzcGxheU9iamVjdFNjYXR0ZXJ9IGZyb20gJy4vc2NhdHRlci5qcydcbmltcG9ydCB7QXBwVGVzdCwgQ29tbWFuZCwgUmVjb3JkZXJUb29sc30gZnJvbSAnLi90ZXN0LmpzJ1xuaW1wb3J0IFRpbWVsaW5lIGZyb20gJy4vdGltZWxpbmUuanMnXG5pbXBvcnQgVGhlbWUgZnJvbSAnLi90aGVtZS5qcydcbmltcG9ydCBCdXR0b24gZnJvbSAnLi9idXR0b24uanMnXG5pbXBvcnQgQnV0dG9uR3JvdXAgZnJvbSAnLi9idXR0b25ncm91cC5qcydcbmltcG9ydCBTbGlkZXIgZnJvbSAnLi9zbGlkZXIuanMnXG5pbXBvcnQgU3dpdGNoIGZyb20gJy4vc3dpdGNoLmpzJ1xuaW1wb3J0IFBvcHVwIGZyb20gJy4vcG9wdXAuanMnXG5pbXBvcnQgUG9wdXBNZW51IGZyb20gJy4vcG9wdXBtZW51LmpzJ1xuaW1wb3J0IE1vZGFsIGZyb20gJy4vbW9kYWwuanMnXG5pbXBvcnQgVm9sYXRpbGUgZnJvbSAnLi92b2xhdGlsZS5qcydcbmltcG9ydCBNZXNzYWdlIGZyb20gJy4vbWVzc2FnZS5qcydcbmltcG9ydCBUb29sdGlwIGZyb20gJy4vdG9vbHRpcC5qcydcbmltcG9ydCBCYWRnZSBmcm9tICcuL2JhZGdlLmpzJ1xuaW1wb3J0IFByb2dyZXNzIGZyb20gJy4vcHJvZ3Jlc3MuanMnXG5pbXBvcnQgTGlzdCBmcm9tICcuL2xpc3QuanMnXG5pbXBvcnQge0xhYmVsZWRHcmFwaGljcywgRm9udEluZm99IGZyb20gJy4vbGFiZWxlZGdyYXBoaWNzLmpzJ1xuLyogTmVlZGVkIHRvIGVuc3VyZSB0aGF0IHJvbGx1cC5qcyBpbmNsdWRlcyBjbGFzcyBkZWZpbml0aW9ucyBhbmQgdGhlIGNsYXNzZXNcbmFyZSB2aXNpYmxlIGluc2lkZSBkb2N0ZXN0cy5cbiovXG53aW5kb3cuUElYSUFwcCA9IFBJWElBcHBcbndpbmRvdy5CbHVyRmlsdGVyID0gQmx1ckZpbHRlclxud2luZG93LkZsaXBFZmZlY3QgPSBGbGlwRWZmZWN0XG53aW5kb3cuRmxpcHBhYmxlID0gRmxpcHBhYmxlXG53aW5kb3cuRGVlcFpvb21JbmZvID0gRGVlcFpvb21JbmZvXG53aW5kb3cuRGVlcFpvb21JbWFnZSA9IERlZXBab29tSW1hZ2VcbndpbmRvdy5Qb3BvdmVyID0gUG9wb3Zlclxud2luZG93LlNjYXR0ZXJDb250YWluZXIgPSBTY2F0dGVyQ29udGFpbmVyXG53aW5kb3cuRGlzcGxheU9iamVjdFNjYXR0ZXIgPSBEaXNwbGF5T2JqZWN0U2NhdHRlclxud2luZG93LkNvbW1hbmQgPSBDb21tYW5kXG53aW5kb3cuUmVjb3JkZXJUb29scyA9IFJlY29yZGVyVG9vbHNcbndpbmRvdy5UaW1lbGluZSA9IFRpbWVsaW5lXG53aW5kb3cuQXBwVGVzdCA9IEFwcFRlc3RcbndpbmRvdy5UaGVtZSA9IFRoZW1lXG53aW5kb3cuQnV0dG9uID0gQnV0dG9uXG53aW5kb3cuQnV0dG9uR3JvdXAgPSBCdXR0b25Hcm91cFxud2luZG93LlNsaWRlciA9IFNsaWRlclxud2luZG93LlN3aXRjaCA9IFN3aXRjaFxud2luZG93LlBvcHVwID0gUG9wdXBcbndpbmRvdy5Qb3B1cE1lbnUgPSBQb3B1cE1lbnVcbndpbmRvdy5Nb2RhbCA9IE1vZGFsXG53aW5kb3cuVm9sYXRpbGUgPSBWb2xhdGlsZVxud2luZG93Lk1lc3NhZ2UgPSBNZXNzYWdlXG53aW5kb3cuVG9vbHRpcCA9IFRvb2x0aXBcbndpbmRvdy5CYWRnZSA9IEJhZGdlXG53aW5kb3cuUHJvZ3Jlc3MgPSBQcm9ncmVzc1xud2luZG93Lkxpc3QgPSBMaXN0XG53aW5kb3cuTGFiZWxlZEdyYXBoaWNzID0gTGFiZWxlZEdyYXBoaWNzXG53aW5kb3cuRm9udEluZm8gPSBGb250SW5mbyJdLCJuYW1lcyI6WyJFdmVudHMiLCJFbGVtZW50cyIsIkludGVyYWN0aW9uTWFwcGVyIiwiUG9wdXBNZW51Il0sIm1hcHBpbmdzIjoiOzs7SUFBQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBZSxNQUFNLEtBQUssQ0FBQzs7SUFFM0I7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxXQUFXLENBQUMsSUFBSSxHQUFHLEVBQUUsRUFBRTs7SUFFM0IsUUFBUSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVE7SUFDckYsUUFBUSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVE7SUFDbkUsUUFBUSxNQUFNLE1B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SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxHQUFHOztJQUVsQixRQUFRLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFDO0lBQ25ELEtBQUs7SUFDTCxDQUFDOztJQUVEO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7QUFDQSxJQUFPLE1BQU0sUUFBUSxTQUFTLEtBQUssQ0FBQzs7SUFFcEM7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxHQUFHOztJQUVsQixRQUFRLEtBQUssQ0FBQyxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFBQztJQUN2QyxLQUFLO0lBQ0wsQ0FBQzs7SUN6T0Q7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBLElBQWUsTUFBTSxRQUFRLFNBQVMsSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUNyRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksV0FBVyxDQUFDLElBQUksR0FBRyxFQUFFLEVBQUU7O0lBRTNCLFFBQVEsS0FBSyxHQUFFO0lBQ2Y7SUFDQSxRQUFRLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNsRCxRQUFRLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBSzs7SUFFMUIsUUFBUSxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFB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QUFHLE9BQU07SUFDNUIsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBQzs7SUFFN0I7SUFDQTtJQUNBLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFFO0lBQzFDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUM7O0lBRTlCO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDN0IsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQztJQUMzRSxTQUFTOztJQUVUO0lBQ0E7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7SUFDNUIsWUFBWSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUM7SUFDbEYsU0FBUzs7SUFFVCxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7SUFDbEMsWUFBWSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUM7SUFDNUYsU0FBUzs7SUFFVDtJQUNBO0lBQ0EsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJO0lBQzNDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUM7SUFDM0IsWUFBWSxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsRUFBQztJQUN2RyxTQUFTLEVBQUM7O0lBRVYsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJO0lBQzNDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUM7SUFDM0IsU0FBUyxFQUFDOztJQUVWLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSTtJQUMxQyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFDO0lBQzNCLFlBQVksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUM7SUFDckcsU0FBUyxFQUFDOztJQUVWLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSTtJQUMzQztJQUNBLFlBQVksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUM7SUFDdEcsU0FBUyxFQUFDOztJQUVWLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSTtJQUN6QyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFDO0lBQzNCLFlBQVksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUN4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LENBQUMsQ0FBQyxFQUFDO0lBQzNCLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUU7SUFDeEIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUM7SUFDNUUsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQSxJQUFJLGdCQUFnQixHQUFHO0lBQ3ZCLFFBQVEsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07SUFDakMsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7SUFDakIsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDckQsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDcEMsWUFBWSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7SUFDcEMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDdEUsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVB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SUFDbEQsUUFBUSxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLEdBQUU7SUFDcEcsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsVUFBUztJQUN0RCxRQUFRLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsR0FBRTtJQUNwRyxRQUFRLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBQzs7SUFFaEUsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7SUFDaEYsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFLEVBQUM7O0lBRS9FLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBQzs7SUFFbEQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxLQUFLO0lBQ0wsQ0FBQzs7SUFFRCxVQUFVLENBQUMsTUFBTSxHQUFHLElBQUk7O0lDaDdDakIsTUFBTSxVQUFVLENBQUM7SUFDeEIsSUFBSSxXQUFXO0lBQ2YsUUFBUSxHQUFHO0lBQ1gsUUFBUTtJQUNSLFlBQVksQ0FBQyxHQUFHLENBQUM7SUFDakIsWUFBWSxDQUFDLEdBQUcsQ0FBQztJQUNqQixZQUFZLEtBQUssR0FBRyxJQUFJO0lBQ3hCLFlBQVksTUFBTSxHQUFHLEdBQUc7SUFDeEIsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixZQUFZLFNBQVMsR0FBRyxJQUFJO0lBQzVCLFlBQVksS0FBSyxHQUFHLENBQUM7SUFDckIsWUFBWSxRQUFRLEdBQUcsR0FBRztJQUMxQixZQUFZLFFBQVEsR0FBRyxHQUFHO0lBQzFCLFlBQVksUUFBUSxHQUFHLENBQUM7SUFDeEIsU0FBUyxHQUFHLEVBQUU7SUFDZCxNQUFNO0lBQ04sUUFBUSxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUc7SUFDdEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDbEIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUs7SUFDMUIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUM7SUFDekIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFNBQVE7SUFDaEMsUUFBUSxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQUs7SUFDaEMsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU07SUFDbEMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsSUFBSSxJQUFJLEdBQUcsUUFBUSxHQUFHLE1BQU0sQ0FBQyxXQUFVO0lBQ3ZFLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLElBQUksSUFBSSxHQUFHLFNBQVMsR0FBRyxNQUFNLENBQUMsWUFBVztJQUMzRSxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSTtJQUM3QixRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUM7SUFDcEI7SUFDQSxZQUFZLEtBQUs7SUFDakIsWUFBWSxNQUFNO0lBQ2xCLFlBQVksUUFBUTtJQUNwQixZQUFZLFNBQVM7SUFDckI7SUFDQSxTQUFTLEVBQUM7SUFDVixLQUFLOztJQUVMLElBQUksTUFBTSxHQUFHO0lBQ2IsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUIsWUFBWSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRTtJQUNuQyxZQUFZLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSTtJQUNqQyxTQUFTO0lBQ1QsS0FBSztJQUNMLENBQUM7QUFDRCxBQXNJQTtBQUNBLElBQU8sTUFBTSxPQUFPLENBQUM7SUFDckIsSUFBSSxXQUFXO0lBQ2YsUUFBUSxtQkFBbUI7SUFDM0IsUUFBUSxZQUFZO0lBQ3BCLFFBQVEsV0FBVztJQUNuQixRQUFRLFVBQVU7SUFDbEIsUUFBUTtJQUNSLFlBQVksZUFBZSxHQUFHLEtBQUs7SUFDbkMsWUFBWSxZQUFZLEdBQUcsQ0FBQztJQUM1QixZQUFZLFlBQVksR0FBRyxHQUFHO0lBQzlCLFlBQVksYUFBYSxHQUFHLENBQUM7SUFDN0IsWUFBWSxRQUFRLEdBQUcsS0FBSztJQUM1QixZQUFZLE1BQU0sR0FBRyxJQUFJO0lBQ3pCLFlBQVksV0FBVyxHQUFHLEtBQUs7SUFDL0IsWUFBWSxZQUFZLEdBQUcsSUFBSTtJQUMvQixZQUFZLFFBQVEsR0FBRyxJQUFJO0lBQzNCLFlBQVksU0FBUyxHQUFHLElBQUk7SUFDNUIsWUFBWSxPQUFPLEdBQUcsSUFBSTtJQUMxQixZQUFZLE1BQU0sR0FBRyxJQUFJO0lBQ3pCLFlBQVksT0FBTyxHQUFHLElBQUk7SUFDMUIsWUFBWSxRQUFRLEdBQUcsSUFBSTtJQUMzQixZQUFZLFNBQVMsR0FBRyxJQUFJO0lBQzVCLFlBQVksUUFBUSxHQUFHLElBQUk7SUFDM0IsU0FBUyxHQUFHLEVBQUU7SUFDZCxNQUFNO0lBQ04sUUFBUSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsb0JBQW1CO0lBQ3RELFFBQVEsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEdBQUU7SUFDekIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLGFBQVk7SUFDeEMsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLGFBQVk7SUFDeEMsUUFBUSxJQUFJLENBQUMsZUFBZSxHQUFHLGdCQUFlO0lBQzlDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFVO0lBQ3BDLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxhQUFZO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFPO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFNO0lBQ25DLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFNO0lBQzVCLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFXO0lBQ3RDLFFBQVEsSUFBSSxDQUFDLGFBQWEsR0FBRyxjQUFhO0lBQzFDLFFBQVEsSUFBSSxRQUFRLEVBQUU7SUFDdEIsWUFBWSxJQUFJLENBQUMsSUFBSSxHQUFFO0lBQ3ZCLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksSUFBSSxHQUFHO0lBQ1gsUUFBUSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSztJQUNoRCxZQUFZLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFZO0lBQ3JDLFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQU87SUFDdEQsWUFBWSxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUM7SUFDakUsWUFBWSxPQUFPLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFFO0lBQ2hDLFlBQVksSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLElBQUksRUFBQztJQUM1RCxZQUFZLEdBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFDO0lBQ2xDO0lBQ0E7SUFDQTtJQUNBLFlBQVksSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFDO0lBQy9ELFlBQVksSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ2hFLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSTtJQUN4RCxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUs7SUFDdkQsb0JBQW9CLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxHQUFFO0lBQ3RELG9CQUFvQixPQUFPLENBQUMsSUFBSSxFQUFDO0lBQ2pDLGlCQUFpQixFQUFDO0lBQ2xCLGFBQWEsRUFBQztJQUNkLFNBQVMsQ0FBQztJQUNWLEtBQUs7O0lBRUwsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFO0lBQ3hCLFFBQVEsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEtBQUs7SUFDaEQsWUFBWSxJQUFJLE9BQU8sR0FBRyxJQUFJLFVBQVU7SUFDeEMsZ0JBQWdCLElBQUksQ0FBQyxXQUFXO0lBQ2hDLGdCQUFnQixJQUFJLENBQUMsbUJBQW1CO0lBQ3hDLGdCQUFnQjtJQUNoQixvQkFBb0IsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9CLG9CQUFvQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0Isb0JBQW9CLFVBQVUsRUFBRSxNQUFNLENBQUMsS0FBSztJQUM1QyxvQkFBb0IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0lBQ3ZDLG9CQUFvQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7SUFDN0Msb0JBQW9CLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtJQUM3QyxvQkFBb0IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXO0lBQzdDLG9CQUFvQixNQUFNLEVBQUUsTUFBTSxDQUFDLFlBQVk7SUFDL0Msb0JBQW9CLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtJQUM3QyxvQkFBb0IsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO0lBQ25ELG9CQUFvQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7SUFDM0Msb0JBQW9CLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztJQUM3QyxvQkFBb0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO0lBQ3JELGlCQUFpQjtJQUNqQixjQUFhOztJQUViLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0lBQzdCLGdCQUFnQixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDN0MsYUFBYTs7SUFFYixZQUFZLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTs7SUFFdEMsZ0JBQWdCLE1BQU0sZ0JBQWdCLEdBQUcsWUFBWTtJQUNyRCxvQkFBb0IsSUFBSSxPQUFPLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7SUFDM0Qsd0JBQXdCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFFOztJQUU5QztJQUNBLHdCQUF3QixPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxjQUFhO0lBQ2pFLHdCQUF3QixPQUFPLENBQUMsYUFBYSxHQUFHLEVBQUM7O0lBRWpEO0lBQ0Esd0JBQXdCLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtJQUNqRCw0QkFBNEIsSUFBSSxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUM7SUFDM0YsNEJBQTRCLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUM7SUFDdEUseUJBQXlCO0lBQ3pCLHFCQUFxQjs7SUFFckIsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQzs7OztJQUk1QixnQkFBZ0IsT0FBTyxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixFQUFDO0lBQ25FLGFBQWE7O0lBRWIsWUFBWSxJQUFJLFNBQVMsR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUM7SUFDN0UsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUM7O0lBRTlELFlBQVksSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO0lBQ2xDLGdCQUFnQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJO0lBQzFELG9CQUFvQixJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUM7SUFDMUQsaUJBQWlCLEVBQUM7SUFDbEIsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFTO0lBQ3RDLFlBQVksT0FBTyxDQUFDLElBQUksRUFBQztJQUN6QixTQUFTLENBQUM7SUFDVixLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBQztJQUN2QixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBQztJQUNsQyxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNsQyxLQUFLOztJQUVMLElBQUksY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUU7SUFDdEMsUUFBUSxTQUFTLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxZQUFXO0lBQ2xELFFBQVEsU0FBUyxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsYUFBWTtJQUNwRCxRQUFRLFNBQVMsQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLE1BQUs7SUFDNUMsUUFBUSxTQUFTLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFRO0lBQzVDLFFBQVEsU0FBUyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUTtJQUM1QyxRQUFRLFNBQVMsQ0FBQyxZQUFZLEdBQUU7SUFDaEMsS0FBSzs7SUFFTCxJQUFJLEtBQUssQ0FBQyxFQUFFLFlBQVksR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7SUFDeEMsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUM7SUFDbEQsUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsRUFBQztJQUNqRyxhQUFhO0lBQ2IsWUFBWSxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUM7SUFDOUQsWUFBWSxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBUztJQUMxQyxZQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUk7SUFDdEQsZ0JBQWdCLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBQztJQUN0RCxnQkFBZ0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxFQUFDO0lBQzlFLGFBQWEsRUFBQztJQUNkLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksZ0JBQWdCLEdBQUc7SUFDdkIsUUFBUSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMxRCxZQUFZLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLFlBQVksVUFBVSxFQUFFLE1BQU07SUFDOUIsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFFO0lBQ3pDLGFBQWE7SUFDYixTQUFTLEVBQUM7SUFDVixLQUFLOztJQUVMLElBQUksTUFBTSxHQUFHO0lBQ2IsUUFBUSxJQUFJLENBQUMsTUFBTSxHQUFFO0lBQ3JCLEtBQUs7O0lBRUwsSUFBSSxNQUFNLEdBQUc7SUFDYixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO0lBQy9CLFlBQVksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUU7SUFDcEMsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDOztBQUVELElBQU8sTUFBTSxZQUFZLENBQUM7SUFDMUIsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7SUFDeEM7SUFDQTs7SUFFQSxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSTtJQUN4QixRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUM7SUFDdEQsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFDO0lBQ3BELFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBQztJQUNsRCxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBSztJQUM1QixRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBTztJQUM5QixRQUFRLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWM7SUFDakQsUUFBUSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxjQUFhO0lBQy9DLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNuQyxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVM7SUFDdkMsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFROztJQUVyQyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQVk7SUFDN0MsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFZO0lBQzdDLFFBQVEsT0FBTyxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUM7SUFDN0UsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLElBQUksRUFBQztJQUM3QyxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsRUFBQztJQUMxRCxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsRUFBQztJQUNuRSxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFDO0lBQ3JELFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO0lBQy9DLFlBQVksa0JBQWtCLEVBQUUsUUFBUTtJQUN4QyxZQUFZLFdBQVcsRUFBRSxJQUFJO0lBQzdCLFNBQVMsRUFBQztJQUNWLFFBQVEsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFDO0lBQzVELFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBQztJQUN4RCxRQUFRLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUM7SUFDeEQsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFDO0lBQzFEO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDMUIsWUFBWUMsbUJBQWlCLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFDOztJQUVqRixZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNyQyxTQUFTO0lBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDMUIsWUFBWUEsbUJBQWlCLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUM7SUFDNUUsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0lBQzNCLFlBQVlBLG1CQUFpQixDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFDO0lBQzdFLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3RDLFNBQVM7SUFDVCxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFO0lBQzNCLEtBQUs7O0lBRUwsSUFBSSxLQUFLLEdBQUc7SUFDWixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQztJQUNsQyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQztJQUNuQyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUMxQixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDO0lBQzlCLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDOUIsU0FBUyxNQUFNO0lBQ2YsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDbkMsZ0JBQWdCLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWTtJQUMxQyxnQkFBZ0IsVUFBVSxFQUFFLE1BQU07SUFDbEMsb0JBQW9CLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFFO0lBQ3pDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN0QyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQ3hDLHdCQUF3QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUM7SUFDakQscUJBQXFCO0lBQ3JCLGlCQUFpQjtJQUNqQixhQUFhLEVBQUM7SUFDZCxTQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLFNBQVMsR0FBRztJQUNoQixRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBQztJQUM1RCxLQUFLOztJQUVMLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBQztJQUNoQyxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtJQUNoQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNoQyxLQUFLOztJQUVMLElBQUksSUFBSSxXQUFXLEdBQUc7SUFDdEIsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFHOztJQUV4QixRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUU7SUFDbEMsWUFBWSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFDO0lBQy9DLFlBQVksTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFLO0lBQ2hDLFNBQVM7SUFDVCxRQUFRLE9BQU8sTUFBTTtJQUNyQixLQUFLOztJQUVMLElBQUksWUFBWSxHQUFHO0lBQ25CO0lBQ0E7SUFDQTs7SUFFQTtJQUNBOztJQUVBO0lBQ0E7O0lBRUEsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUM7SUFDckM7SUFDQSxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO0lBQ25FLFlBQVksS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXO0lBQ25DLFNBQVMsRUFBQztJQUNWLEtBQUs7O0lBRUwsSUFBSSxZQUFZLEdBQUc7SUFDbkIsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksR0FBRTtJQUNuQyxRQUFRLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBQztJQUNwRSxLQUFLOztJQUVMLElBQUksU0FBUyxHQUFHO0lBQ2hCLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRTtJQUMzQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFFO0lBQzVCLEtBQUs7O0lBRUwsSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7SUFDOUIsUUFBUSxJQUFJLENBQUMsWUFBWSxHQUFFO0lBQzNCLEtBQUs7O0lBRUwsSUFBSSxjQUFjLENBQUMsS0FBSyxFQUFFO0lBQzFCLFFBQVEsSUFBSSxLQUFLLEdBQUcsR0FBRTtJQUN0QixRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxNQUFLO0lBQ2hDLFFBQVEsSUFBSSxLQUFLLEdBQUcsSUFBRztJQUN2QixRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxHQUFHLEVBQUU7SUFDaEMsWUFBWSxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUk7SUFDaEMsU0FBUyxNQUFNO0lBQ2YsWUFBWSxLQUFLLEdBQUcsQ0FBQyxLQUFJO0lBQ3pCLFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSztJQUNwQixLQUFLOztJQUVMLElBQUksVUFBVSxDQUFDLElBQUksRUFBRTtJQUNyQixRQUFRLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUM7SUFDaEQsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFDO0lBQ2hELFFBQVEsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUTtJQUMzRCxRQUFRLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU07SUFDekQsUUFBUSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFLO0lBQ3hDLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTTtJQUN6QyxRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDO0lBQ3ZFLEtBQUs7O0lBRUwsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRTtJQUMzQyxRQUFRLElBQUksT0FBTyxFQUFFO0lBQ3JCLFlBQVksU0FBUyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFDO0lBQ2pFLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUU7SUFDM0MsUUFBUSxJQUFJLE9BQU8sRUFBRTtJQUNyQixZQUFZLFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBQztJQUNqRSxTQUFTO0lBQ1QsS0FBSzs7OztJQUlMLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtJQUNuQixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDNUMsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQzVELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtJQUNwQixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDNUMsUUFBUSxJQUFJLE1BQU0sRUFBRTtJQUNwQixZQUFZLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxFQUFDO0lBQzVELFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksS0FBSyxDQUFDLEVBQUUsWUFBWSxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtJQUN4QyxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBQztJQUNyRCxZQUFZLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBQztJQUNyRCxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUTtJQUNoRSxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTTtJQUM5RCxZQUFZLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBSztJQUN0RCxZQUFZLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTTtJQUN4RCxZQUFZLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQUs7SUFDdkQsWUFBWSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFNO0lBQ3pELFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFDO0lBQ2hDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQ3RDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDO0lBQ3ZDLFNBQVMsTUFBTTtJQUNmLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUM7SUFDcEQsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUM7SUFDdEMsU0FBUztJQUNULFFBQVEsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQU87SUFDaEUsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEdBQUU7SUFDMUQsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBRyxNQUFLO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsTUFBSztJQUN6QyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDdEMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRTs7SUFFcEMsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQU87SUFDcEMsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsR0FBRyxFQUFDO0lBQzVDLFFBQVEsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU87SUFDbEMsY0FBYyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUNwRSxjQUFjLElBQUksQ0FBQyxXQUFVO0lBQzdCLFFBQVEsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQzNFLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFVO0lBQ2pFLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFXO0lBQ25FLFFBQVEsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQUs7SUFDdEQsUUFBUSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTTtJQUN4RCxRQUFRLElBQUksRUFBRSxHQUFHLGFBQVk7SUFDN0IsUUFBUSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ2pFLFFBQVEsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsRUFBQztJQUNqRSxRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFNO0lBQy9DLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU07O0lBRS9DLFFBQVEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUM7SUFDdkYsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSTtJQUNoRixRQUFRLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBQztJQUN0QyxRQUFRLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFO0lBQ25ELFlBQVksU0FBUyxFQUFFLE9BQU87SUFDOUIsWUFBWSxJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU87SUFDaEMsWUFBWSxlQUFlLEVBQUUsU0FBUztJQUN0QyxZQUFZLFFBQVE7SUFDcEIsWUFBWSxVQUFVLEVBQUUsQ0FBQyxJQUFJO0lBQzdCLGdCQUFnQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDbEM7SUFDQSxvQkFBb0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDO0lBQzdDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUM7O0lBRTNDLG9CQUFvQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7SUFDN0Msd0JBQXdCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFDO0lBQ2pELHFCQUFxQjtJQUNyQixpQkFBaUIsTUFBTTs7SUFFdkIsb0JBQW9CLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLEVBQUU7SUFDcEQsd0JBQXdCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFDO0lBQ3BFLHdCQUF3QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBQztJQUNyRSxxQkFBcUIsTUFBTTtJQUMzQix3QkFBd0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUM7SUFDaEQscUJBQXFCO0lBQ3JCLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRTtJQUN0QyxpQkFBaUI7SUFDakIsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLFlBQVc7SUFDaEQsZ0JBQWdCLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDbkMsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxHQUFHLFFBQU87SUFDdEQsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBaUI7SUFDOUUsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxtQkFBa0I7O0lBRWhGLGdCQUFnQixJQUFJLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBSztJQUN0RSxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsU0FBUTtJQUNoRCxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEdBQUcsYUFBWTtJQUN4RCxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsVUFBUztJQUNsRCxhQUFhO0lBQ2IsWUFBWSxPQUFPLEVBQUUsSUFBSTtJQUN6QixTQUFTLEVBQUM7O0lBRVY7SUFDQSxRQUFRLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsRUFBRTtJQUMxRCxZQUFZLEtBQUssRUFBRSxXQUFXO0lBQzlCLFlBQVksSUFBSSxFQUFFLE1BQU0sQ0FBQyxPQUFPO0lBQ2hDLFlBQVksU0FBUyxFQUFFLE9BQU8sR0FBRyxRQUFRO0lBQ3pDLFlBQVksZUFBZSxFQUFFLFNBQVM7SUFDdEMsWUFBWSxLQUFLLEVBQUUsQ0FBQztJQUNwQixZQUFZLE1BQU0sRUFBRSxDQUFDO0lBQ3JCLFlBQVksQ0FBQyxFQUFFLENBQUM7SUFDaEIsWUFBWSxDQUFDLEVBQUUsQ0FBQztJQUNoQixZQUFZLFVBQVUsRUFBRSxDQUFDLElBQUk7SUFDN0IsZ0JBQWdCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNsQyxvQkFBb0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDO0lBQ3pDO0lBQ0EsaUJBQWlCLE1BQU07SUFDdkIsb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBQztJQUN4QztJQUNBLGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsU0FBUyxFQUFDO0lBQ1YsS0FBSztJQUNMLENBQUM7O0lDdG9CTSxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxHQUFFOzs7SUFHMUM7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBLElBQU8sTUFBTSxJQUFJLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN0QyxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO0lBQzlCLFFBQVEsS0FBSyxDQUFDLE9BQU8sRUFBQztJQUN0QixRQUFRLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBRztJQUN0QixRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFDO0lBQzFCLEtBQUs7O0lBRUwsSUFBSSxPQUFPLFNBQVMsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRTtJQUN0RCxRQUFRLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDekYsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksUUFBUSxDQUFDLEdBQUcsRUFBRSxLQUFLLEdBQUcsS0FBSyxFQUFFO0lBQ2pDLFFBQVEsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDeEMsWUFBWSxJQUFJLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQ2xELFlBQVksS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUM7SUFDM0IsWUFBWSxJQUFJLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBQztJQUNwRSxTQUFTO0lBQ1QsYUFBYTtJQUNiLFlBQVksaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUM7SUFDdkQsWUFBWSxJQUFJLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFDO0lBQzNELFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksVUFBVSxHQUFHO0lBQ2pCLFFBQVEsSUFBSSxLQUFLLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDbkQsUUFBUSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBQztJQUMxQixRQUFRLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUU7SUFDN0IsWUFBWSxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBQztJQUM5QyxTQUFTO0lBQ1QsUUFBUSxPQUFPLEtBQUssQ0FBQyxJQUFJO0lBQ3pCLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLEtBQUssR0FBRyxLQUFLLEVBQUU7SUFDcEMsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxFQUFFLENBRXhCO0lBQ1QsUUFBUSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFFO0lBQ3JDLFFBQVEsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFO0lBQ3hCLFlBQVksSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksR0FBRTtJQUMzRSxZQUFZLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDO0lBQy9CLFlBQVksSUFBSSxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBQztJQUNoRixTQUFTO0lBQ1QsYUFBYTtJQUNiLFlBQVksSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEtBQUssR0FBRTtJQUM3RSxZQUFZLElBQUksS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLGlCQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUM7SUFDaEYsWUFBWSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBQztJQUMvQixTQUFTO0lBQ1QsS0FBSztJQUNMLENBQUM7O0lDMUVEO0lBQ0E7SUFDQTtBQUNBLElBQU8sTUFBTSxVQUFVLENBQUM7SUFDeEIsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFO0lBQ3ZCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQzFCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQzFCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRTtJQUNwQixLQUFLOztJQUVMO0lBQ0EsSUFBSSxLQUFLLEdBQUc7SUFDWixRQUFRLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUU7SUFDNUIsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxHQUFFO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUMvQixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRTtJQUMzQixLQUFLOztJQUVMO0lBQ0E7O0lBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtJQUM1QixRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxLQUFLO0lBQzlDLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLEtBQUs7SUFDL0MsUUFBUSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUM7SUFDckMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDN0IsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDaEMsUUFBUSxPQUFPLElBQUk7SUFDbkIsS0FBSzs7SUFFTCxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUU7SUFDcEIsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBQztJQUN6RCxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFDO0lBQzNELFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxJQUFJLEdBQUcsRUFBQztJQUNuRSxLQUFLOztJQUVMO0lBQ0EsSUFBSSxNQUFNLEdBQUc7SUFDYixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRTtJQUMzQixRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFFO0lBQzVCLEtBQUs7O0lBRUw7SUFDQSxJQUFJLE9BQU8sR0FBRztJQUNkLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRTtJQUNwQixLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRTtJQUM5QyxRQUFRLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUN2QyxRQUFRLElBQUksSUFBSSxJQUFJLElBQUksRUFBRTtJQUMxQixZQUFZLE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUM7SUFDL0MsWUFBWSxJQUFJLENBQUMsVUFBVSxHQUFFO0lBQzdCLFNBQVM7SUFDVCxRQUFRLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFDO0lBQ3JDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksRUFBQztJQUNsQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBQztJQUNyRCxLQUFLO0lBQ0wsQ0FBQzs7SUFFRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLGNBQWMsU0FBUyxVQUFVLENBQUM7O0lBRS9DLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7SUFDcEMsUUFBUSxLQUFLLENBQUMsS0FBSyxFQUFDO0lBQ3BCLFFBQVEsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFLO0lBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFFO0lBQy9DLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFDO0lBQ3pELFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFDO0lBQ3pELFFBQVEsSUFBSSxXQUFXLEVBQUU7SUFDekIsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEVBQUM7SUFDbEUsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxRQUFRLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7SUFDNUI7SUFDQSxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxLQUFLO0lBQzlDLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLEtBQUs7O0lBRS9DLFFBQVEsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDeEMsWUFBWSxJQUFJLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQ2xELFlBQVksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUU7SUFDN0M7SUFDQSxnQkFBZ0IsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQU87SUFDMUMsZ0JBQWdCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUM7SUFDOUQsZ0JBQWdCLE9BQU8sS0FBSztJQUM1QixhQUFhO0lBQ2IsU0FBUztJQUNUO0lBQ0EsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUM7SUFDbEQsUUFBUSxJQUFJLE9BQU8sRUFBRTtJQUNyQixZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLHdCQUF3QixFQUFFLE9BQU8sRUFBQztJQUMxRSxZQUFZLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUM7SUFDMUQsWUFBWSxPQUFPLEtBQUs7SUFDeEIsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUM7SUFDbkQsUUFBUSxJQUFJLElBQUksRUFBRTtJQUNsQixZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixFQUFFLElBQUksRUFBQztJQUMzRSxZQUFZLElBQUksT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUM7SUFDaEQsWUFBWSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFDO0lBQzFELFlBQVksT0FBTyxLQUFLO0lBQ3hCLFNBQVM7SUFDVCxRQUFRLE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQztJQUM1QyxLQUFLOztJQUVMO0lBQ0EsSUFBSSxXQUFXLEdBQUc7SUFDbEIsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTO0lBQzFCLFlBQVksTUFBTTtJQUNsQixRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUU7SUFDM0IsS0FBSzs7SUFFTDtJQUNBLElBQUksT0FBTyxHQUFHO0lBQ2QsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTO0lBQzFCLFlBQVksTUFBTTtJQUNsQixRQUFRLElBQUksQ0FBQyxhQUFhLEdBQUU7SUFDNUIsS0FBSzs7SUFFTDtJQUNBLElBQUksT0FBTyxHQUFHO0lBQ2QsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUk7SUFDN0IsUUFBUSxLQUFLLENBQUMsT0FBTyxHQUFFO0lBQ3ZCLFFBQVEsSUFBSTtJQUNaLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUU7SUFDL0IsU0FBUyxDQUFDLE9BQU8sS0FBSyxFQUFFO0lBQ3hCLFlBQVksT0FBTyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLEVBQUM7SUFDL0QsU0FBUztJQUNULEtBQUs7O0lBRUwsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtJQUM1QixRQUFRLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBQztJQUMxQyxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUU7SUFDaEMsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUIsWUFBWSxJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUMsUUFBTztJQUMxQyxZQUFZLElBQUksV0FBVyxHQUFHLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUM7SUFDbEUsWUFBWSxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBQztJQUN4QyxZQUFZLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEVBQUUsT0FBTyxFQUFDO0lBQ3BFLFlBQVksTUFBTTtJQUNsQixTQUFTO0lBQ1QsUUFBUSxJQUFJO0lBQ1osWUFBWSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUM7SUFDdkQsWUFBWSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUM7SUFDNUUsU0FBUztJQUNULFFBQVEsT0FBTyxHQUFHLEVBQUU7SUFDcEIsWUFBWSxPQUFPLENBQUMsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEdBQUcsQ0FBQyxPQUFPLEVBQUM7SUFDL0QsU0FBUztJQUNULEtBQUs7O0lBRUw7SUFDQSxJQUFJLFlBQVksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFO0lBQzVCO0lBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDNUI7SUFDQSxZQUFZLE1BQU07SUFDbEIsU0FBUztJQUNULFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtJQUNqQyxZQUFZLFVBQVUsQ0FBQyxNQUFNO0lBQzdCLGdCQUFnQixJQUFJLENBQUMsWUFBWSxHQUFFO0lBQ25DLGFBQWEsRUFBRSxLQUFLLEVBQUM7SUFDckIsWUFBWSxNQUFNO0lBQ2xCLFNBQVM7SUFDVCxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0lBQ3ZDLFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEdBQUU7SUFDMUMsWUFBWSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ3JDLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUU7SUFDOUIsU0FBUztJQUNULEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0EsSUFBSSxhQUFhLENBQUMsU0FBUyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsRUFBRSxFQUFFO0lBQzdDLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQzVCLFlBQVksTUFBTTtJQUNsQixTQUFTO0lBQ1QsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUN2QyxZQUFZLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7SUFDckM7SUFDQSxnQkFBZ0IsVUFBVSxDQUFDLE1BQU07SUFDakMsb0JBQW9CLElBQUksQ0FBQyxhQUFhLEdBQUU7SUFDeEMsaUJBQWlCLEVBQUUsS0FBSyxFQUFDO0lBQ3pCLGdCQUFnQixNQUFNO0lBQ3RCLGFBQWE7SUFDYixZQUFZLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDckIsWUFBWSxJQUFJLElBQUksR0FBRyxHQUFFO0lBQ3pCLFlBQVksT0FBTyxDQUFDLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtJQUMvRCxnQkFBZ0IsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEdBQUU7SUFDOUMsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUMzQyxvQkFBb0IsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFDO0lBQzdELG9CQUFvQixJQUFJLFFBQVEsRUFBRTtJQUNsQyx3QkFBd0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUM7SUFDbEUscUJBQXFCO0lBQ3JCLHlCQUF5QjtJQUN6Qix3QkFBd0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDdEMsd0JBQXdCLENBQUMsSUFBSSxFQUFDO0lBQzlCLHFCQUFxQjtJQUNyQixpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFlBQVksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU07SUFDN0MsZ0JBQWdCLElBQUksQ0FBQyxhQUFhLEdBQUU7SUFDcEMsYUFBYSxFQUFDO0lBQ2QsU0FBUztJQUNULEtBQUs7SUFDTCxDQUFDO0FBQ0QsQUF3RkE7O0lBRUE7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUNBLElBQU8sTUFBTSxnQkFBZ0IsU0FBUyxVQUFVLENBQUM7O0lBRWpELElBQUksV0FBVyxDQUFDLEtBQUssRUFBRTtJQUN2QixRQUFRLEtBQUssQ0FBQyxLQUFLLEVBQUM7SUFDcEIsUUFBUSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLHVDQUF1QyxFQUFDO0lBQ3RGLFFBQVEsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssS0FBSztJQUN0QyxZQUFZLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDcEMsZ0JBQWdCLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsS0FBSTtJQUMxRDtJQUNBLGdCQUFnQixJQUFJLGVBQWUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWU7SUFDN0UsZ0JBQWdCLElBQUksVUFBVSxHQUFHLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFDO0lBQ2pGLGdCQUFnQixJQUFJLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFDO0lBQzNELGdCQUFnQixJQUFJLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFDO0lBQ3BELGdCQUFnQixJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFDO0lBQzlELGFBQWE7SUFDYixVQUFTO0lBQ1QsS0FBSzs7SUFFTCxJQUFJLE9BQU8sR0FBRztJQUNkLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7SUFDdkMsWUFBWSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRTtJQUMxQyxZQUFZLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzlDLFlBQVksSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBQztJQUN0QyxZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFDO0lBQ3ZFLFNBQVM7SUFDVCxLQUFLOztJQUVMLElBQUksT0FBTyxHQUFHO0lBQ2QsUUFBUSxJQUFJLEtBQUssR0FBRyxHQUFFO0lBQ3RCLFFBQVEsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7SUFDMUMsWUFBWSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRTtJQUMxQyxZQUFZLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzlDLFlBQVksS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUM7SUFDdkMsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFDO0lBQzNELEtBQUs7O0lBRUwsSUFBSSxNQUFNLEdBQUc7SUFDYixRQUFRLEtBQUssQ0FBQyxNQUFNLEdBQUU7SUFDdEIsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBQztJQUNyRCxLQUFLOztJQUVMLElBQUksT0FBTyxHQUFHO0lBQ2QsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBQztJQUNyRCxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFFO0lBQy9CLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJO0lBQzFCLFFBQVEsS0FBSyxDQUFDLE9BQU8sR0FBRTtJQUN2QixLQUFLO0lBQ0wsQ0FBQzs7SUM5V0Q7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0FBQ0EsSUFBTyxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFDLElBQUksV0FBVztJQUNmLFFBQVEsS0FBSztJQUNiLFFBQVEsSUFBSTtJQUNaLFFBQVEsS0FBSztJQUNiLFFBQVEsSUFBSTtJQUNaLFFBQVEsSUFBSTtJQUNaLFFBQVEsS0FBSztJQUNiLFFBQVEsTUFBTTtJQUNkLFFBQVEsUUFBUTtJQUNoQixRQUFRLE9BQU87SUFDZixRQUFRLFVBQVUsR0FBRyxJQUFJO0lBQ3pCLE1BQU07SUFDTixRQUFRLEtBQUssR0FBRTtJQUNmLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQzFCLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFLO0lBQzdCLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ3hCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFLO0lBQzFCLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ3hCLFFBQVEsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFJO0lBQ3hCLFFBQVEsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFLO0lBQy9CLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFNO0lBQ2pDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFRO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFPO0lBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsR0FBRTtJQUMvQixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLEdBQUU7SUFDbEMsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksR0FBRyxHQUFFO0lBQ2xDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBQztJQUNwQyxRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBSztJQUM5QixRQUFRLElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVTtJQUNwQyxRQUFRLElBQUksQ0FBQyxJQUFJLEdBQUcsTUFBSztJQUN6QixRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUM7SUFDdEUsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxFQUFDO0lBQ3BEO0lBQ0EsWUFBWSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBQztJQUN6RSxRQUFRLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBSztJQUNoQyxRQUFRLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSTs7SUFFOUIsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUk7O0lBRXpCLFFBQVEsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFJO0lBQ2hDLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFJOztJQUUvQixRQUFRLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRTtJQUN4QyxRQUFRLElBQUksQ0FBQyxNQUFNLEdBQUU7SUFDckIsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQUs7SUFDOUIsS0FBSzs7OztJQUlMO0lBQ0EsSUFBSSxVQUFVLEdBQUc7SUFDakIsUUFBUSxPQUFPLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU07SUFDN0QsS0FBSzs7SUFFTDtJQUNBO0lBQ0EsSUFBSSxJQUFJLFNBQVMsR0FBRztJQUNwQixRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLEVBQUU7SUFDckMsWUFBWSxJQUFJLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUU7SUFDOUMsWUFBWSxRQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUM7SUFDN0MsWUFBWSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUM7SUFDM0MsWUFBWSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUM7SUFDekUsWUFBWSxRQUFRLENBQUMsT0FBTyxHQUFFO0lBQzlCLFlBQVksUUFBUSxDQUFDLFdBQVcsR0FBRyxNQUFLO0lBQ3hDLFlBQVksSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFRO0lBQ3RDLFNBQVM7SUFDVCxRQUFRLE9BQU8sSUFBSSxDQUFDLFVBQVU7SUFDOUIsS0FBSzs7SUFFTDtJQUNBO0lBQ0EsSUFBSSxJQUFJLElBQUksR0FBRztJQUNmLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksRUFBRTtJQUNoQyxZQUFZLElBQUksUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsR0FBRTtJQUM5QyxZQUFZLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBQztJQUMzQyxZQUFZLFFBQVEsQ0FBQyxXQUFXLEdBQUcsTUFBSztJQUN4QyxZQUFZLElBQUksQ0FBQyxLQUFLLEdBQUcsU0FBUTtJQUNqQyxZQUFZLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBQztJQUNyQyxTQUFTO0lBQ1QsUUFBUSxPQUFPLElBQUksQ0FBQyxLQUFLO0lBQ3pCLEtBQUs7O0lBRUw7SUFDQSxJQUFJLE1BQU0sR0FBRztJQUNiLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSztJQUN0QixZQUFZLE9BQU8sQ0FBQyxHQUFHO0lBQ3ZCLGdCQUFnQixlQUFlO0lBQy9CLGdCQUFnQixJQUFJLENBQUMsS0FBSztJQUMxQixnQkFBZ0IsVUFBVTtJQUMxQixnQkFBZ0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLGdCQUFnQixTQUFTO0lBQ3pCLGdCQUFnQixJQUFJLENBQUMsSUFBSTtJQUN6QixnQkFBZ0IsU0FBUztJQUN6QixnQkFBZ0IsSUFBSSxDQUFDLElBQUk7SUFDekIsZ0JBQWdCLE1BQU07SUFDdEIsZ0JBQWdCLElBQUksQ0FBQyxVQUFVO0lBQy9CLGdCQUFnQixNQUFNO0lBQ3RCLGdCQUFnQixJQUFJLENBQUMsV0FBVztJQUNoQyxnQkFBZ0IsU0FBUztJQUN6QixnQkFBZ0IsSUFBSSxDQUFDLFFBQVE7SUFDN0IsY0FBYTtJQUNiLEtBQUs7O0lBRUw7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7SUFDM0IsUUFBUSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVE7SUFDbkMsUUFBUSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVE7SUFDbkMsUUFBUSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBTztJQUNsQyxRQUFRLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRTtJQUN0QixZQUFZLENBQUMsSUFBSSxRQUFPO0lBQ3hCLFNBQVM7SUFDVCxRQUFRLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRTtJQUN0QixZQUFZLENBQUMsSUFBSSxRQUFPO0lBQ3hCLFNBQVM7SUFDVCxRQUFRLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkMsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsSUFBSSxjQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtJQUM3QixRQUFRLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFRO0lBQzdCLFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVE7SUFDN0IsUUFBUSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUM7SUFDN0MsUUFBUSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRTtJQUNsQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxFQUFDO0lBQ3ZDLFNBQVM7SUFDVCxRQUFRLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFO0lBQ2xDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDLEVBQUM7SUFDeEMsU0FBUztJQUNULFFBQVEsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxLQUFLOztJQUVMO0lBQ0EsSUFBSSxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtJQUM1QixRQUFRLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRTtJQUN4RSxZQUFZLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFTO0lBQ3pDLFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ25ELFlBQVksUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUM7SUFDM0QsWUFBWSxRQUFRLENBQUMsS0FBSyxHQUFFO0lBQzVCLFlBQVksUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFDO0lBQzdDLFlBQVksUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFDO0lBQzNDLFlBQVksUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFDO0lBQ3pELFlBQVksUUFBUSxDQUFDLE9BQU8sR0FBRTtJQUM5QixZQUFZLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQztJQUN6QyxTQUFTLE1BQU07SUFDZixZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQztJQUM1QyxTQUFTO0lBQ1QsS0FBSzs7SUFFTDtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtJQUMvQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBQztJQUM5QyxTQUFTO0lBQ1QsUUFBUSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSTtJQUM1QixZQUFZLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDbkMsWUFBWSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUU7SUFDckQsZ0JBQWdCLElBQUksT0FBTyxFQUFFO0lBQzdCLG9CQUFvQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFO0lBQ3BELGlCQUFpQjtJQUNqQixhQUFhO0lBQ2IsU0FBUyxFQUFDO0lBQ1YsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRTtJQUM3QixLQUFLOztJQUVMO0lBQ0EsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7SUFDbkMsUUFBUSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUM7SUFDL0MsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUU7SUFDMUMsUUFBUSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUM7SUFDaEMsUUFBUSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUM7SUFDdkMsUUFBUSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDckQsUUFBUSxRQUFRLENBQUMsT0FBTyxHQUFFO0lBQzFCLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUM7SUFDL0IsS0FBSzs7SUFFTDtJQUNBLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtJQUNqQyxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDckMsWUFBWSxPQUFPLENBQUMsSUFBSSxDQUFDLDhCQUE4QixFQUFDO0lBQ3hELFlBQVksTUFBTTtJQUNsQixTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUM7SUFDaEMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFDO0lBQ3JDLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQzVCLFlBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsRUFBQztJQUMzRCxTQUFTO0lBQ1Q7SUFDQSxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksYUFBYSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtJQUN2QyxRQUFRLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBQztJQUM3QyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUMzQixZQUFZLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUM7SUFDL0MsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFHO0lBQzNCLFFBQVEsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFLO0lBQ2hDLFFBQVEsSUFBSSxTQUFTLEVBQUU7SUFDdkIsWUFBWSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUM7SUFDMUIsWUFBWSxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBQztJQUN0RSxTQUFTO0lBQ1QsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBQztJQUN6QyxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksT0FBTyxHQUFHO0lBQ2QsUUFBUSxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUk7SUFDN0IsUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRTtJQUM3QixRQUFRLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUM7SUFDekMsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRTtJQUM5QixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFFO0lBQzlCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUU7SUFDM0IsS0FBSzs7SUFFTCxJQUFJLFdBQVcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFO0lBQzNCLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFDO0lBQ25DLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUM7SUFDOUIsUUFBUSxJQUFJLENBQUMsT0FBTyxHQUFFO0lBQ3RCLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFDO0lBQ2xDLEtBQUs7O0lBRUwsSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUU7SUFDMUIsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQ3JDLFlBQVksSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDO0lBQzlDLFlBQVksSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFDO0lBQ3ZDLFNBQVM7SUFDVCxLQUFLOztJQUVMO0lBQ0E7SUFDQTtJQUNBLElBQUksWUFBWSxDQUFDLFNBQVMsRUFBRTtJQUM1QixRQUFRLElBQUksS0FBSyxHQUFHLEVBQUM7SUFDckIsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUMxRCxZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQ3JDLGdCQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUM7SUFDM0MsZ0JBQWdCLEtBQUssSUFBSSxFQUFDO0lBQzFCLGFBQWE7SUFDYixTQUFTO0lBQ1QsUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSztJQUMvQixZQUFZLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFDO0lBQzFELEtBQUs7O0lBRUwsSUFBSSxvQkFBb0IsR0FBRztJQUMzQixRQUFRLElBQUksS0FBSyxHQUFHLEVBQUM7SUFDckIsUUFBUSxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUMxRCxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUN2QyxnQkFBZ0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFDO0lBQzNDLGdCQUFnQixLQUFLLElBQUksRUFBQztJQUMxQixhQUFhO0lBQ2IsU0FBUztJQUNULFFBQVEsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUs7SUFDL0IsWUFBWSxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFDO0lBQ2xFLEtBQUs7O0lBRUwsSUFBSSxjQUFjLEdBQUc7SUFDckIsUUFBUSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSTtJQUNoQyxRQUFRLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFTO0lBQ2xDLFFBQVEsUUFBUSxDQUFDLEtBQUssR0FBRTtJQUN4QixRQUFRLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBQztJQUNwQyxRQUFRLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFO0lBQ3JELFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ25ELFlBQVksSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFDO0lBQ2pELFlBQVksUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFDO0lBQzFDLFlBQVksUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBQztJQUN6RSxZQUFZLFFBQVEsQ0FBQyxPQUFPLEdBQUU7SUFDOUIsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVc7SUFDaEMsUUFBUSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUU7SUFDdkIsWUFBWSxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUM7SUFDekMsWUFBWSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUM7SUFDMUQsWUFBWSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUNyQyxZQUFZLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBQzs7SUFFMUQsWUFBWSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFDO0lBQ2hELFlBQVksUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBQztJQUMvQyxTQUFTOztJQUVULFFBQVEsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQVk7SUFDakMsUUFBUSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUU7SUFDdkIsWUFB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SSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDM0YsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBQztJQUMvRCxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztJQUM3SCxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDNUQsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztJQUM5RSxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztJQUMvRCxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFFOztJQUVoQztJQUNBLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUU7SUFDNUIsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDekIsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBQztJQUN6SSxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBQztJQUNqRyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxDQUFDLEVBQUM7SUFDNUUsU0FBUyxNQUFNO0lBQ2YsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUM7SUFDdkgsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFDO0lBQ3JGLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLEVBQUM7SUFDdEUsU0FBUztJQUNULFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEdBQUU7O0lBRTlCLFFBQVEsT0FBTyxJQUFJO0lBQ25CLEtBQUs7SUFDTDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBLElBQUksWUFBWSxHQUFHOztJQUVuQixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFFO0lBQzlCLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUM7SUFDeEgsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBQztJQUNyRixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFDO0lBQzdDLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUM7SUFDL0QsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDO0lBQzNGLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUM7SUFDL0QsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7SUFDN0gsUUFBUSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFDO0lBQzVELFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUks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