Remove unused blade settings pages not linked from UI Convert remaining frontend pages to SPA actions Convert settings user_settings and general to SPA actions Convert settings profile pages to SPA actions Convert contacts and projects add/edit pages to SPA actions Convert clients add/edit page to SPA action with loading pattern Refactor component scoped IDs from $id to $sid Fix jqhtml comment syntax and implement universal error component system Update all application code to use new unified error system Remove all backwards compatibility - unified error system complete Phase 5: Remove old response classes Phase 3-4: Ajax response handler sends new format, old helpers deprecated Phase 2: Add client-side unified error foundation Phase 1: Add server-side unified error foundation Add unified Ajax error response system with constants 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
18087 lines
1.8 MiB
Executable File
18087 lines
1.8 MiB
Executable File
/* === storage/rsx-tmp/bundle_config_Dev_Bundle.js === */
|
|
window.rsxapp = window.rsxapp || {};
|
|
window.rsxapp.module_paths = {"bootstrap5_src":"rsx\/theme\/vendor\/bootstrap5\/scss"};
|
|
|
|
|
|
/* === storage/rsx-tmp/npm_import_declarations_95a6f602c98037611b640b0b5342830b.js === */
|
|
// NPM Import Declarations for App Bundle
|
|
// Auto-generated to provide NPM modules to app bundle scope
|
|
// Cache key: 95a6f602c98037611b640b0b5342830b
|
|
|
|
const jqhtml = window._rsx_npm.jqhtml;
|
|
if (!jqhtml) {
|
|
throw new Error(
|
|
'RSX Framework Error: NPM module "jqhtml" not found.\n' +
|
|
'Expected window._rsx_npm.jqhtml to be defined by the vendor bundle.'
|
|
);
|
|
}
|
|
|
|
const _Base_Jqhtml_Component = window._rsx_npm._Base_Jqhtml_Component;
|
|
if (!_Base_Jqhtml_Component) {
|
|
throw new Error(
|
|
'RSX Framework Error: NPM module "_Base_Jqhtml_Component" not found.\n' +
|
|
'Expected window._rsx_npm._Base_Jqhtml_Component to be defined by the vendor bundle.'
|
|
);
|
|
}
|
|
|
|
// Clean up NPM container to prevent console access
|
|
delete window._rsx_npm;
|
|
|
|
|
|
/* === app/RSpade/Core/Js/decorator.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Decorator function that marks a function as a decorator implementation.
|
|
*
|
|
* When a function has @decorator in its JSDoc comment, it whitelists that function
|
|
* to be used as a decorator on other methods throughout the codebase.
|
|
*
|
|
* The function itself performs no operation - it simply returns its input unchanged.
|
|
* Its purpose is purely as a marker for the manifest validation system.
|
|
*
|
|
* Usage:
|
|
* // /**
|
|
* // * My custom decorator implementation
|
|
* // * @decorator
|
|
* // *\/
|
|
* function my_custom_decorator(target, key, descriptor) {
|
|
* // Decorator implementation
|
|
* }
|
|
*
|
|
* This allows my_custom_decorator to be used as @my_custom_decorator on static methods.
|
|
*
|
|
* TODO: This is probably no longer necessary? maybe?
|
|
*/
|
|
function decorator(value) {
|
|
return value;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/browser.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Browser and DOM utility functions for the RSpade framework.
|
|
* These functions handle browser detection, viewport utilities, and DOM manipulation.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// BROWSER DETECTION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Detects if user is on a mobile device or using mobile viewport
|
|
* @returns {boolean} True if mobile device or viewport < 992px
|
|
* @todo Improve user agent detection for all mobile devices
|
|
*/
|
|
function is_mobile() {
|
|
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
|
return true;
|
|
} else if ($(window).width() < 992) {
|
|
// 992px = bootstrap 4 col-md-
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Detects if user is on desktop (not mobile)
|
|
* @returns {boolean} True if not mobile device/viewport
|
|
*/
|
|
function is_desktop() {
|
|
return !is_mobile();
|
|
}
|
|
|
|
/**
|
|
* Detects the user's operating system
|
|
* @returns {string} OS name: 'Mac OS', 'iPhone', 'iPad', 'Windows', 'Android-Phone', 'Android-Tablet', 'Linux', or 'Unknown'
|
|
*/
|
|
function get_os() {
|
|
let user_agent = window.navigator.userAgent,
|
|
platform = window.navigator.platform,
|
|
macos_platforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
|
|
windows_platforms = ['Win32', 'Win64', 'Windows', 'WinCE'],
|
|
ios_platforms = ['iPhone', 'iPad', 'iPod'],
|
|
os = null;
|
|
let is_mobile_device = is_mobile();
|
|
if (macos_platforms.indexOf(platform) !== -1) {
|
|
os = 'Mac OS';
|
|
} else if (ios_platforms.indexOf(platform) !== -1 && is_mobile_device) {
|
|
os = 'iPhone';
|
|
} else if (ios_platforms.indexOf(platform) !== -1 && !is_mobile_device) {
|
|
os = 'iPad';
|
|
} else if (windows_platforms.indexOf(platform) !== -1) {
|
|
os = 'Windows';
|
|
} else if (/Android/.test(user_agent) && is_mobile_device) {
|
|
os = 'Android-Phone';
|
|
} else if (/Android/.test(user_agent) && !is_mobile_device) {
|
|
os = 'Android-Tablet';
|
|
} else if (!os && /Linux/.test(platform)) {
|
|
os = 'Linux';
|
|
} else {
|
|
os = 'Unknown';
|
|
}
|
|
return os;
|
|
}
|
|
|
|
/**
|
|
* Detects if the user agent is a web crawler/bot
|
|
* @returns {boolean} True if user agent appears to be a bot/crawler
|
|
*/
|
|
function is_crawler() {
|
|
let user_agent = navigator.userAgent;
|
|
let bot_pattern = /bot|spider|crawl|slurp|archiver|ping|search|dig|tracker|monitor|snoopy|yahoo|baidu|msn|ask|teoma|axios/i;
|
|
return bot_pattern.test(user_agent);
|
|
}
|
|
|
|
// ============================================================================
|
|
// DOM SCROLLING UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Scrolls parent container to make target element visible if needed
|
|
* @param {string|HTMLElement|jQuery} target - Target element to scroll into view
|
|
*/
|
|
function scroll_into_view_if_needed(target) {
|
|
const $target = $(target);
|
|
|
|
// Find the closest parent with overflow-y: auto
|
|
const $parent = $target.parent();
|
|
|
|
// Calculate the absolute top position of the target
|
|
const target_top = $target.position().top + $parent.scrollTop();
|
|
const target_height = $target.outerHeight();
|
|
const parent_height = $parent.height();
|
|
const scroll_position = $parent.scrollTop();
|
|
|
|
// Check if the target is out of view
|
|
if (target_top < scroll_position || target_top + target_height > scroll_position + parent_height) {
|
|
Debugger.console_debug('UI', 'Scrolling!', target_top);
|
|
|
|
// Calculate the new scroll position to center the target
|
|
let new_scroll_position = target_top + target_height / 2 - parent_height / 2;
|
|
|
|
// Limit the scroll position between 0 and the maximum scrollable height
|
|
new_scroll_position = Math.max(0, Math.min(new_scroll_position, $parent[0].scrollHeight - parent_height));
|
|
|
|
// Scroll the parent to the new scroll position
|
|
$parent.scrollTop(new_scroll_position);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scrolls page to make target element visible if needed (with animation)
|
|
* @param {string|HTMLElement|jQuery} target - Target element to scroll into view
|
|
*/
|
|
function scroll_page_into_view_if_needed(target) {
|
|
const $target = $(target);
|
|
|
|
// Calculate the absolute top position of the target relative to the document
|
|
const target_top = $target.offset().top;
|
|
const target_height = $target.outerHeight();
|
|
const window_height = $(window).height();
|
|
const window_scroll_position = $(window).scrollTop();
|
|
|
|
// Check if the target is out of view
|
|
if (target_top < window_scroll_position || target_top + target_height > window_scroll_position + window_height) {
|
|
Debugger.console_debug('UI', 'Scrolling!', target_top);
|
|
|
|
// Calculate the new scroll position to center the target
|
|
const new_scroll_position = target_top + target_height / 2 - window_height / 2;
|
|
|
|
// Animate the scroll to the new position
|
|
$('html, body').animate({
|
|
scrollTop: new_scroll_position
|
|
}, 1000); // duration of the scroll animation in milliseconds
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// DOM UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Waits for all images on the page to load
|
|
* @param {Function} callback - Function to call when all images are loaded
|
|
*/
|
|
function wait_for_images(callback) {
|
|
const $images = $('img'); // Get all img tags
|
|
const total_images = $images.length;
|
|
let images_loaded = 0;
|
|
if (total_images === 0) {
|
|
callback(); // if there are no images, immediately call the callback
|
|
}
|
|
$images.each(function () {
|
|
const img = new Image();
|
|
img.onload = function () {
|
|
images_loaded++;
|
|
if (images_loaded === total_images) {
|
|
callback(); // call the callback when all images are loaded
|
|
}
|
|
};
|
|
img.onerror = function () {
|
|
images_loaded++;
|
|
if (images_loaded === total_images) {
|
|
callback(); // also call the callback if an image fails to load
|
|
}
|
|
};
|
|
img.src = this.src; // this triggers the loading
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a jQuery element containing a non-breaking space
|
|
* @returns {jQuery} jQuery span element with
|
|
*/
|
|
function $nbsp() {
|
|
return $('<span> </span>');
|
|
}
|
|
|
|
/**
|
|
* Escapes special characters in a jQuery selector
|
|
* @param {string} id - Element ID to escape
|
|
* @returns {string} jQuery selector string with escaped special characters
|
|
* @warning Not safe for security-critical operations
|
|
*/
|
|
function escape_jq_selector(id) {
|
|
return '#' + id.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1');
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/datetime.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Date and time utility functions for the RSpade framework.
|
|
* These functions handle date/time conversions and Unix timestamps.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// DATE/TIME UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Gets the current Unix timestamp (seconds since epoch)
|
|
* @returns {number} Current Unix timestamp in seconds
|
|
* @todo Calculate based on server time at page render
|
|
* @todo Move to a date library
|
|
*/
|
|
function unix_time() {
|
|
return Math.round(new Date().getTime() / 1000);
|
|
}
|
|
|
|
/**
|
|
* Converts a date string to Unix timestamp
|
|
* @param {string} str_date - Date string (Y-m-d H:i:s format)
|
|
* @returns {number} Unix timestamp in seconds
|
|
*/
|
|
function ymdhis_to_unix(str_date) {
|
|
const date = new Date(str_date);
|
|
return date.getTime() / 1000;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/error.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Error handling utility functions for the RSpade framework.
|
|
* These functions handle error creation and debugging utilities.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// ERROR HANDLING
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Creates an error object from a string
|
|
* @param {string|Object} str - Error message or existing error object
|
|
* @param {number} [error_code] - Optional error status code
|
|
* @returns {Object} Error object with error and status properties
|
|
*/
|
|
function error(str, error_code) {
|
|
if (typeof str.error != undef) {
|
|
return str;
|
|
} else {
|
|
if (typeof error_code == undef) {
|
|
return {
|
|
error: str,
|
|
status: null
|
|
};
|
|
} else {
|
|
return {
|
|
error: str,
|
|
status: error_code
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sanity check failure handler for JavaScript
|
|
*
|
|
* This function should be called when a sanity check fails - i.e., when the code
|
|
* encounters a condition that "shouldn't happen" if everything is working correctly.
|
|
*
|
|
* Unlike PHP, we can't stop JavaScript execution, but we can:
|
|
* 1. Throw an error that will be caught by error handlers
|
|
* 2. Log a clear error to the console
|
|
* 3. Provide stack trace for debugging
|
|
*
|
|
* Use this instead of silently returning or continuing when encountering unexpected conditions.
|
|
*
|
|
* @param {string} message Optional specific message about what shouldn't have happened
|
|
* @throws {Error} Always throws with location and context information
|
|
*/
|
|
function shouldnt_happen() {
|
|
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
const error = new Error();
|
|
const stack = error.stack || '';
|
|
const stackLines = stack.split('\n');
|
|
|
|
// Get the caller location (skip the Error line and this function)
|
|
let callerInfo = 'unknown location';
|
|
if (stackLines.length > 2) {
|
|
const callerLine = stackLines[2] || stackLines[1] || '';
|
|
// Extract file and line number from stack trace
|
|
const match = callerLine.match(/at\s+.*?\s+\((.*?):(\d+):(\d+)\)/) || callerLine.match(/at\s+(.*?):(\d+):(\d+)/);
|
|
if (match) {
|
|
callerInfo = `${match[1]}:${match[2]}`;
|
|
}
|
|
}
|
|
let errorMessage = `Fatal: shouldnt_happen() was called at ${callerInfo}\n`;
|
|
errorMessage += 'This indicates a sanity check failed - the code is not behaving as expected.\n';
|
|
if (message) {
|
|
errorMessage += `Details: ${message}\n`;
|
|
}
|
|
errorMessage += 'Please thoroughly review the related code to determine why this error occurred.';
|
|
|
|
// Log to console with full visibility
|
|
console.error('='.repeat(80));
|
|
console.error('SANITY CHECK FAILURE');
|
|
console.error('='.repeat(80));
|
|
console.error(errorMessage);
|
|
console.error('Stack trace:', stack);
|
|
console.error('='.repeat(80));
|
|
|
|
// Throw error to stop execution flow
|
|
const fatalError = new Error(errorMessage);
|
|
fatalError.name = 'SanityCheckFailure';
|
|
throw fatalError;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/hash.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Hashing and comparison utility functions for the RSpade framework.
|
|
* These functions handle object hashing and deep comparison.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// HASHING AND COMPARISON
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Generates a unique hash for any value (handles objects, arrays, circular references)
|
|
* @param {*} the_var - Value to hash
|
|
* @param {boolean} [calc_sha1=true] - If true, returns SHA1 hash; if false, returns JSON
|
|
* @param {Array<string>} [ignored_keys=null] - Keys to ignore when hashing objects
|
|
* @returns {string} SHA1 hash or JSON string of the value
|
|
*/
|
|
function hash(the_var) {
|
|
let calc_sha1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
let ignored_keys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
if (typeof the_var == undef) {
|
|
the_var = '__undefined__';
|
|
}
|
|
if (ignored_keys === null) {
|
|
ignored_keys = ['$'];
|
|
}
|
|
|
|
// Converts value to json, discarding circular references
|
|
let json_stringify_nocirc = function (value) {
|
|
const cache = [];
|
|
return JSON.stringify(value, function (key, v) {
|
|
if (typeof v === 'object' && typeof the_var._cache_key == 'function') {
|
|
return the_var._hash_key();
|
|
} else if (typeof v === 'object' && v !== null) {
|
|
if (cache.indexOf(v) !== -1) {
|
|
// Duplicate reference found, discard key
|
|
return;
|
|
}
|
|
cache.push(v);
|
|
}
|
|
return v;
|
|
});
|
|
};
|
|
|
|
// Turn every property and all its children into a single depth array of values that we can then
|
|
// sort and hash as a whole
|
|
let flat_var = {};
|
|
let _flatten = function (the_var, prefix) {
|
|
let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
// If a class object is provided, circular references can make the call stack recursive.
|
|
// For the purposes of how the hash function is called, this should be sufficient.
|
|
if (depth > 10) {
|
|
return;
|
|
}
|
|
|
|
// Does not account for dates i think...
|
|
|
|
if (is_object(the_var) && typeof the_var._cache_key == 'function') {
|
|
// Use _cache_key to hash components
|
|
flat_var[prefix] = the_var._hash_key();
|
|
} else if (is_object(the_var) && typeof Abstract !== 'undefined' && the_var instanceof Abstract) {
|
|
// Stringify all class objects
|
|
flat_var[prefix] = json_stringify_nocirc(the_var);
|
|
} else if (is_object(the_var)) {
|
|
// Iterate other objects
|
|
flat_var[prefix] = {};
|
|
for (let k in the_var) {
|
|
if (the_var.hasOwnProperty(k) && ignored_keys.indexOf(k) == -1) {
|
|
_flatten(the_var[k], prefix + '..' + k, depth + 1);
|
|
}
|
|
}
|
|
} else if (is_array(the_var)) {
|
|
// Iterate arrays
|
|
flat_var[prefix] = [];
|
|
let i = 0;
|
|
foreach(the_var, v => {
|
|
_flatten(v, prefix + '..' + i, depth + 1);
|
|
i++;
|
|
});
|
|
} else if (is_function(the_var)) {
|
|
// nothing
|
|
} else if (!is_numeric(the_var)) {
|
|
flat_var[prefix] = String(the_var);
|
|
} else {
|
|
flat_var[prefix] = the_var;
|
|
}
|
|
};
|
|
_flatten(the_var, '_');
|
|
let sorter = [];
|
|
foreach(flat_var, function (v, k) {
|
|
sorter.push([k, v]);
|
|
});
|
|
sorter.sort(function (a, b) {
|
|
return a[0] > b[0];
|
|
});
|
|
let json = JSON.stringify(sorter);
|
|
if (calc_sha1) {
|
|
let hashed = sha1.sha1(json);
|
|
return hashed;
|
|
} else {
|
|
return json;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deep comparison of two values (ignores property order and functions)
|
|
* @param {*} a - First value to compare
|
|
* @param {*} b - Second value to compare
|
|
* @returns {boolean} True if values are deeply equal
|
|
*/
|
|
function deep_equal(a, b) {
|
|
return hash(a, false) == hash(b, false);
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Mutex.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Mutex decorator for exclusive method execution
|
|
*
|
|
* Without arguments: Per-instance locking (each object has its own lock per method)
|
|
* @mutex
|
|
* async my_method() { ... }
|
|
*
|
|
* With ID argument: Global locking by ID (all instances share the lock)
|
|
* @mutex('operation_name')
|
|
* async my_method() { ... }
|
|
*
|
|
* @decorator
|
|
* @param {string} [global_id] - Optional global mutex ID for cross-instance locking
|
|
*/
|
|
function mutex(global_id) {
|
|
// Storage (using IIFEs to keep WeakMap/Map in closure scope)
|
|
const instance_mutexes = function () {
|
|
if (!mutex._instance_storage) {
|
|
mutex._instance_storage = new WeakMap();
|
|
}
|
|
return mutex._instance_storage;
|
|
}();
|
|
const global_mutexes = function () {
|
|
if (!mutex._global_storage) {
|
|
mutex._global_storage = new Map();
|
|
}
|
|
return mutex._global_storage;
|
|
}();
|
|
|
|
/**
|
|
* Get or create a mutex for a specific instance and method
|
|
*/
|
|
function get_instance_mutex(instance, method_name) {
|
|
let instance_locks = instance_mutexes.get(instance);
|
|
if (!instance_locks) {
|
|
instance_locks = new Map();
|
|
instance_mutexes.set(instance, instance_locks);
|
|
}
|
|
let lock_state = instance_locks.get(method_name);
|
|
if (!lock_state) {
|
|
lock_state = {
|
|
active: false,
|
|
queue: []
|
|
};
|
|
instance_locks.set(method_name, lock_state);
|
|
}
|
|
return lock_state;
|
|
}
|
|
|
|
/**
|
|
* Get or create a global mutex by ID
|
|
*/
|
|
function get_global_mutex(id) {
|
|
let lock_state = global_mutexes.get(id);
|
|
if (!lock_state) {
|
|
lock_state = {
|
|
active: false,
|
|
queue: []
|
|
};
|
|
global_mutexes.set(id, lock_state);
|
|
}
|
|
return lock_state;
|
|
}
|
|
|
|
/**
|
|
* Execute the next queued operation for a mutex
|
|
*/
|
|
function schedule_next(lock_state) {
|
|
if (lock_state.active || lock_state.queue.length === 0) {
|
|
return;
|
|
}
|
|
const {
|
|
fn,
|
|
resolve,
|
|
reject
|
|
} = lock_state.queue.shift();
|
|
lock_state.active = true;
|
|
Promise.resolve().then(fn).then(resolve, reject).finally(() => {
|
|
lock_state.active = false;
|
|
schedule_next(lock_state);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Acquire a mutex lock and execute callback
|
|
*/
|
|
function acquire_lock(lock_state, fn) {
|
|
return new Promise((resolve, reject) => {
|
|
lock_state.queue.push({
|
|
fn,
|
|
resolve,
|
|
reject
|
|
});
|
|
schedule_next(lock_state);
|
|
});
|
|
}
|
|
|
|
// If called with an ID argument: @mutex('id')
|
|
if (typeof global_id === 'string') {
|
|
return function (target, key, descriptor) {
|
|
const original_method = descriptor.value;
|
|
if (typeof original_method !== 'function') {
|
|
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
|
}
|
|
descriptor.value = function () {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
const lock_state = get_global_mutex(global_id);
|
|
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
|
};
|
|
return descriptor;
|
|
};
|
|
}
|
|
|
|
// If called without arguments: @mutex (target is the first argument)
|
|
const target = global_id; // In this case, first arg is target
|
|
const key = arguments[1];
|
|
const descriptor = arguments[2];
|
|
const original_method = descriptor.value;
|
|
if (typeof original_method !== 'function') {
|
|
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
|
}
|
|
descriptor.value = function () {
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
args[_key2] = arguments[_key2];
|
|
}
|
|
const lock_state = get_instance_mutex(this, key);
|
|
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
|
};
|
|
return descriptor;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/async.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Async utility functions for the RSpade framework.
|
|
* These functions handle asynchronous operations, delays, debouncing, and mutexes.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// ASYNC UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Pauses execution for specified milliseconds
|
|
* @param {number} [milliseconds=0] - Delay in milliseconds (0 uses requestAnimationFrame)
|
|
* @returns {Promise<void>} Promise that resolves after delay
|
|
* @example await sleep(1000); // Wait 1 second
|
|
*/
|
|
function sleep() {
|
|
let milliseconds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
return new Promise(resolve => {
|
|
if (milliseconds == 0 && requestAnimationFrame) {
|
|
requestAnimationFrame(resolve);
|
|
} else {
|
|
setTimeout(resolve, milliseconds);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a debounced function with exclusivity and promise fan-in
|
|
*
|
|
* This function, when invoked, immediately runs the callback exclusively.
|
|
* For subsequent invocations, it applies a delay before running the callback exclusively again.
|
|
* The delay starts after the current asynchronous operation resolves.
|
|
*
|
|
* If 'delay' is set to 0, the function will only prevent enqueueing multiple executions of the
|
|
* same method more than once, but will still run them immediately in an exclusive sequential manner.
|
|
*
|
|
* The most recent invocation of the function will be the parameters that get passed to the function
|
|
* when it invokes.
|
|
*
|
|
* The function returns a promise that resolves when the next exclusive execution completes.
|
|
*
|
|
* Usage as function:
|
|
* const debouncedFn = debounce(myFunction, 250);
|
|
*
|
|
* Usage as decorator:
|
|
* @debounce(250)
|
|
* myMethod() { ... }
|
|
*
|
|
* @param {function|number} callback_or_delay The callback function OR delay when used as decorator
|
|
* @param {number} delay The delay in milliseconds before subsequent invocations
|
|
* @param {boolean} immediate if true, the first time the action is called, the callback executes immediately
|
|
* @returns {function} A function that when invoked, runs the callback immediately and exclusively,
|
|
*
|
|
* @decorator
|
|
*/
|
|
function debounce(callback_or_delay, delay) {
|
|
let immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
// Decorator usage: @debounce(250) or @debounce(250, true)
|
|
// First argument is a number (the delay), returns decorator function
|
|
if (typeof callback_or_delay === 'number') {
|
|
const decorator_delay = callback_or_delay;
|
|
const decorator_immediate = delay || false;
|
|
|
|
// TC39 decorator form: receives (value, context)
|
|
return function (value, context) {
|
|
if (context.kind === 'method') {
|
|
return debounce_impl(value, decorator_delay, decorator_immediate);
|
|
}
|
|
};
|
|
}
|
|
|
|
// Function usage: debounce(fn, 250)
|
|
// First argument is a function (the callback)
|
|
const callback = callback_or_delay;
|
|
return debounce_impl(callback, delay, immediate);
|
|
}
|
|
|
|
/**
|
|
* Internal implementation of debounce logic
|
|
* @private
|
|
*/
|
|
function debounce_impl(callback, delay) {
|
|
let immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
let running = false;
|
|
let queued = false;
|
|
let last_end_time = 0; // timestamp of last completed run
|
|
let timer = null;
|
|
let next_args = [];
|
|
let next_context = null;
|
|
let resolve_queue = [];
|
|
let reject_queue = [];
|
|
const run_function = async () => {
|
|
const these_resolves = resolve_queue;
|
|
const these_rejects = reject_queue;
|
|
const args = next_args;
|
|
const context = next_context;
|
|
resolve_queue = [];
|
|
reject_queue = [];
|
|
next_args = [];
|
|
next_context = null;
|
|
queued = false;
|
|
running = true;
|
|
try {
|
|
const result = await callback.apply(context, args);
|
|
for (const resolve of these_resolves) resolve(result);
|
|
} catch (err) {
|
|
for (const reject of these_rejects) reject(err);
|
|
} finally {
|
|
running = false;
|
|
last_end_time = Date.now();
|
|
if (queued) {
|
|
clearTimeout(timer);
|
|
timer = setTimeout(run_function, Math.max(delay, 0));
|
|
} else {
|
|
timer = null;
|
|
}
|
|
}
|
|
};
|
|
return function () {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
next_args = args;
|
|
next_context = this;
|
|
return new Promise((resolve, reject) => {
|
|
resolve_queue.push(resolve);
|
|
reject_queue.push(reject);
|
|
|
|
// Nothing running and nothing scheduled
|
|
if (!running && !timer) {
|
|
const first_call = last_end_time === 0;
|
|
if (immediate && first_call) {
|
|
run_function();
|
|
return;
|
|
}
|
|
const since = first_call ? Infinity : Date.now() - last_end_time;
|
|
if (since >= delay) {
|
|
run_function();
|
|
} else {
|
|
const wait = Math.max(delay - since, 0);
|
|
clearTimeout(timer);
|
|
timer = setTimeout(run_function, wait);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// If we're already running or a timer exists, just mark queued.
|
|
// The finally{} of run_function handles scheduling after full delay.
|
|
queued = true;
|
|
});
|
|
};
|
|
}
|
|
|
|
// ============================================================================
|
|
// READ-WRITE LOCK FUNCTIONS - Delegated to ReadWriteLock class
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Acquire an exclusive write lock by name.
|
|
* Only one writer runs at a time; blocks readers until finished.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
function rwlock(name, cb) {
|
|
return ReadWriteLock.acquire(name, cb);
|
|
}
|
|
|
|
/**
|
|
* Acquire a shared read lock by name.
|
|
* Multiple readers run in parallel, but readers are blocked by queued/active writers.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
function rwlock_read(name, cb) {
|
|
return ReadWriteLock.acquire_read(name, cb);
|
|
}
|
|
|
|
/**
|
|
* Forcefully clear all locks and queues for a given name.
|
|
* @param {string} name
|
|
*/
|
|
function rwlock_force_unlock(name) {
|
|
ReadWriteLock.force_unlock(name);
|
|
}
|
|
|
|
/**
|
|
* Inspect lock state for debugging.
|
|
* @param {string} name
|
|
* @returns {{readers:number, writer_active:boolean, reader_q:number, writer_q:number}}
|
|
*/
|
|
function rwlock_pending(name) {
|
|
return ReadWriteLock.pending(name);
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/functions.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Core utility functions for the RSpade framework.
|
|
* These functions handle type checking, type conversion, string manipulation,
|
|
* and object/array utilities. They mirror functionality from PHP functions.
|
|
*
|
|
* Other utility functions are organized in:
|
|
* - async.js: Async utilities (sleep, debounce, mutex)
|
|
* - browser.js: Browser/DOM utilities (is_mobile, scroll functions)
|
|
* - datetime.js: Date/time utilities
|
|
* - hash.js: Hashing and comparison
|
|
* - error.js: Error handling
|
|
*/
|
|
|
|
// Todo: test that prod build identifies and removes uncalled functions from the final bundle.
|
|
|
|
// ============================================================================
|
|
// CONSTANTS AND HELPERS
|
|
// ============================================================================
|
|
|
|
// Define commonly used constants
|
|
const undef = 'undefined';
|
|
|
|
/**
|
|
* Iterates over arrays or objects with promise support
|
|
*
|
|
* Works with both synchronous and asynchronous callbacks. If the callback
|
|
* returns promises, they are executed in parallel and this function returns
|
|
* a promise that resolves when all parallel tasks complete.
|
|
*
|
|
* @param {Array|Object} obj - Collection to iterate
|
|
* @param {Function} callback - Function to call for each item (value, key) - can be async
|
|
* @returns {Promise|undefined} Promise if any callbacks return promises, undefined otherwise
|
|
*
|
|
* @example
|
|
* // Synchronous usage
|
|
* foreach([1,2,3], (val) => console.log(val));
|
|
*
|
|
* @example
|
|
* // Asynchronous usage - waits for all to complete
|
|
* await foreach([1,2,3], async (val) => {
|
|
* await fetch('/api/process/' + val);
|
|
* });
|
|
*/
|
|
function foreach(obj, callback) {
|
|
const results = [];
|
|
if (Array.isArray(obj)) {
|
|
obj.forEach((value, index) => {
|
|
results.push(callback(value, index));
|
|
});
|
|
} else if (obj && typeof obj === 'object') {
|
|
for (let key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
results.push(callback(obj[key], key));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Filter for promises
|
|
const promises = results.filter(result => result && typeof result.then === 'function');
|
|
|
|
// If there are any promises, return Promise.all to wait for all to complete
|
|
if (promises.length > 0) {
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
// No promises returned, so we're done
|
|
return undefined;
|
|
}
|
|
|
|
// ============================================================================
|
|
// TYPE CHECKING FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Checks if a value is numeric
|
|
* @param {*} n - Value to check
|
|
* @returns {boolean} True if the value is a finite number
|
|
*/
|
|
function is_numeric(n) {
|
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a string
|
|
* @param {*} s - Value to check
|
|
* @returns {boolean} True if the value is a string
|
|
*/
|
|
function is_string(s) {
|
|
return typeof s == 'string';
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an integer
|
|
* @param {*} n - Value to check
|
|
* @returns {boolean} True if the value is an integer
|
|
*/
|
|
function is_integer(n) {
|
|
return Number.isInteger(n);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a promise-like object
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value has a then method
|
|
*/
|
|
function is_promise(obj) {
|
|
return typeof obj == 'object' && typeof obj.then == 'function';
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an array
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value is an array
|
|
*/
|
|
function is_array(obj) {
|
|
return Array.isArray(obj);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an object (excludes null)
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value is an object and not null
|
|
*/
|
|
function is_object(obj) {
|
|
return typeof obj === 'object' && obj !== null;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a function
|
|
* @param {*} function_to_check - Value to check
|
|
* @returns {boolean} True if the value is a function
|
|
*/
|
|
function is_function(function_to_check) {
|
|
return function_to_check && {}.toString.call(function_to_check) === '[object Function]';
|
|
}
|
|
|
|
/**
|
|
* Checks if a string is a valid email address
|
|
* Uses a practical RFC 5322 compliant regex that matches 99.99% of real-world email addresses
|
|
* @param {string} email - Email address to validate
|
|
* @returns {boolean} True if the string is a valid email address
|
|
*/
|
|
function is_email(email) {
|
|
if (!is_string(email)) {
|
|
return false;
|
|
}
|
|
const regex = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
|
|
return regex.test(email);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is defined (not undefined)
|
|
* @param {*} value - Value to check
|
|
* @returns {boolean} True if value is not undefined
|
|
*/
|
|
function isset(value) {
|
|
return typeof value != undef;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is empty (null, undefined, 0, "", empty array/object)
|
|
* @param {*} object - Value to check
|
|
* @returns {boolean} True if the value is considered empty
|
|
*/
|
|
function empty(object) {
|
|
if (typeof object == undef) {
|
|
return true;
|
|
}
|
|
if (object === null) {
|
|
return true;
|
|
}
|
|
if (typeof object == 'string' && object == '') {
|
|
return true;
|
|
}
|
|
if (typeof object == 'number') {
|
|
return object == 0;
|
|
}
|
|
if (Array.isArray(object)) {
|
|
return !object.length;
|
|
}
|
|
if (typeof object == 'function') {
|
|
return false;
|
|
}
|
|
for (let key in object) {
|
|
if (object.hasOwnProperty(key)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ============================================================================
|
|
// TYPE CONVERSION FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Converts a value to a floating point number
|
|
* Returns 0 for null, undefined, NaN, or non-numeric values
|
|
* @param {*} val - Value to convert
|
|
* @returns {number} Floating point number
|
|
*/
|
|
function float(val) {
|
|
// Handle null, undefined, empty string
|
|
if (val === null || val === undefined || val === '') {
|
|
return 0.0;
|
|
}
|
|
|
|
// Try to parse the value
|
|
const parsed = parseFloat(val);
|
|
|
|
// Check for NaN and return 0 if parsing failed
|
|
return isNaN(parsed) ? 0.0 : parsed;
|
|
}
|
|
|
|
/**
|
|
* Converts a value to an integer
|
|
* Returns 0 for null, undefined, NaN, or non-numeric values
|
|
* @param {*} val - Value to convert
|
|
* @returns {number} Integer value
|
|
*/
|
|
function int(val) {
|
|
// Handle null, undefined, empty string
|
|
if (val === null || val === undefined || val === '') {
|
|
return 0;
|
|
}
|
|
|
|
// Try to parse the value
|
|
const parsed = parseInt(val, 10);
|
|
|
|
// Check for NaN and return 0 if parsing failed
|
|
return isNaN(parsed) ? 0 : parsed;
|
|
}
|
|
|
|
/**
|
|
* Converts a value to a string
|
|
* Returns empty string for null or undefined
|
|
* @param {*} val - Value to convert
|
|
* @returns {string} String representation
|
|
*/
|
|
function str(val) {
|
|
// Handle null and undefined specially
|
|
if (val === null || val === undefined) {
|
|
return '';
|
|
}
|
|
|
|
// Convert to string
|
|
return String(val);
|
|
}
|
|
|
|
/**
|
|
* Converts numeric strings to numbers, returns all other values unchanged
|
|
* Used when you need to ensure numeric types but don't want to force
|
|
* conversion of non-numeric values (which would become 0)
|
|
* @param {*} val - Value to convert
|
|
* @returns {*} Number if input was numeric string, otherwise unchanged
|
|
*/
|
|
function value_unless_numeric_string_then_numeric_value(val) {
|
|
// If it's already a number, return it
|
|
if (typeof val === 'number') {
|
|
return val;
|
|
}
|
|
|
|
// If it's a string and numeric, convert it
|
|
if (is_string(val) && is_numeric(val)) {
|
|
// Use parseFloat to handle both integers and floats
|
|
return parseFloat(val);
|
|
}
|
|
|
|
// Return everything else unchanged (null, objects, non-numeric strings, etc.)
|
|
return val;
|
|
}
|
|
|
|
// ============================================================================
|
|
// STRING MANIPULATION FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Escapes HTML special characters (uses Lodash escape)
|
|
* @param {string} str - String to escape
|
|
* @returns {string} HTML-escaped string
|
|
*/
|
|
function html(str) {
|
|
return _.escape(str);
|
|
}
|
|
|
|
/**
|
|
* Converts newlines to HTML line breaks
|
|
* @param {string} str - String to convert
|
|
* @returns {string} String with newlines replaced by <br />
|
|
*/
|
|
function nl2br(str) {
|
|
if (typeof str === undef || str === null) {
|
|
return '';
|
|
}
|
|
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br />$2');
|
|
}
|
|
|
|
/**
|
|
* Escapes HTML and converts newlines to <br />
|
|
* @param {string} str - String to process
|
|
* @returns {string} HTML-escaped string with line breaks
|
|
*/
|
|
function htmlbr(str) {
|
|
return nl2br(html(str));
|
|
}
|
|
|
|
/**
|
|
* URL-encodes a string
|
|
* @param {string} str - String to encode
|
|
* @returns {string} URL-encoded string
|
|
*/
|
|
function urlencode(str) {
|
|
return encodeURIComponent(str);
|
|
}
|
|
|
|
/**
|
|
* URL-decodes a string
|
|
* @param {string} str - String to decode
|
|
* @returns {string} URL-decoded string
|
|
*/
|
|
function urldecode(str) {
|
|
return decodeURIComponent(str);
|
|
}
|
|
|
|
/**
|
|
* JSON-encodes a value
|
|
* @param {*} value - Value to encode
|
|
* @returns {string} JSON string
|
|
*/
|
|
function json_encode(value) {
|
|
return JSON.stringify(value);
|
|
}
|
|
|
|
/**
|
|
* JSON-decodes a string
|
|
* @param {string} str - JSON string to decode
|
|
* @returns {*} Decoded value
|
|
*/
|
|
function json_decode(str) {
|
|
return JSON.parse(str);
|
|
}
|
|
|
|
/**
|
|
* Console debug output with channel filtering
|
|
* Alias for Debugger.console_debug
|
|
* @param {string} channel - Debug channel name
|
|
* @param {...*} values - Values to log
|
|
*/
|
|
function console_debug(channel) {
|
|
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
values[_key - 1] = arguments[_key];
|
|
}
|
|
Debugger.console_debug(channel, ...values);
|
|
}
|
|
|
|
/**
|
|
* Replaces all occurrences of a substring in a string
|
|
* @param {string} string - String to search in
|
|
* @param {string} search - Substring to find
|
|
* @param {string} replace - Replacement substring
|
|
* @returns {string} String with all occurrences replaced
|
|
*/
|
|
function replace_all(string, search, replace) {
|
|
if (!is_string(string)) {
|
|
string = string + '';
|
|
}
|
|
return string.split(search).join(replace);
|
|
}
|
|
|
|
/**
|
|
* Capitalizes the first letter of each word
|
|
* @param {string} input - String to capitalize
|
|
* @returns {string} String with first letter of each word capitalized
|
|
*/
|
|
function ucwords(input) {
|
|
return input.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
}
|
|
|
|
// ============================================================================
|
|
// OBJECT AND ARRAY UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Counts the number of properties in an object or elements in an array
|
|
* @param {Object|Array} o - Object or array to count
|
|
* @returns {number} Number of own properties/elements
|
|
*/
|
|
function count(o) {
|
|
let c = 0;
|
|
for (const k in o) {
|
|
if (o.hasOwnProperty(k)) {
|
|
++c;
|
|
}
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/**
|
|
* Creates a shallow clone of an object, array, or function
|
|
* @param {*} obj - Value to clone
|
|
* @returns {*} Cloned value
|
|
*/
|
|
function clone(obj) {
|
|
if (typeof Function.prototype.__clone == undef) {
|
|
Function.prototype.__clone = function () {
|
|
//https://stackoverflow.com/questions/1833588/javascript-clone-a-function
|
|
const that = this;
|
|
let temp = function cloned() {
|
|
return that.apply(this, arguments);
|
|
};
|
|
for (let key in this) {
|
|
if (this.hasOwnProperty(key)) {
|
|
temp[key] = this[key];
|
|
}
|
|
}
|
|
return temp;
|
|
};
|
|
}
|
|
if (typeof obj == 'function') {
|
|
return obj.__clone();
|
|
} else if (obj.constructor && obj.constructor == Array) {
|
|
return obj.slice(0);
|
|
} else {
|
|
// https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object/30042948#30042948
|
|
return Object.assign({}, obj);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the first non-null/undefined value from arguments
|
|
* @param {...*} arguments - Values to check
|
|
* @returns {*} First non-null/undefined value, or null if none found
|
|
*/
|
|
function coalesce() {
|
|
let args = Array.from(arguments);
|
|
let return_val = null;
|
|
args.forEach(function (arg) {
|
|
if (return_val === null && typeof arg != undef && arg !== null) {
|
|
return_val = arg;
|
|
}
|
|
});
|
|
return return_val;
|
|
}
|
|
|
|
/**
|
|
* Converts CSV string to array, trimming each element
|
|
* @param {string} str_csv - CSV string to convert
|
|
* @returns {Array<string>} Array of trimmed values
|
|
* @todo Handle quoted/escaped characters
|
|
*/
|
|
function csv_to_array_trim(str_csv) {
|
|
const parts = str_csv.split(',');
|
|
const ret = [];
|
|
foreach(parts, part => {
|
|
ret.push(part.trim());
|
|
});
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* === rsx/theme/quill/quill_cdn.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Quill Editor - Utility Functions
|
|
*
|
|
* Provides utility functions for working with Quill editor.
|
|
*/
|
|
|
|
/**
|
|
* Ensures Quill is loaded before executing callback
|
|
* @param {Function} callback - Function to call when Quill is ready
|
|
*/
|
|
function quill_ready(callback) {
|
|
if (typeof window.Quill !== 'undefined') {
|
|
callback();
|
|
} else {
|
|
setTimeout(() => quill_ready(callback), 50);
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Manifest.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Manifest - JavaScript class registry and metadata system
|
|
*
|
|
* This class maintains a registry of all JavaScript classes in the bundle,
|
|
* tracking their names and inheritance relationships. It provides utilities
|
|
* for working with class hierarchies and calling initialization methods.
|
|
*/
|
|
class Manifest {
|
|
/**
|
|
* Define classes in the manifest (framework internal)
|
|
* @param {Array} items - Array of class definitions [[Class, "ClassName", ParentClass, decorators], ...]
|
|
*/
|
|
static _define(items) {
|
|
// Initialize the classes object if not already defined
|
|
if (typeof Manifest._classes === 'undefined') {
|
|
Manifest._classes = {};
|
|
}
|
|
|
|
// Process each class definition
|
|
items.forEach(item => {
|
|
let class_object = item[0];
|
|
let class_name = item[1];
|
|
let class_extends = item[2] || null;
|
|
let decorators = item[3] || null;
|
|
|
|
// Store the class information (using object to avoid duplicates)
|
|
Manifest._classes[class_name] = {
|
|
class: class_object,
|
|
name: class_name,
|
|
extends: class_extends,
|
|
decorators: decorators // Store compact decorator data
|
|
};
|
|
|
|
// Add metadata to the class object itself
|
|
class_object._name = class_name;
|
|
class_object._extends = class_extends;
|
|
class_object._decorators = decorators;
|
|
});
|
|
|
|
// Build the subclass index after all classes are defined
|
|
Manifest._build_subclass_index();
|
|
}
|
|
|
|
/**
|
|
* Build an index of subclasses for efficient lookups
|
|
* This creates a mapping where each class name points to an array of all its subclasses
|
|
* @private
|
|
*/
|
|
static _build_subclass_index() {
|
|
// Initialize the subclass index
|
|
Manifest._subclass_index = {};
|
|
|
|
// Step through each class and walk up its parent chain
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
let current_class_name = class_name;
|
|
let current_classdata = classdata;
|
|
|
|
// Walk up the parent chain until we reach the root
|
|
while (current_classdata) {
|
|
const extends_name = current_classdata.extends;
|
|
if (extends_name) {
|
|
// Initialize the parent's subclass array if needed
|
|
if (!Manifest._subclass_index[extends_name]) {
|
|
Manifest._subclass_index[extends_name] = [];
|
|
}
|
|
|
|
// Add this class to its parent's subclass list
|
|
if (!Manifest._subclass_index[extends_name].includes(class_name)) {
|
|
Manifest._subclass_index[extends_name].push(class_name);
|
|
}
|
|
|
|
// Move up to the parent's metadata (if it exists in manifest)
|
|
if (Manifest._classes[extends_name]) {
|
|
current_classdata = Manifest._classes[extends_name];
|
|
} else {
|
|
// Parent not in manifest (e.g., native JavaScript class), stop here
|
|
current_classdata = null;
|
|
}
|
|
} else {
|
|
// No parent, we've reached the root
|
|
current_classdata = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all classes that extend a given base class
|
|
* @param {Class|string} base_class - The base class (object or name string) to check for
|
|
* @returns {Array} Array of objects with {class_name, class_object} for classes that extend the base class
|
|
*/
|
|
static get_extending(base_class) {
|
|
if (!Manifest._classes) {
|
|
return [];
|
|
}
|
|
|
|
// Convert string to class object if needed
|
|
let base_class_object = base_class;
|
|
if (typeof base_class === 'string') {
|
|
base_class_object = Manifest.get_class_by_name(base_class);
|
|
if (!base_class_object) {
|
|
throw new Error(`Base class not found: ${base_class}`);
|
|
}
|
|
}
|
|
const classes = [];
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
if (Manifest.js_is_subclass_of(classdata.class, base_class_object)) {
|
|
classes.push({
|
|
class_name: class_name,
|
|
class_object: classdata.class
|
|
});
|
|
}
|
|
}
|
|
|
|
// Sort alphabetically by class name to ensure deterministic behavior and prevent race condition bugs
|
|
classes.sort((a, b) => a.class_name.localeCompare(b.class_name));
|
|
return classes;
|
|
}
|
|
|
|
/**
|
|
* Check if a class is a subclass of another class
|
|
* Matches PHP Manifest::js_is_subclass_of() signature and behavior
|
|
* @param {Class|string} subclass - The child class (object or name) to check
|
|
* @param {Class|string} superclass - The parent class (object or name) to check against
|
|
* @returns {boolean} True if subclass extends superclass (directly or indirectly)
|
|
*/
|
|
static js_is_subclass_of(subclass, superclass) {
|
|
// Convert string names to class objects
|
|
let subclass_object = subclass;
|
|
if (typeof subclass === 'string') {
|
|
subclass_object = Manifest.get_class_by_name(subclass);
|
|
if (!subclass_object) {
|
|
// Can't resolve subclass - return false per spec
|
|
return false;
|
|
}
|
|
}
|
|
let superclass_object = superclass;
|
|
if (typeof superclass === 'string') {
|
|
superclass_object = Manifest.get_class_by_name(superclass);
|
|
if (!superclass_object) {
|
|
// Can't resolve superclass - fail loud per spec
|
|
throw new Error(`Superclass not found in manifest: ${superclass}`);
|
|
}
|
|
}
|
|
|
|
// Classes are not subclasses of themselves
|
|
if (subclass_object === superclass_object) {
|
|
return false;
|
|
}
|
|
|
|
// Walk up the inheritance chain
|
|
let current_class = subclass_object;
|
|
while (current_class) {
|
|
if (current_class === superclass_object) {
|
|
return true;
|
|
}
|
|
// Move up to parent class
|
|
if (current_class._extends) {
|
|
// _extends may be a string or class reference
|
|
if (typeof current_class._extends === 'string') {
|
|
current_class = Manifest.get_class_by_name(current_class._extends);
|
|
} else {
|
|
current_class = current_class._extends;
|
|
}
|
|
} else {
|
|
current_class = null;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get a class by its name
|
|
* @param {string} class_name - The name of the class
|
|
* @returns {Class|null} The class object or null if not found
|
|
*/
|
|
static get_class_by_name(class_name) {
|
|
if (!Manifest._classes || !Manifest._classes[class_name]) {
|
|
return null;
|
|
}
|
|
return Manifest._classes[class_name].class;
|
|
}
|
|
|
|
/**
|
|
* Get all registered classes
|
|
* @returns {Array} Array of objects with {class_name, class_object, extends}
|
|
*/
|
|
static get_all_classes() {
|
|
if (!Manifest._classes) {
|
|
return [];
|
|
}
|
|
const results = [];
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
results.push({
|
|
class_name: classdata.name,
|
|
class_object: classdata.class,
|
|
extends: classdata.extends
|
|
});
|
|
}
|
|
|
|
// Sort alphabetically by class name to ensure deterministic behavior and prevent race condition bugs
|
|
results.sort((a, b) => a.class_name.localeCompare(b.class_name));
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Get the build key from the application configuration
|
|
* @returns {string} The build key or "NOBUILD" if not available
|
|
*/
|
|
static build_key() {
|
|
if (window.rsxapp && window.rsxapp.build_key) {
|
|
return window.rsxapp.build_key;
|
|
}
|
|
return 'NOBUILD';
|
|
}
|
|
|
|
/**
|
|
* Get decorators for a specific class and method
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @param {string} method_name - The method name
|
|
* @returns {Array|null} Array of decorator objects or null if none found
|
|
*/
|
|
static get_decorators(class_name, method_name) {
|
|
// Convert class object to name if needed
|
|
if (typeof class_name !== 'string') {
|
|
class_name = class_name._name || class_name.name;
|
|
}
|
|
const class_info = Manifest._classes[class_name];
|
|
if (!class_info || !class_info.decorators || !class_info.decorators[method_name]) {
|
|
return null;
|
|
}
|
|
|
|
// Transform compact format to object format
|
|
return Manifest._transform_decorators(class_info.decorators[method_name]);
|
|
}
|
|
|
|
/**
|
|
* Get all methods with decorators for a class
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @returns {Object} Object with method names as keys and decorator arrays as values
|
|
*/
|
|
static get_all_decorators(class_name) {
|
|
// Convert class object to name if needed
|
|
if (typeof class_name !== 'string') {
|
|
class_name = class_name._name || class_name.name;
|
|
}
|
|
const class_info = Manifest._classes[class_name];
|
|
if (!class_info || !class_info.decorators) {
|
|
return {};
|
|
}
|
|
|
|
// Transform all decorators from compact to object format
|
|
const result = {};
|
|
for (let method_name in class_info.decorators) {
|
|
result[method_name] = Manifest._transform_decorators(class_info.decorators[method_name]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Transform compact decorator format to object format
|
|
* @param {Array} compact_decorators - Array of [name, [args]] tuples
|
|
* @returns {Array} Array of decorator objects with name and arguments properties
|
|
* @private
|
|
*/
|
|
static _transform_decorators(compact_decorators) {
|
|
if (!Array.isArray(compact_decorators)) {
|
|
return [];
|
|
}
|
|
return compact_decorators.map(decorator => {
|
|
if (Array.isArray(decorator) && decorator.length >= 2) {
|
|
return {
|
|
name: decorator[0],
|
|
arguments: decorator[1] || []
|
|
};
|
|
}
|
|
// Handle malformed decorator data
|
|
return {
|
|
name: 'unknown',
|
|
arguments: []
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check if a method has a specific decorator
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @param {string} method_name - The method name
|
|
* @param {string} decorator_name - The decorator name to check for
|
|
* @returns {boolean} True if the method has the decorator
|
|
*/
|
|
static has_decorator(class_name, method_name, decorator_name) {
|
|
const decorators = Manifest.get_decorators(class_name, method_name);
|
|
if (!decorators) {
|
|
return false;
|
|
}
|
|
return decorators.some(d => d.name === decorator_name);
|
|
}
|
|
|
|
/**
|
|
* Get all subclasses of a given class using the pre-built index
|
|
* This is the JavaScript equivalent of PHP's Manifest::js_get_subclasses_of()
|
|
* @param {Class|string} base_class - The base class (object or name string) to get subclasses of
|
|
* @returns {Array<Class>} Array of actual class objects that are subclasses of the base class
|
|
*/
|
|
static js_get_subclasses_of(base_class) {
|
|
// Initialize index if needed
|
|
if (!Manifest._subclass_index) {
|
|
Manifest._build_subclass_index();
|
|
}
|
|
|
|
// Convert class object to name if needed
|
|
let base_class_name = base_class;
|
|
if (typeof base_class !== 'string') {
|
|
base_class_name = base_class._name || base_class.name;
|
|
}
|
|
|
|
// Check if the base class exists
|
|
if (!Manifest._classes[base_class_name]) {
|
|
// Base class not in manifest - return empty array
|
|
return [];
|
|
}
|
|
|
|
// Get subclass names from the index
|
|
const subclass_names = Manifest._subclass_index[base_class_name] || [];
|
|
|
|
// Convert names to actual class objects
|
|
const subclass_objects = [];
|
|
for (let subclass_name of subclass_names) {
|
|
const classdata = Manifest._classes[subclass_name];
|
|
subclass_objects.push(classdata.class);
|
|
}
|
|
|
|
// Sort by class name for deterministic behavior
|
|
subclass_objects.sort((a, b) => {
|
|
const name_a = a._name || a.name;
|
|
const name_b = b._name || b.name;
|
|
return name_a.localeCompare(name_b);
|
|
});
|
|
return subclass_objects;
|
|
}
|
|
}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Behaviors.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Behaviors - Core Framework User Experience Enhancements
|
|
*
|
|
* This class provides automatic quality-of-life behaviors that improve the default
|
|
* browser experience for RSX applications. These behaviors are transparent to
|
|
* application developers and run automatically on framework initialization.
|
|
*
|
|
* These behaviors use jQuery event delegation to handle both existing and dynamically
|
|
* added content. They are implemented with low priority to allow application code to
|
|
* override default behaviors when needed.
|
|
*
|
|
* @internal Framework use only - not part of public API
|
|
*/
|
|
class Rsx_Behaviors {
|
|
static _on_framework_core_init() {
|
|
Rsx_Behaviors._init_ignore_invalid_anchor_links();
|
|
Rsx_Behaviors._trim_copied_text();
|
|
}
|
|
|
|
/**
|
|
* - Anchor link handling: Prevents broken "#" links from causing page jumps or URL changes
|
|
* - Ignores "#" (empty hash) to prevent scroll-to-top behavior
|
|
* - Ignores "#placeholder*" links used as route placeholders during development
|
|
* - Validates anchor targets exist before allowing navigation
|
|
* - Preserves normal anchor behavior when targets exist
|
|
*/
|
|
static _init_ignore_invalid_anchor_links() {
|
|
return; // disabled for now - make this into a configurable option
|
|
|
|
// Use event delegation on document to handle all current and future anchor clicks
|
|
// Use mousedown instead of click to run before most application handlers
|
|
$(document).on('mousedown', 'a[href^="#"]', function (e) {
|
|
const $link = $(this);
|
|
const href = $link.attr('href');
|
|
|
|
// Check if another handler has already prevented default
|
|
if (e.isDefaultPrevented()) {
|
|
return;
|
|
}
|
|
|
|
// Allow data-rsx-allow-hash attribute to bypass this behavior
|
|
if ($link.data('rsx-allow-hash')) {
|
|
return;
|
|
}
|
|
|
|
// Handle empty hash - prevent scroll to top
|
|
if (href === '#') {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
|
|
// Handle placeholder links used during development
|
|
if (href.startsWith('#placeholder')) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
|
|
// For other hash links, check if target exists
|
|
const targetId = href.substring(1);
|
|
if (targetId) {
|
|
// Check for element with matching ID or name attribute
|
|
const targetExists = document.getElementById(targetId) !== null || document.querySelector(`[name="${targetId}"]`) !== null;
|
|
if (!targetExists) {
|
|
// Target doesn't exist - prevent navigation
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
// Target exists - allow normal anchor behavior
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* - Copy text trimming: Automatically removes leading/trailing whitespace from copied text
|
|
* - Hold Shift to preserve whitespace
|
|
* - Skips trimming in code blocks, textareas, and contenteditable elements
|
|
*/
|
|
static _trim_copied_text() {
|
|
document.addEventListener('copy', function (event) {
|
|
// Don't trim if user is holding Shift (allows copying with whitespace if needed)
|
|
if (event.shiftKey) return;
|
|
let selection = window.getSelection();
|
|
let selected_text = selection.toString();
|
|
|
|
// Don't trim if selection is empty
|
|
if (!selected_text) return;
|
|
|
|
// Don't trim if copying from code blocks, textareas, or content-editable (preserve formatting)
|
|
let container = selection.getRangeAt(0).commonAncestorContainer;
|
|
if (container.nodeType === 3) container = container.parentNode; // Text node to element
|
|
if (container.closest('pre, code, .code-block, textarea, [contenteditable="true"]')) return;
|
|
let trimmed_text = selected_text.trim();
|
|
|
|
// Only modify if there's actually whitespace to trim
|
|
if (trimmed_text !== selected_text && trimmed_text.length > 0) {
|
|
event.preventDefault();
|
|
event.clipboardData.setData('text/plain', trimmed_text);
|
|
console.log('Copy: trimmed whitespace from selection');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Cache.js (babel) === */
|
|
"use strict";
|
|
|
|
// Simple key value cache. Can only store 5000 entries, will reset after 5000 entries.
|
|
|
|
// Todo: keep local cache concept the same, replace global cache concept with the nov 2019 version of
|
|
// session cache. Use a session key & build key to track cache keys so cached values only last until user logs out.
|
|
// review session code to ensure that session key *always* rotates on logout. Make session id a protected value.
|
|
class Rsx_Cache {
|
|
static on_core_define() {
|
|
Core_Cache._caches = {
|
|
global: {},
|
|
instance: {}
|
|
};
|
|
Core_Cache._caches_set = 0;
|
|
}
|
|
|
|
// Alias for get_instance
|
|
static get(key) {
|
|
return Rsx_Cache.get_instance(key);
|
|
}
|
|
|
|
// Returns from the pool of cached data for this 'instance'. An instance
|
|
// in this case is a virtual page load / navigation in the SPA. Call Main.lib.reset() to reset.
|
|
// Returns null on failure
|
|
static get_instance(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
if (typeof Core_Cache._caches.instance[key_encoded] != undef) {
|
|
return JSON.parse(Core_Cache._caches.instance[key_encoded]);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Returns null on failure
|
|
// Returns a cached value from global cache (unique to page load, survives reset())
|
|
static get_global(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
if (typeof Core_Cache._caches.global[key_encoded] != undef) {
|
|
return JSON.parse(Core_Cache._caches.global[key_encoded]);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Sets a value in instance and global cache (not shared between browser tabs)
|
|
static set(key, value) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return;
|
|
}
|
|
if (value === null) {
|
|
return;
|
|
}
|
|
if (value.length > 64 * 1024) {
|
|
Debugger.console_debug('CACHE', 'Warning - not caching large cache entry', key);
|
|
return;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
Core_Cache._caches.global[key_encoded] = JSON.stringify(value);
|
|
Core_Cache._caches.instance[key_encoded] = JSON.stringify(value);
|
|
|
|
// Debugger.console_debug("CACHE", "Set", key, value);
|
|
|
|
Core_Cache._caches_set++;
|
|
|
|
// Reset cache after 5000 items set
|
|
if (Core_Cache._caches_set > 5000) {
|
|
// Get an accurate count
|
|
Core_Cache._caches_set = count(Core_Cache._caches.global);
|
|
if (Core_Cache._caches_set > 5000) {
|
|
Core_Cache._caches = {
|
|
global: {},
|
|
instance: {}
|
|
};
|
|
Core_Cache._caches_set = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns null on failure
|
|
// Returns a cached value from session cache (shared between browser tabs)
|
|
static get_session(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
if (!Rsx_Cache._supportsStorage()) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
let rs = sessionStorage.getItem(key_encoded);
|
|
if (!empty(rs)) {
|
|
return JSON.parse(rs);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Sets a value in session cache (shared between browser tabs)
|
|
static set_session(key, value) {
|
|
let _tryagain = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
if (Main.debug('no_api_cache')) {
|
|
return;
|
|
}
|
|
if (value.length > 64 * 1024) {
|
|
Debugger.console_debug('CACHE', 'Warning - not caching large cache entry', key);
|
|
return;
|
|
}
|
|
if (!Rsx_Cache._supportsStorage()) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
try {
|
|
sessionStorage.removeItem(key_encoded);
|
|
sessionStorage.setItem(key_encoded, JSON.stringify(value));
|
|
} catch (e) {
|
|
if (Rsx_Cache._isOutOfSpace(e) && sessionStorage.length) {
|
|
sessionStorage.clear();
|
|
if (_tryagain) {
|
|
Core_Cache.set_session(key, value, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
static _reset() {
|
|
Core_Cache._caches.instance = {};
|
|
}
|
|
|
|
/**
|
|
* For given key of any type including an object, return a string representing
|
|
* the key that the cached value should be stored as in sessionstorage
|
|
*/
|
|
static _encodekey(key) {
|
|
const prefix = 'cache_';
|
|
|
|
// Session reimplement
|
|
// var prefix = "cache_" + Spa.session().user_id() + "_";
|
|
|
|
if (is_string(key) && key.length < 150 && key.indexOf(' ') == -1) {
|
|
return prefix + Manifest.build_key() + '_' + key;
|
|
} else {
|
|
return prefix + hash([Manifest.build_key(), key]);
|
|
}
|
|
}
|
|
|
|
// Determines if sessionStorage is supported in the browser;
|
|
// result is cached for better performance instead of being run each time.
|
|
// Feature detection is based on how Modernizr does it;
|
|
// it's not straightforward due to FF4 issues.
|
|
// It's not run at parse-time as it takes 200ms in Android.
|
|
// Code from https://github.com/pamelafox/lscache/blob/master/lscache.js, Apache License Pamelafox
|
|
static _supportsStorage() {
|
|
let key = '__cachetest__';
|
|
let value = key;
|
|
if (Rsx_Cache.__supportsStorage !== undefined) {
|
|
return Rsx_Cache.__supportsStorage;
|
|
}
|
|
|
|
// some browsers will throw an error if you try to access local storage (e.g. brave browser)
|
|
// hence check is inside a try/catch
|
|
try {
|
|
if (!sessionStorage) {
|
|
return false;
|
|
}
|
|
} catch (ex) {
|
|
return false;
|
|
}
|
|
try {
|
|
sessionStorage.setItem(key, value);
|
|
sessionStorage.removeItem(key);
|
|
Rsx_Cache.__supportsStorage = true;
|
|
} catch (e) {
|
|
// If we hit the limit, and we don't have an empty sessionStorage then it means we have support
|
|
if (Rsx_Cache._isOutOfSpace(e) && sessionStorage.length) {
|
|
Rsx_Cache.__supportsStorage = true; // just maxed it out and even the set test failed.
|
|
} else {
|
|
Rsx_Cache.__supportsStorage = false;
|
|
}
|
|
}
|
|
return Rsx_Cache.__supportsStorage;
|
|
}
|
|
|
|
// Check to set if the error is us dealing with being out of space
|
|
static _isOutOfSpace(e) {
|
|
return e && (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED' || e.name === 'QuotaExceededError');
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Init.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Init - Core framework initialization and environment validation
|
|
*/
|
|
class Rsx_Init {
|
|
/**
|
|
* Called via Rsx._rsx_core_boot
|
|
* Initializes the core environment and runs basic sanity checks
|
|
*/
|
|
static _on_framework_core_init() {
|
|
if (!Rsx.is_prod()) {
|
|
Rsx_Init.__environment_checks();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Development environment checks to ensure proper configuration
|
|
*/
|
|
static __environment_checks() {
|
|
// Find all script tags in the DOM
|
|
const scripts = document.getElementsByTagName('script');
|
|
for (let i = 0; i < scripts.length; i++) {
|
|
const script = scripts[i];
|
|
|
|
// Skip inline scripts (no src attribute)
|
|
if (!script.src) {
|
|
continue;
|
|
}
|
|
|
|
// Check if script has defer attribute
|
|
if (!script.defer) {
|
|
const src = script.src || '(inline script)';
|
|
const reason = `All script tags used in an RSpade project must have defer attribute. Found script without defer: ${src}`;
|
|
|
|
// Stop framework boot with reason
|
|
Rsx._rsx_core_boot_stop(reason);
|
|
|
|
// Also log to console for visibility
|
|
console.error(`[RSX BOOT STOPPED] ${reason}`);
|
|
|
|
// Stop checking after first violation
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Js_Model.js (babel) === */
|
|
"use strict";
|
|
|
|
// @FILE-SUBCLASS-01-EXCEPTION
|
|
|
|
/**
|
|
* Base class for JavaScript ORM models
|
|
*
|
|
* Provides core functionality for fetching records from backend PHP models.
|
|
* All model stubs generated by the manifest extend this base class.
|
|
*
|
|
* Example usage:
|
|
* // Fetch single record
|
|
* const user = await User_Model.fetch(123);
|
|
*
|
|
* // Fetch multiple records
|
|
* const users = await User_Model.fetch([1, 2, 3]);
|
|
*
|
|
* // Create instance with data
|
|
* const user = new User_Model({id: 1, name: 'John'});
|
|
*
|
|
* @Instantiatable
|
|
*/
|
|
class Rsx_Js_Model {
|
|
/**
|
|
* Constructor - Initialize model instance with data
|
|
*
|
|
* @param {Object} data - Key-value pairs to populate the model
|
|
*/
|
|
constructor() {
|
|
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
|
|
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
|
|
// This provides typed model objects instead of plain JSON, with methods and type checking.
|
|
|
|
// This constructor filters out the __MODEL marker that was used to identify which class
|
|
// to instantiate, keeping only the actual data properties on the instance.
|
|
const {
|
|
__MODEL,
|
|
...modelData
|
|
} = data;
|
|
Object.assign(this, modelData);
|
|
}
|
|
|
|
/**
|
|
* Fetch record(s) from the backend model
|
|
*
|
|
* This method mirrors the PHP Model::fetch() functionality.
|
|
* The backend model must have a fetch() method with the
|
|
* #[Ajax_Endpoint_Model_Fetch] annotation to be callable.
|
|
*
|
|
* @param {number|Array} id - Single ID or array of IDs to fetch
|
|
* @returns {Promise} - Single model instance, array of instances, or false
|
|
*/
|
|
static async fetch(id) {
|
|
const CurrentClass = this;
|
|
// Get the model class name from the current class
|
|
const modelName = CurrentClass.name;
|
|
const response = await $.ajax({
|
|
url: `/_fetch/${modelName}`,
|
|
method: 'POST',
|
|
data: {
|
|
id: id
|
|
},
|
|
dataType: 'json'
|
|
});
|
|
|
|
// Handle response based on type
|
|
if (response === false) {
|
|
return false;
|
|
}
|
|
|
|
// Use _instantiate_models_recursive to handle ORM instantiation
|
|
// This will automatically detect __MODEL properties and create appropriate instances
|
|
return Rsx_Js_Model._instantiate_models_recursive(response);
|
|
}
|
|
|
|
/**
|
|
* Get the model class name
|
|
* Used internally for API calls
|
|
*
|
|
* @returns {string} The class name
|
|
*/
|
|
static getModelName() {
|
|
const CurrentClass = this;
|
|
return CurrentClass.name;
|
|
}
|
|
|
|
/**
|
|
* Refresh this instance with latest data from server
|
|
*
|
|
* @returns {Promise} Updated instance or false if not found
|
|
*/
|
|
async refresh() {
|
|
const that = this;
|
|
if (!that.id) {
|
|
shouldnt_happen('Cannot refresh model without id property');
|
|
}
|
|
const fresh = await that.constructor.fetch(that.id);
|
|
if (fresh === false) {
|
|
return false;
|
|
}
|
|
|
|
// Update this instance with fresh data
|
|
Object.assign(that, fresh);
|
|
return that;
|
|
}
|
|
|
|
/**
|
|
* Convert model instance to plain object
|
|
* Useful for serialization or sending to APIs
|
|
*
|
|
* @returns {Object} Plain object representation
|
|
*/
|
|
toObject() {
|
|
const that = this;
|
|
const obj = {};
|
|
for (const key in that) {
|
|
if (that.hasOwnProperty(key) && typeof that[key] !== 'function') {
|
|
obj[key] = that[key];
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* Convert model instance to JSON string
|
|
*
|
|
* @returns {string} JSON representation
|
|
*/
|
|
toJSON() {
|
|
const that = this;
|
|
return JSON.stringify(that.toObject());
|
|
}
|
|
|
|
/**
|
|
* Recursively instantiate ORM models in response data
|
|
*
|
|
* Looks for objects with __MODEL property and instantiates the appropriate
|
|
* JavaScript model class if it exists in the global scope.
|
|
*
|
|
* @param {*} data - The data to process (can be any type)
|
|
* @returns {*} The data with ORM objects instantiated
|
|
*/
|
|
static _instantiate_models_recursive(data) {
|
|
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
|
|
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
|
|
// This provides typed model objects instead of plain JSON, with methods and type checking.
|
|
|
|
// This recursive processor scans all API response data looking for __MODEL markers.
|
|
// When found, it attempts to instantiate the appropriate JavaScript model class,
|
|
// converting {__MODEL: "User_Model", id: 1, name: "John"} into new User_Model({...}).
|
|
// Works recursively through arrays and nested objects to handle complex data structures.
|
|
// Handle null/undefined
|
|
if (data === null || data === undefined) {
|
|
return data;
|
|
}
|
|
|
|
// Handle arrays - recursively process each element
|
|
if (Array.isArray(data)) {
|
|
return data.map(item => Rsx_Js_Model._instantiate_models_recursive(item));
|
|
}
|
|
|
|
// Handle objects
|
|
if (typeof data === 'object') {
|
|
// Check if this object has a __MODEL property
|
|
if (data.__MODEL && typeof data.__MODEL === 'string') {
|
|
// Try to find the model class in the global scope
|
|
const ModelClass = window[data.__MODEL];
|
|
|
|
// If the model class exists and extends Rsx_Js_Model, instantiate it
|
|
// Dynamic model resolution requires checking class existence - @JS-DEFENSIVE-01-EXCEPTION
|
|
if (ModelClass && ModelClass.prototype instanceof Rsx_Js_Model) {
|
|
return new ModelClass(data);
|
|
}
|
|
}
|
|
|
|
// Recursively process all object properties
|
|
const result = {};
|
|
for (const key in data) {
|
|
if (data.hasOwnProperty(key)) {
|
|
result[key] = Rsx_Js_Model._instantiate_models_recursive(data[key]);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Return primitive values as-is
|
|
return data;
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_View_Transitions.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* View_Transitions - Smooth page-to-page transitions using View Transitions API
|
|
*
|
|
* Enables cross-document view transitions so the browser doesn't paint the new page
|
|
* until it's ready, creating smooth animations between pages.
|
|
*
|
|
* Falls back gracefully if View Transitions API is not available.
|
|
*/
|
|
class Rsx_View_Transitions {
|
|
/**
|
|
* Called during framework core init phase
|
|
* Checks for View Transitions API support and enables if available
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Check if View Transitions API is supported
|
|
if (!document.startViewTransition) {
|
|
console_debug('VIEW_TRANSITIONS', 'View Transitions API not supported, skipping');
|
|
return;
|
|
}
|
|
|
|
// Enable cross-document view transitions via CSS
|
|
Rsx_View_Transitions._inject_transition_css();
|
|
}
|
|
|
|
/**
|
|
* Inject CSS to enable cross-document view transitions
|
|
*
|
|
* The @view-transition { navigation: auto; } rule tells the browser to:
|
|
* 1. Capture a snapshot of the current page before navigation
|
|
* 2. Fetch the new page
|
|
* 3. Wait until the new page is fully loaded and painted (document.ready)
|
|
* 4. Animate smoothly between the two states
|
|
*
|
|
* This prevents the white flash during navigation and creates app-like transitions.
|
|
*/
|
|
static _inject_transition_css() {
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@view-transition {
|
|
navigation: auto;
|
|
}
|
|
|
|
/* Disable animation - instant transition */
|
|
::view-transition-group(*),
|
|
::view-transition-old(*),
|
|
::view-transition-new(*) {
|
|
animation-duration: 0s;
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/ReadWriteLock.js (babel) === */
|
|
"use strict";
|
|
|
|
var _50ae609e_ReadWriteLock;
|
|
function _50ae609e_assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
/**
|
|
* ReadWriteLock implementation for RSpade framework
|
|
* Provides exclusive (write) and shared (read) locking mechanisms for asynchronous operations
|
|
*/
|
|
class ReadWriteLock {
|
|
/**
|
|
* Acquire an exclusive mutex lock by name.
|
|
* Only one writer runs at a time; blocks readers until finished.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
static acquire(name, cb) {
|
|
return new Promise((resolve, reject) => {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
s.writer_q.push({
|
|
cb,
|
|
resolve,
|
|
reject
|
|
});
|
|
_50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Acquire a shared read lock by name.
|
|
* Multiple readers can run in parallel; blocks when writer is active.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
static acquire_read(name, cb) {
|
|
return new Promise((resolve, reject) => {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
if (s.writer_active || s.writer_q.length > 0) {
|
|
s.reader_q.push({
|
|
cb,
|
|
resolve,
|
|
reject
|
|
});
|
|
return _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
}
|
|
s.readers += 1;
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.readers -= 1;
|
|
if (s.readers === 0) _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Force-unlock a mutex (use with caution).
|
|
* Completely removes the lock state, potentially breaking waiting operations.
|
|
* @param {string} name
|
|
*/
|
|
static force_unlock(name) {
|
|
_50ae609e_assertClassBrand(ReadWriteLock, this, _locks)._.delete(name);
|
|
}
|
|
|
|
/**
|
|
* Get information about pending operations on a mutex.
|
|
* @param {string} name
|
|
* @returns {{readers: number, writer_active: boolean, reader_q: number, writer_q: number}}
|
|
*/
|
|
static pending(name) {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _locks)._.get(name);
|
|
if (!s) return {
|
|
readers: 0,
|
|
writer_active: false,
|
|
reader_q: 0,
|
|
writer_q: 0
|
|
};
|
|
return {
|
|
readers: s.readers,
|
|
writer_active: s.writer_active,
|
|
reader_q: s.reader_q.length,
|
|
writer_q: s.writer_q.length
|
|
};
|
|
}
|
|
}
|
|
_50ae609e_ReadWriteLock = ReadWriteLock;
|
|
/**
|
|
* Get or create a lock object for a given name
|
|
* @private
|
|
*/
|
|
function _50ae609e_get_lock(name) {
|
|
let s = _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _locks)._.get(name);
|
|
if (!s) {
|
|
s = {
|
|
readers: 0,
|
|
writer_active: false,
|
|
reader_q: [],
|
|
writer_q: []
|
|
};
|
|
_50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _locks)._.set(name, s);
|
|
}
|
|
return s;
|
|
}
|
|
/**
|
|
* Schedule the next operation for a lock
|
|
* @private
|
|
*/
|
|
function _50ae609e_schedule(name) {
|
|
const s = _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
if (s.writer_active || s.readers > 0) return;
|
|
|
|
// run one writer if queued
|
|
if (s.writer_q.length > 0) {
|
|
const {
|
|
cb,
|
|
resolve,
|
|
reject
|
|
} = s.writer_q.shift();
|
|
s.writer_active = true;
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.writer_active = false;
|
|
_50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// otherwise run all queued readers in parallel
|
|
if (s.reader_q.length > 0) {
|
|
const batch = s.reader_q.splice(0);
|
|
s.readers += batch.length;
|
|
for (const {
|
|
cb,
|
|
resolve,
|
|
reject
|
|
} of batch) {
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.readers -= 1;
|
|
if (s.readers === 0) _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
var _locks = {
|
|
_: new Map()
|
|
};
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Form_Utils.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form utilities for validation and error handling
|
|
*/
|
|
class Form_Utils {
|
|
/**
|
|
* Framework initialization hook to register jQuery plugin
|
|
* Creates $.fn.ajax_submit() for form elements
|
|
* @private
|
|
*/
|
|
static _on_framework_core_define() {
|
|
let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
$.fn.ajax_submit = function () {
|
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
const $element = $(this);
|
|
if (!$element.is('form')) {
|
|
throw new Error('ajax_submit() can only be called on form elements');
|
|
}
|
|
const url = $element.attr('action');
|
|
if (!url) {
|
|
throw new Error('Form must have an action attribute');
|
|
}
|
|
const {
|
|
controller,
|
|
action
|
|
} = Ajax.ajax_url_to_controller_action(url);
|
|
return Form_Utils.ajax_submit($element, controller, action, options);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Shows form validation errors
|
|
*
|
|
* REQUIRED HTML STRUCTURE:
|
|
* For inline field errors to display properly, form fields must follow this structure:
|
|
*
|
|
* <div class="form-group">
|
|
* <label class="form-label" for="field-name">Field Label</label>
|
|
* <input class="form-control" id="field-name" name="field-name" type="text">
|
|
* </div>
|
|
*
|
|
* Key requirements:
|
|
* - Wrap each field in a container with class "form-group" (or "form-check" / "input-group")
|
|
* - Input must have a "name" attribute matching the error key
|
|
* - Use "form-control" class on inputs for Bootstrap 5 styling
|
|
*
|
|
* Accepts three formats:
|
|
* - String: Single error shown as alert
|
|
* - Array of strings: Multiple errors shown as bulleted alert
|
|
* - Object: Field names mapped to errors, shown inline (unmatched shown as alert)
|
|
*
|
|
* @param {string} parent_selector - jQuery selector for parent element
|
|
* @param {string|Object|Array} errors - Error messages to display
|
|
* @returns {Promise} Promise that resolves when all animations complete
|
|
*/
|
|
static apply_form_errors(parent_selector, errors) {
|
|
console.error(errors);
|
|
const $parent = $(parent_selector);
|
|
|
|
// Reset the form errors before applying new ones
|
|
Form_Utils.reset_form_errors(parent_selector);
|
|
|
|
// Normalize input to standard format
|
|
const normalized = Form_Utils._normalize_errors(errors);
|
|
return new Promise(resolve => {
|
|
let animations = [];
|
|
if (normalized.type === 'string') {
|
|
// Single error message
|
|
animations = Form_Utils._apply_general_errors($parent, normalized.data);
|
|
} else if (normalized.type === 'array') {
|
|
// Array of error messages
|
|
const deduplicated = Form_Utils._deduplicate_errors(normalized.data);
|
|
animations = Form_Utils._apply_general_errors($parent, deduplicated);
|
|
} else if (normalized.type === 'fields') {
|
|
// Field-specific errors
|
|
const result = Form_Utils._apply_field_errors($parent, normalized.data);
|
|
animations = result.animations;
|
|
|
|
// Count matched fields
|
|
const matched_count = Object.keys(normalized.data).length - Object.keys(result.unmatched).length;
|
|
const unmatched_deduplicated = Form_Utils._deduplicate_errors(result.unmatched);
|
|
const unmatched_count = Object.keys(unmatched_deduplicated).length;
|
|
|
|
// Show summary alert if there are any field errors (matched or unmatched)
|
|
if (matched_count > 0 || unmatched_count > 0) {
|
|
// Build summary message
|
|
let summary_msg = '';
|
|
if (matched_count > 0) {
|
|
summary_msg = matched_count === 1 ? 'Please correct the error highlighted below.' : 'Please correct the errors highlighted below.';
|
|
}
|
|
|
|
// If there are unmatched errors, add them as a bulleted list
|
|
if (unmatched_count > 0) {
|
|
const summary_animations = Form_Utils._apply_combined_error($parent, summary_msg, unmatched_deduplicated);
|
|
animations.push(...summary_animations);
|
|
} else {
|
|
// Just the summary message, no unmatched errors
|
|
const summary_animations = Form_Utils._apply_general_errors($parent, summary_msg);
|
|
animations.push(...summary_animations);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Resolve the promise once all animations are complete
|
|
Promise.all(animations).then(() => {
|
|
// Scroll to error container if it exists
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
if ($error_container.length > 0) {
|
|
const container_top = $error_container.offset().top;
|
|
|
|
// Calculate fixed header offset
|
|
const fixed_header_height = Form_Utils._get_fixed_header_height();
|
|
|
|
// Scroll to position error container 20px below any fixed headers
|
|
const target_scroll = container_top - fixed_header_height - 20;
|
|
$('html, body').animate({
|
|
scrollTop: target_scroll
|
|
}, 500);
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clears form validation errors and resets all form values to defaults
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
*/
|
|
static reset(form_selector) {
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
Form_Utils.reset_form_errors(form_selector);
|
|
$form.trigger('reset');
|
|
}
|
|
|
|
/**
|
|
* Serializes form data into key-value object
|
|
* Returns all input elements with name attributes as object properties
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
* @returns {Object} Form data as key-value pairs
|
|
*/
|
|
static serialize(form_selector) {
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
const data = {};
|
|
$form.serializeArray().forEach(item => {
|
|
data[item.name] = item.value;
|
|
});
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Submits form to RSX controller action via AJAX
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
* @param {string} controller - Controller class name (e.g., 'User_Controller')
|
|
* @param {string} action - Action method name (e.g., 'save_profile')
|
|
* @param {Object} options - Optional configuration {on_success: fn, on_error: fn}
|
|
* @returns {Promise} Promise that resolves with response data
|
|
*/
|
|
static async ajax_submit(form_selector, controller, action) {
|
|
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
const form_data = Form_Utils.serialize($form);
|
|
Form_Utils.reset_form_errors(form_selector);
|
|
try {
|
|
const response = await Ajax.call(controller, action, form_data);
|
|
if (options.on_success) {
|
|
options.on_success(response);
|
|
}
|
|
return response;
|
|
} catch (error) {
|
|
if (error.type === 'form_error' && error.details) {
|
|
await Form_Utils.apply_form_errors(form_selector, error.details);
|
|
} else {
|
|
await Form_Utils.apply_form_errors(form_selector, error.message || 'An error occurred');
|
|
}
|
|
if (options.on_error) {
|
|
options.on_error(error);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes form validation errors
|
|
* @param {string} parent_selector - jQuery selector for parent element
|
|
*/
|
|
static reset_form_errors(parent_selector) {
|
|
const $parent = $(parent_selector);
|
|
|
|
// Remove flash messages
|
|
$('.flash-messages').remove();
|
|
|
|
// Remove alert-danger messages
|
|
$parent.find('.alert-danger').remove();
|
|
|
|
// Remove validation error classes and text from form elements
|
|
$parent.find('.is-invalid').removeClass('is-invalid');
|
|
$parent.find('.invalid-feedback').remove();
|
|
}
|
|
|
|
// ------------------------
|
|
|
|
/**
|
|
* Normalizes error input into standard formats
|
|
* @param {string|Object|Array} errors - Raw error input
|
|
* @returns {Object} Normalized errors as {type: 'string'|'array'|'fields', data: ...}
|
|
* @private
|
|
*/
|
|
static _normalize_errors(errors) {
|
|
// Handle null/undefined
|
|
if (!errors) {
|
|
return {
|
|
type: 'string',
|
|
data: 'An error has occurred'
|
|
};
|
|
}
|
|
|
|
// Handle string
|
|
if (typeof errors === 'string') {
|
|
return {
|
|
type: 'string',
|
|
data: errors
|
|
};
|
|
}
|
|
|
|
// Handle array
|
|
if (Array.isArray(errors)) {
|
|
// Array of strings - general errors
|
|
if (errors.every(e => typeof e === 'string')) {
|
|
return {
|
|
type: 'array',
|
|
data: errors
|
|
};
|
|
}
|
|
// Array with object as first element - extract it
|
|
if (errors.length > 0 && typeof errors[0] === 'object') {
|
|
return Form_Utils._normalize_errors(errors[0]);
|
|
}
|
|
// Empty or mixed array
|
|
return {
|
|
type: 'array',
|
|
data: []
|
|
};
|
|
}
|
|
|
|
// Handle object - check for Laravel response wrapper
|
|
if (typeof errors === 'object') {
|
|
// Unwrap {errors: {...}} or {error: {...}}
|
|
const unwrapped = errors.errors || errors.error;
|
|
if (unwrapped) {
|
|
return Form_Utils._normalize_errors(unwrapped);
|
|
}
|
|
|
|
// Convert Laravel validator format {field: [msg1, msg2]} to {field: msg1}
|
|
const normalized = {};
|
|
for (const field in errors) {
|
|
if (errors.hasOwnProperty(field)) {
|
|
const value = errors[field];
|
|
if (Array.isArray(value) && value.length > 0) {
|
|
normalized[field] = value[0];
|
|
} else if (typeof value === 'string') {
|
|
normalized[field] = value;
|
|
} else {
|
|
normalized[field] = String(value);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
type: 'fields',
|
|
data: normalized
|
|
};
|
|
}
|
|
|
|
// Final catch-all*
|
|
return {
|
|
type: 'string',
|
|
data: String(errors)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Removes duplicate error messages from array or object values
|
|
* @param {Array|Object} errors - Errors to deduplicate
|
|
* @returns {Array|Object} Deduplicated errors
|
|
* @private
|
|
*/
|
|
static _deduplicate_errors(errors) {
|
|
if (Array.isArray(errors)) {
|
|
return [...new Set(errors)];
|
|
}
|
|
if (typeof errors === 'object') {
|
|
const seen = new Set();
|
|
const result = {};
|
|
for (const key in errors) {
|
|
const value = errors[key];
|
|
if (!seen.has(value)) {
|
|
seen.add(value);
|
|
result[key] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
return errors;
|
|
}
|
|
|
|
/**
|
|
* Applies field-specific validation errors to form inputs
|
|
* @param {jQuery} $parent - Parent element containing form
|
|
* @param {Object} field_errors - Object mapping field names to error messages
|
|
* @returns {Object} Object containing {animations: Array, unmatched: Object}
|
|
* @private
|
|
*/
|
|
static _apply_field_errors($parent, field_errors) {
|
|
const animations = [];
|
|
const unmatched = {};
|
|
for (const field_name in field_errors) {
|
|
const error_message = field_errors[field_name];
|
|
const $input = $parent.find(`[name="${field_name}"]`);
|
|
if (!$input.length) {
|
|
unmatched[field_name] = error_message;
|
|
continue;
|
|
}
|
|
const $error = $('<div class="invalid-feedback"></div>').html(error_message);
|
|
const $target = $input.closest('.form-group, .form-check, .input-group');
|
|
if (!$target.length) {
|
|
unmatched[field_name] = error_message;
|
|
continue;
|
|
}
|
|
$input.addClass('is-invalid');
|
|
$error.appendTo($target);
|
|
animations.push($error.hide().fadeIn(300).promise());
|
|
}
|
|
return {
|
|
animations,
|
|
unmatched
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Applies combined error message with summary and unmatched field errors
|
|
* @param {jQuery} $parent - Parent element containing form
|
|
* @param {string} summary_msg - Summary message (e.g., "Please correct the errors below")
|
|
* @param {Object} unmatched_errors - Object of field errors that couldn't be matched to fields
|
|
* @returns {Array} Array of animation promises
|
|
* @private
|
|
*/
|
|
static _apply_combined_error($parent, summary_msg, unmatched_errors) {
|
|
const animations = [];
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
const $target = $error_container.length > 0 ? $error_container : $parent;
|
|
|
|
// Create alert with summary message and bulleted list of unmatched errors
|
|
const $alert = $('<div class="alert alert-danger" role="alert"></div>');
|
|
|
|
// Add summary message if provided
|
|
if (summary_msg) {
|
|
$('<p class="mb-2"></p>').text(summary_msg).appendTo($alert);
|
|
}
|
|
|
|
// Add unmatched errors as bulleted list
|
|
if (Object.keys(unmatched_errors).length > 0) {
|
|
const $list = $('<ul class="mb-0"></ul>');
|
|
for (const field_name in unmatched_errors) {
|
|
const error_msg = unmatched_errors[field_name];
|
|
$('<li></li>').html(error_msg).appendTo($list);
|
|
}
|
|
$list.appendTo($alert);
|
|
}
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
return animations;
|
|
}
|
|
|
|
/**
|
|
* Applies general error messages as alert box
|
|
* @param {jQuery} $parent - Parent element to prepend alert to
|
|
* @param {string|Array} messages - Error message(s) to display
|
|
* @returns {Array} Array of animation promises
|
|
* @private
|
|
*/
|
|
static _apply_general_errors($parent, messages) {
|
|
const animations = [];
|
|
|
|
// Look for a specific error container div (e.g., in Rsx_Form component)
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
const $target = $error_container.length > 0 ? $error_container : $parent;
|
|
if (typeof messages === 'string') {
|
|
// Single error - simple alert without list
|
|
const $alert = $('<div class="alert alert-danger" role="alert"></div>').text(messages);
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
} else if (Array.isArray(messages) && messages.length > 0) {
|
|
// Multiple errors - bulleted list
|
|
const $alert = $('<div class="alert alert-danger" role="alert"><ul class="mb-0"></ul></div>');
|
|
const $list = $alert.find('ul');
|
|
messages.forEach(msg => {
|
|
const text = (msg + '').trim() || 'An error has occurred';
|
|
$('<li></li>').html(text).appendTo($list);
|
|
});
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
} else if (typeof messages === 'object' && !Array.isArray(messages)) {
|
|
// Object of unmatched field errors - convert to array
|
|
const error_list = Object.values(messages).map(v => String(v).trim()).filter(v => v);
|
|
if (error_list.length > 0) {
|
|
return Form_Utils._apply_general_errors($parent, error_list);
|
|
}
|
|
}
|
|
return animations;
|
|
}
|
|
|
|
/**
|
|
* Calculates the total height of fixed/sticky headers at the top of the page
|
|
* @returns {number} Total height in pixels of fixed top elements
|
|
* @private
|
|
*/
|
|
static _get_fixed_header_height() {
|
|
let total_height = 0;
|
|
|
|
// Find all fixed or sticky positioned elements
|
|
$('*').each(function () {
|
|
const $el = $(this);
|
|
const position = $el.css('position');
|
|
|
|
// Only check fixed or sticky elements
|
|
if (position !== 'fixed' && position !== 'sticky') {
|
|
return;
|
|
}
|
|
|
|
// Check if element is positioned at or near the top
|
|
const top = parseInt($el.css('top')) || 0;
|
|
if (top > 50) {
|
|
return; // Not a top header
|
|
}
|
|
|
|
// Check if element is visible
|
|
if (!$el.is(':visible')) {
|
|
return;
|
|
}
|
|
|
|
// Check if element spans significant width (likely a header/navbar)
|
|
const width = $el.outerWidth();
|
|
const viewport_width = $(window).width();
|
|
if (width < viewport_width * 0.5) {
|
|
return; // Too narrow to be a header
|
|
}
|
|
|
|
// Add this element's height
|
|
total_height += $el.outerHeight();
|
|
});
|
|
return total_height;
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Debugger.js (babel) === */
|
|
"use strict";
|
|
|
|
function _27e0e986_defineProperty(e, r, t) { return (r = _27e0e986_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _27e0e986_toPropertyKey(t) { var i = _27e0e986_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _27e0e986_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
/**
|
|
* Debugger class for console_debug and browser error logging
|
|
* Handles batched submission to server when configured
|
|
*/
|
|
class Debugger {
|
|
/**
|
|
* Initialize framework error handling
|
|
* Called during framework initialization
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Check if browser error logging is enabled
|
|
if (window.rsxapp && window.rsxapp.log_browser_errors) {
|
|
// Register global error handler
|
|
window.addEventListener('error', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.message,
|
|
filename: event.filename,
|
|
lineno: event.lineno,
|
|
colno: event.colno,
|
|
stack: event.error ? event.error.stack : null,
|
|
type: 'error'
|
|
});
|
|
});
|
|
|
|
// Register unhandled promise rejection handler
|
|
window.addEventListener('unhandledrejection', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.reason ? event.reason.message || String(event.reason) : 'Unhandled promise rejection',
|
|
stack: event.reason && event.reason.stack ? event.reason.stack : null,
|
|
type: 'unhandledrejection'
|
|
});
|
|
});
|
|
}
|
|
|
|
// Register ui refresh handler
|
|
Rsx.on('refresh', Debugger.on_refresh);
|
|
}
|
|
|
|
// In dev mode, some ui elements can be automatically applied to assist with development
|
|
static on_refresh() {
|
|
if (!Rsx.is_prod()) {
|
|
// Add an underline 2 px blue to all a tags with href === "#" using jquery
|
|
// Todo: maybe this should be a configurable debug option?
|
|
// $('a[href="#"]').css({
|
|
// 'border-bottom': '2px solid blue',
|
|
// 'text-decoration': 'none'
|
|
// });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* JavaScript implementation of console_debug
|
|
* Mirrors PHP functionality with batching for Laravel log
|
|
*/
|
|
static console_debug(channel) {
|
|
// Check if console_debug is enabled
|
|
if (!window.rsxapp || !window.rsxapp.console_debug || !window.rsxapp.console_debug.enabled) {
|
|
return;
|
|
}
|
|
const config = window.rsxapp.console_debug;
|
|
|
|
// Normalize channel name
|
|
channel = String(channel).toUpperCase().replace(/[\[\]]/g, '');
|
|
|
|
// Apply filtering
|
|
if (config.filter_mode === 'specific') {
|
|
const specific = config.specific_channel;
|
|
if (specific) {
|
|
// Split comma-separated values and normalize
|
|
const channels = specific.split(',').map(c => c.trim().toUpperCase());
|
|
if (!channels.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
} else if (config.filter_mode === 'whitelist') {
|
|
const whitelist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (!whitelist.includes(channel)) {
|
|
return;
|
|
}
|
|
} else if (config.filter_mode === 'blacklist') {
|
|
const blacklist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (blacklist.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Prepare the message
|
|
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
values[_key - 1] = arguments[_key];
|
|
}
|
|
let message = {
|
|
channel: channel,
|
|
values: values,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Add location if configured
|
|
if (config.include_location || config.include_backtrace) {
|
|
const error = new Error();
|
|
const stack = error.stack || '';
|
|
const stackLines = stack.split('\n');
|
|
if (config.include_location && stackLines.length > 2) {
|
|
// Skip Error line and this function
|
|
const callerLine = stackLines[2] || '';
|
|
const match = callerLine.match(/at\s+.*?\s+\((.*?):(\d+):(\d+)\)/) || callerLine.match(/at\s+(.*?):(\d+):(\d+)/);
|
|
if (match) {
|
|
message.location = `${match[1]}:${match[2]}`;
|
|
}
|
|
}
|
|
if (config.include_backtrace) {
|
|
// Include first 5 stack frames, skipping this function
|
|
message.backtrace = stackLines.slice(2, 7).map(line => line.trim()).filter(line => line);
|
|
}
|
|
}
|
|
|
|
// Output to browser console if enabled
|
|
if (config.outputs && config.outputs.browser) {
|
|
const prefix = config.include_benchmark ? `[${Debugger._get_time_prefix()}] ` : '';
|
|
const channelPrefix = `[${channel}]`;
|
|
|
|
// Use appropriate console method based on channel
|
|
let consoleMethod = 'log';
|
|
if (channel.includes('ERROR')) consoleMethod = 'error';else if (channel.includes('WARN')) consoleMethod = 'warn';else if (channel.includes('INFO')) consoleMethod = 'info';
|
|
console[consoleMethod](prefix + channelPrefix, ...values);
|
|
}
|
|
|
|
// Batch for Laravel log if enabled
|
|
if (config.outputs && config.outputs.laravel_log) {
|
|
Debugger._batch_console_message(message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log an error to the server
|
|
* Used manually or by Ajax error handling
|
|
*/
|
|
static log_error(error) {
|
|
// Check if browser error logging is enabled
|
|
if (!window.rsxapp || !window.rsxapp.log_browser_errors) {
|
|
return;
|
|
}
|
|
|
|
// Normalize error format
|
|
let errorData = {};
|
|
if (typeof error === 'string') {
|
|
errorData.message = error;
|
|
errorData.type = 'manual';
|
|
} else if (error instanceof Error) {
|
|
errorData.message = error.message;
|
|
errorData.stack = error.stack;
|
|
errorData.type = 'exception';
|
|
} else if (error && typeof error === 'object') {
|
|
errorData = error;
|
|
if (!errorData.type) {
|
|
errorData.type = 'manual';
|
|
}
|
|
}
|
|
Debugger._handle_browser_error(errorData);
|
|
}
|
|
|
|
/**
|
|
* Internal: Handle browser errors with batching
|
|
*/
|
|
static _handle_browser_error(errorData) {
|
|
// Check limits
|
|
if (Debugger._error_count >= Debugger.MAX_ERRORS_PER_PAGE) {
|
|
return;
|
|
}
|
|
if (Debugger._error_batch_count >= Debugger.MAX_ERROR_BATCHES) {
|
|
return;
|
|
}
|
|
Debugger._error_count++;
|
|
|
|
// Add metadata
|
|
errorData.url = window.location.href;
|
|
errorData.userAgent = navigator.userAgent;
|
|
errorData.timestamp = new Date().toISOString();
|
|
|
|
// Add to batch
|
|
Debugger._error_batch.push(errorData);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._error_timer) {
|
|
clearTimeout(Debugger._error_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._error_timer = setTimeout(() => {
|
|
Debugger._flush_error_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Batch console_debug messages for Laravel log
|
|
*/
|
|
static _batch_console_message(message) {
|
|
Debugger._console_batch.push(message);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._console_timer) {
|
|
clearTimeout(Debugger._console_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._console_timer = setTimeout(() => {
|
|
Debugger._flush_console_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush console_debug batch to server
|
|
*/
|
|
static async _flush_console_batch() {
|
|
if (Debugger._console_batch.length === 0) {
|
|
return;
|
|
}
|
|
const messages = Debugger._console_batch;
|
|
Debugger._console_batch = [];
|
|
Debugger._console_timer = null;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_console_messages'), {
|
|
messages: messages
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send console_debug messages to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush error batch to server
|
|
*/
|
|
static async _flush_error_batch() {
|
|
if (Debugger._error_batch.length === 0) {
|
|
return;
|
|
}
|
|
const errors = Debugger._error_batch;
|
|
Debugger._error_batch = [];
|
|
Debugger._error_timer = null;
|
|
Debugger._error_batch_count++;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_browser_errors'), {
|
|
errors: errors
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send browser errors to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Get time prefix for benchmarking
|
|
*/
|
|
static _get_time_prefix() {
|
|
const now = Date.now();
|
|
if (!Debugger._start_time) {
|
|
Debugger._start_time = now;
|
|
}
|
|
const elapsed = now - Debugger._start_time;
|
|
return (elapsed / 1000).toFixed(3) + 's';
|
|
}
|
|
}
|
|
// Batching state for console_debug messages
|
|
_27e0e986_defineProperty(Debugger, "_console_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_console_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_console_batch_count", 0);
|
|
// Batching state for error messages
|
|
_27e0e986_defineProperty(Debugger, "_error_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_error_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_error_count", 0);
|
|
_27e0e986_defineProperty(Debugger, "_error_batch_count", 0);
|
|
// Constants
|
|
_27e0e986_defineProperty(Debugger, "DEBOUNCE_MS", 2000);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERRORS_PER_PAGE", 20);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERROR_BATCHES", 5);
|
|
// Store start time for benchmarking
|
|
_27e0e986_defineProperty(Debugger, "_start_time", null);
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Jq_Helpers.js (babel) === */
|
|
"use strict";
|
|
|
|
// @JS-THIS-01-EXCEPTION
|
|
/**
|
|
* jQuery helper extensions for the RSX framework
|
|
* These extensions add utility methods to jQuery's prototype
|
|
* Note: 'this' references in jQuery extensions refer to jQuery objects by design
|
|
*/
|
|
class Rsx_Jq_Helpers {
|
|
/**
|
|
* Initialize jQuery extensions when the framework core is defined
|
|
* This method is called during framework initialization
|
|
*/
|
|
static _on_framework_core_define() {
|
|
// Returns true if jquery selector matched an element
|
|
$.fn.exists = function () {
|
|
return this.length > 0;
|
|
};
|
|
|
|
// Returns true if jquery element is visible
|
|
$.fn.is_visible = function () {
|
|
return this.is(':visible');
|
|
};
|
|
|
|
// Scrolls to the target element, only scrolls up. Todo: Create a version
|
|
// of this that also scrolls only down, or both
|
|
$.fn.scroll_up_to = function () {
|
|
let speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
if (!this.exists()) {
|
|
// console.warn("Could not find target element to scroll to");
|
|
return;
|
|
}
|
|
if (!this.is_in_dom()) {
|
|
// console.warn("Target element for scroll is not on dom");
|
|
return;
|
|
}
|
|
let e_top = Math.round(this.offset().top);
|
|
let s_top = $('body').scrollTop();
|
|
if (e_top < 0) {
|
|
let target = s_top + e_top;
|
|
$('html, body').animate({
|
|
scrollTop: target
|
|
}, speed);
|
|
}
|
|
};
|
|
|
|
// $().is(":focus") - check if element has focus
|
|
$.expr[':'].focus = function (elem) {
|
|
return elem === document.activeElement && (elem.type || elem.href);
|
|
};
|
|
|
|
// Save native click behavior before override
|
|
$.fn._click_native = $.fn.click;
|
|
|
|
// Override .click() to call preventDefault by default
|
|
// This prevents accidental page navigation/form submission - the correct behavior 95% of the time
|
|
$.fn.click = function (handler) {
|
|
// If no handler provided, trigger click event (jQuery .click() with no args)
|
|
if (typeof handler === 'undefined') {
|
|
return this._click_native();
|
|
}
|
|
|
|
// Attach click handler with automatic preventDefault
|
|
return this.on('click', function (e) {
|
|
// Save original preventDefault
|
|
const original_preventDefault = e.preventDefault.bind(e);
|
|
|
|
// Override preventDefault to show warning when called explicitly
|
|
e.preventDefault = function () {
|
|
console.warn('event.preventDefault() is called automatically by RSpade .click() handlers and can be removed.');
|
|
return original_preventDefault();
|
|
};
|
|
|
|
// Call preventDefault before handler
|
|
original_preventDefault();
|
|
return handler.call(this, e);
|
|
});
|
|
};
|
|
|
|
// Escape hatch: click handler without preventDefault for the 5% case
|
|
$.fn.click_allow_default = function (handler) {
|
|
if (typeof handler === 'undefined') {
|
|
return this._click_native();
|
|
}
|
|
return this._click_native(handler);
|
|
};
|
|
|
|
// Returns true if the jquery element exists in and is attached to the DOM
|
|
$.fn.is_in_dom = function () {
|
|
let $element = this;
|
|
let _ancestor = function (HTMLobj) {
|
|
while (HTMLobj.parentElement) {
|
|
HTMLobj = HTMLobj.parentElement;
|
|
}
|
|
return HTMLobj;
|
|
};
|
|
return _ancestor($element[0]) === document.documentElement;
|
|
};
|
|
|
|
// Returns true if the element is visible in the viewport
|
|
$.fn.is_in_viewport = function () {
|
|
let scrolltop = $(window).scrollTop() > 0 ? $(window).scrollTop() : $('body').scrollTop();
|
|
let $element = this;
|
|
const top_of_element = $element.offset().top;
|
|
const bottom_of_element = $element.offset().top + $element.outerHeight();
|
|
const bottom_of_screen = scrolltop + $(window).innerHeight();
|
|
const top_of_screen = scrolltop;
|
|
if (bottom_of_screen > top_of_element && top_of_screen < bottom_of_element) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Gets the tagname of a jquery element
|
|
$.fn.tagname = function () {
|
|
return this.prop('tagName').toLowerCase();
|
|
};
|
|
|
|
// Returns true if a href is not same domain
|
|
$.fn.is_external = function () {
|
|
const host = window.location.host;
|
|
const link = $('<a>', {
|
|
href: this.attr('href')
|
|
})[0].hostname;
|
|
return link !== host;
|
|
};
|
|
|
|
// HTML5 form validation wrappers
|
|
$.fn.checkValidity = function () {
|
|
if (this.length === 0) return false;
|
|
return this[0].checkValidity();
|
|
};
|
|
$.fn.reportValidity = function () {
|
|
if (this.length === 0) return false;
|
|
return this[0].reportValidity();
|
|
};
|
|
$.fn.requestSubmit = function () {
|
|
if (this.length === 0) return this;
|
|
this[0].requestSubmit();
|
|
return this;
|
|
};
|
|
|
|
// Find related components by searching up the ancestor tree
|
|
// Like .closest() but searches within ancestors instead of matching them
|
|
$.fn.closest_sibling = function (selector) {
|
|
let $current = this;
|
|
let $parent = $current.parent();
|
|
|
|
// Keep going up the tree until we hit body
|
|
while ($parent.length > 0 && !$parent.is('body')) {
|
|
// Search within this parent for the selector
|
|
let $found = $parent.find(selector);
|
|
if ($found.length > 0) {
|
|
return $found;
|
|
}
|
|
|
|
// Move up one level
|
|
$parent = $parent.parent();
|
|
}
|
|
|
|
// If we reached body, search within body as well
|
|
if ($parent.is('body')) {
|
|
let $found = $parent.find(selector);
|
|
if ($found.length > 0) {
|
|
return $found;
|
|
}
|
|
}
|
|
|
|
// Return empty jQuery object if nothing found
|
|
return $();
|
|
};
|
|
|
|
// Override $.ajax to prevent direct AJAX calls to local server
|
|
// Developers must use the Ajax endpoint pattern: await Controller.method(params)
|
|
const native_ajax = $.ajax;
|
|
$.ajax = function (url, options) {
|
|
// Handle both $.ajax(url, options) and $.ajax(options) signatures
|
|
let settings;
|
|
if (typeof url === 'string') {
|
|
settings = options || {};
|
|
settings.url = url;
|
|
} else {
|
|
settings = url || {};
|
|
}
|
|
|
|
// Check if this is a local request (relative URL or same domain)
|
|
const request_url = settings.url || '';
|
|
const is_relative = !request_url.match(/^https?:\/\//);
|
|
const is_same_domain = request_url.startsWith(window.location.origin);
|
|
const is_local_request = is_relative || is_same_domain;
|
|
|
|
// Allow framework Ajax.call() to function
|
|
if (settings.__local_integration === true) {
|
|
return native_ajax.call(this, settings);
|
|
}
|
|
|
|
// Allow file upload endpoint - requires native $.ajax for FormData support
|
|
const is_file_upload = request_url === '/_upload' || request_url.endsWith('/_upload');
|
|
if (is_file_upload) {
|
|
return native_ajax.call(this, settings);
|
|
}
|
|
|
|
// Block local AJAX requests that don't use the Ajax endpoint pattern
|
|
if (is_local_request) {
|
|
// Try to parse controller and action from URL
|
|
let controller_name = null;
|
|
let action_name = null;
|
|
const url_match = request_url.match(/\/_rsx_api\/([^\/]+)\/([^\/\?]+)/);
|
|
if (url_match) {
|
|
controller_name = url_match[1];
|
|
action_name = url_match[2];
|
|
}
|
|
let error_message = 'AJAX requests to localhost via $.ajax() are prohibited.\n\n';
|
|
if (controller_name && action_name) {
|
|
error_message += `Instead of:\n`;
|
|
error_message += ` $.ajax({url: '${request_url}', ...})\n\n`;
|
|
error_message += `Use:\n`;
|
|
error_message += ` await ${controller_name}.${action_name}(parameters)\n\n`;
|
|
} else {
|
|
error_message += `Use the Ajax endpoint pattern:\n`;
|
|
error_message += ` await Controller_Name.action_name(parameters)\n\n`;
|
|
}
|
|
error_message += `The controller method must have the #[Ajax_Endpoint] attribute.`;
|
|
shouldnt_happen(error_message);
|
|
}
|
|
|
|
// Allow external requests (different domain)
|
|
return native_ajax.call(this, settings);
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx.js (babel) === */
|
|
"use strict";
|
|
|
|
function _e8211f5b_defineProperty(e, r, t) { return (r = _e8211f5b_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _e8211f5b_toPropertyKey(t) { var i = _e8211f5b_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _e8211f5b_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
// @ROUTE-EXISTS-01-EXCEPTION - This file contains documentation examples with fictional route names
|
|
|
|
/**
|
|
* Rsx - Core JavaScript Runtime System
|
|
*
|
|
* The Rsx class is the central hub for the RSX JavaScript runtime, providing essential
|
|
* system-level utilities that all other framework components depend on. It serves as the
|
|
* foundation for the client-side framework, handling core operations that must be globally
|
|
* accessible and consistently available.
|
|
*
|
|
* Core Responsibilities:
|
|
* - Event System: Application-wide event bus for framework lifecycle and custom events
|
|
* - Environment Detection: Runtime environment identification (dev/production)
|
|
* - Route Management: Type-safe route generation and URL building
|
|
* - Unique ID Generation: Client-side unique identifier generation
|
|
* - Framework Bootstrap: Multi-phase initialization orchestration
|
|
* - Logging: Centralized logging interface (delegates to console_debug)
|
|
*
|
|
* The Rsx class deliberately keeps its scope limited to core utilities. Advanced features
|
|
* are delegated to specialized classes:
|
|
* - Manifest operations → Manifest class
|
|
* - Caching → Rsx_Cache class
|
|
* - AJAX/API calls → Ajax_* classes
|
|
* - Route proxies → Rsx_Route_Proxy class
|
|
* - Behaviors → Rsx_Behaviors class
|
|
*
|
|
* All methods are static - Rsx is never instantiated. It's available globally from the
|
|
* moment bundles load and remains constant throughout the application lifecycle.
|
|
*
|
|
* Usage Examples:
|
|
* ```javascript
|
|
* // Event system
|
|
* Rsx.on('app_ready', () => console.log('App initialized'));
|
|
* Rsx.trigger('custom_event', {data: 'value'});
|
|
*
|
|
* // Environment detection
|
|
* if (Rsx.is_dev()) { console.log('Development mode'); }
|
|
*
|
|
* // Route generation
|
|
* const url = Rsx.Route('Controller', 'action').url();
|
|
*
|
|
* // Unique IDs
|
|
* const uniqueId = Rsx.uid(); // e.g., "rsx_1234567890_1"
|
|
* ```
|
|
*
|
|
* @static
|
|
* @global
|
|
*/
|
|
class Rsx {
|
|
// Initialize event handlers storage
|
|
static _init_events() {
|
|
if (typeof Rsx._event_handlers === 'undefined') {
|
|
Rsx._event_handlers = {};
|
|
}
|
|
if (typeof Rsx._triggered_events === 'undefined') {
|
|
Rsx._triggered_events = {};
|
|
}
|
|
}
|
|
|
|
// Register an event handler
|
|
static on(event, callback) {
|
|
Rsx._init_events();
|
|
if (typeof callback !== 'function') {
|
|
throw new Error('Callback must be a function');
|
|
}
|
|
if (!Rsx._event_handlers[event]) {
|
|
Rsx._event_handlers[event] = [];
|
|
}
|
|
Rsx._event_handlers[event].push(callback);
|
|
|
|
// If this event was already triggered, call the callback immediately
|
|
if (Rsx._triggered_events[event]) {
|
|
console_debug('RSX_INIT', 'Triggering ' + event + ' for late registered callback');
|
|
callback(Rsx._triggered_events[event]);
|
|
}
|
|
}
|
|
|
|
// Trigger an event with optional data
|
|
static trigger(event) {
|
|
let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
Rsx._init_events();
|
|
|
|
// Record that this event was triggered
|
|
Rsx._triggered_events[event] = data;
|
|
if (!Rsx._event_handlers[event]) {
|
|
return;
|
|
}
|
|
console_debug('RSX_INIT', 'Triggering ' + event + ' for ' + Rsx._event_handlers[event].length + ' callbacks');
|
|
|
|
// Call all registered handlers for this event in order
|
|
for (const callback of Rsx._event_handlers[event]) {
|
|
callback(data);
|
|
}
|
|
}
|
|
|
|
// Alias for trigger.refresh(''), should be called after major UI updates to apply such effects as
|
|
// underlining links to unimplemented # routes
|
|
static trigger_refresh() {
|
|
// Use Rsx.on('refresh', callback); to register a callback for refresh
|
|
this.trigger('refresh');
|
|
}
|
|
|
|
// Log to server that an event happened
|
|
static log(type) {
|
|
let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'notice';
|
|
Core_Log.log(type, message);
|
|
}
|
|
|
|
// Returns true if the app is being run in dev mode
|
|
// This should affect caching and some debug checks
|
|
static is_dev() {
|
|
return window.rsxapp.debug;
|
|
}
|
|
static is_prod() {
|
|
return !window.rsxapp.debug;
|
|
}
|
|
|
|
// Generates a unique number for the application instance
|
|
static uid() {
|
|
if (typeof Rsx._uid == undef) {
|
|
Rsx._uid = 0;
|
|
}
|
|
return Rsx._uid++;
|
|
}
|
|
|
|
// Storage for route definitions loaded from bundles
|
|
|
|
/**
|
|
* Define routes from bundled data
|
|
* Called by generated JavaScript in bundles
|
|
*/
|
|
static _define_routes(routes) {
|
|
// Merge routes into the global route storage
|
|
for (const class_name in routes) {
|
|
if (!Rsx._routes[class_name]) {
|
|
Rsx._routes[class_name] = {};
|
|
}
|
|
for (const method_name in routes[class_name]) {
|
|
Rsx._routes[class_name][method_name] = routes[class_name][method_name];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate URL for a controller route
|
|
*
|
|
* This method generates URLs for controller actions by looking up route patterns
|
|
* and replacing parameters. It handles both regular routes and Ajax endpoints.
|
|
*
|
|
* If the route is not found in the route definitions, a default pattern is used:
|
|
* `/_/{controller}/{action}` with all parameters appended as query strings.
|
|
*
|
|
* Usage examples:
|
|
* ```javascript
|
|
* // Simple route without parameters (defaults to 'index' action)
|
|
* const url = Rsx.Route('Frontend_Index_Controller');
|
|
* // Returns: /dashboard
|
|
*
|
|
* // Route with explicit action
|
|
* const url = Rsx.Route('Frontend_Index_Controller', 'index');
|
|
* // Returns: /dashboard
|
|
*
|
|
* // Route with integer parameter (sets 'id')
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', 123);
|
|
* // Returns: /clients/view/123
|
|
*
|
|
* // Route with named parameters (object)
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', {id: 'C001'});
|
|
* // Returns: /clients/view/C001
|
|
*
|
|
* // Route with required and query parameters
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', {
|
|
* id: 'C001',
|
|
* tab: 'history'
|
|
* });
|
|
* // Returns: /clients/view/C001?tab=history
|
|
*
|
|
* // Route not found - uses default pattern
|
|
* const url = Rsx.Route('Unimplemented_Controller', 'some_action', {foo: 'bar'});
|
|
* // Returns: /_/Unimplemented_Controller/some_action?foo=bar
|
|
*
|
|
* // Placeholder route
|
|
* const url = Rsx.Route('Future_Controller', '#index');
|
|
* // Returns: #
|
|
* ```
|
|
*
|
|
* @param {string} class_name The controller class name (e.g., 'User_Controller')
|
|
* @param {string} [action_name='index'] The action/method name (defaults to 'index'). Use '#action' for placeholders.
|
|
* @param {number|Object} [params=null] Route parameters. Integer sets 'id', object provides named params.
|
|
* @returns {string} The generated URL
|
|
*/
|
|
static Route(class_name) {
|
|
let action_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'index';
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
// Normalize params to object
|
|
let params_obj = {};
|
|
if (typeof params === 'number') {
|
|
params_obj = {
|
|
id: params
|
|
};
|
|
} else if (params && typeof params === 'object') {
|
|
params_obj = params;
|
|
} else if (params !== null && params !== undefined) {
|
|
throw new Error('Params must be number, object, or null');
|
|
}
|
|
|
|
// Placeholder route: action starts with # means unimplemented/scaffolding
|
|
if (action_name.startsWith('#')) {
|
|
return '#';
|
|
}
|
|
|
|
// Check if route exists in definitions
|
|
let pattern;
|
|
if (Rsx._routes[class_name] && Rsx._routes[class_name][action_name]) {
|
|
pattern = Rsx._routes[class_name][action_name];
|
|
} else {
|
|
// Route not found - use default pattern /_/{controller}/{action}
|
|
pattern = `/_/${class_name}/${action_name}`;
|
|
}
|
|
|
|
// Generate URL from pattern
|
|
return Rsx._generate_url_from_pattern(pattern, params_obj);
|
|
}
|
|
|
|
/**
|
|
* Generate URL from route pattern by replacing parameters
|
|
*
|
|
* @param {string} pattern The route pattern (e.g., '/users/:id/view')
|
|
* @param {Object} params Parameters to fill into the route
|
|
* @returns {string} The generated URL
|
|
*/
|
|
static _generate_url_from_pattern(pattern, params) {
|
|
// Extract required parameters from the pattern
|
|
const required_params = [];
|
|
const matches = pattern.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
|
|
if (matches) {
|
|
// Remove the : prefix from each match
|
|
for (const match of matches) {
|
|
required_params.push(match.substring(1));
|
|
}
|
|
}
|
|
|
|
// Check for required parameters
|
|
const missing = [];
|
|
for (const required of required_params) {
|
|
if (!(required in params)) {
|
|
missing.push(required);
|
|
}
|
|
}
|
|
if (missing.length > 0) {
|
|
throw new Error(`Required parameters [${missing.join(', ')}] are missing for route ${pattern}`);
|
|
}
|
|
|
|
// Build the URL by replacing parameters
|
|
let url = pattern;
|
|
const used_params = {};
|
|
for (const param_name of required_params) {
|
|
const value = params[param_name];
|
|
// URL encode the value
|
|
const encoded_value = encodeURIComponent(value);
|
|
url = url.replace(':' + param_name, encoded_value);
|
|
used_params[param_name] = true;
|
|
}
|
|
|
|
// Collect any extra parameters for query string
|
|
const query_params = {};
|
|
for (const key in params) {
|
|
if (!used_params[key]) {
|
|
query_params[key] = params[key];
|
|
}
|
|
}
|
|
|
|
// Append query string if there are extra parameters
|
|
if (Object.keys(query_params).length > 0) {
|
|
const query_string = Object.entries(query_params).map(_ref => {
|
|
let [key, value] = _ref;
|
|
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
}).join('&');
|
|
url += '?' + query_string;
|
|
}
|
|
return url;
|
|
}
|
|
|
|
/**
|
|
* Internal: Call a specific method on all classes that have it
|
|
* Collects promises from return values and waits for all to resolve
|
|
* @param {string} method_name The method name to call on all classes
|
|
* @returns {Promise} Promise that resolves when all method calls complete
|
|
*/
|
|
static async _rsx_call_all_classes(method_name) {
|
|
const all_classes = Manifest.get_all_classes();
|
|
const classes_with_method = [];
|
|
const promise_pile = [];
|
|
for (const class_info of all_classes) {
|
|
const class_object = class_info.class_object;
|
|
const class_name = class_info.class_name;
|
|
|
|
// Check if this class has the method (static methods are on the class itself)
|
|
if (typeof class_object[method_name] === 'function') {
|
|
classes_with_method.push(class_name);
|
|
const return_value = await class_object[method_name]();
|
|
|
|
// Collect promises from return value
|
|
if (return_value instanceof Promise) {
|
|
promise_pile.push(return_value);
|
|
} else if (Array.isArray(return_value)) {
|
|
for (const item of return_value) {
|
|
if (item instanceof Promise) {
|
|
promise_pile.push(item);
|
|
}
|
|
}
|
|
}
|
|
if (Rsx.__stopped) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (classes_with_method.length > 0) {
|
|
console_debug('RSX_INIT', `${method_name}: ${classes_with_method.length} classes`);
|
|
}
|
|
|
|
// Await all promises before returning
|
|
if (promise_pile.length > 0) {
|
|
console_debug('RSX_INIT', `${method_name}: Awaiting ${promise_pile.length} promises`);
|
|
await Promise.all(promise_pile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Execute multi-phase initialization for all registered classes
|
|
* This runs various initialization phases in order to properly set up the application
|
|
* @returns {Promise} Promise that resolves when all initialization phases complete
|
|
*/
|
|
static async _rsx_core_boot() {
|
|
if (Rsx.__booted) {
|
|
console.error('Rsx._rsx_core_boot called more than once');
|
|
return;
|
|
}
|
|
Rsx.__booted = true;
|
|
|
|
// Get all registered classes from the manifest
|
|
const all_classes = Manifest.get_all_classes();
|
|
console_debug('RSX_INIT', `Starting _rsx_core_boot with ${all_classes.length} classes`);
|
|
if (!all_classes || all_classes.length === 0) {
|
|
// No classes to initialize
|
|
shouldnt_happen('No classes registered in js - there should be at least the core framework classes');
|
|
return;
|
|
}
|
|
|
|
// Define initialization phases in order
|
|
const phases = [{
|
|
event: 'framework_core_define',
|
|
method: '_on_framework_core_define'
|
|
}, {
|
|
event: 'framework_modules_define',
|
|
method: '_on_framework_modules_define'
|
|
}, {
|
|
event: 'framework_core_init',
|
|
method: '_on_framework_core_init'
|
|
}, {
|
|
event: 'app_modules_define',
|
|
method: 'on_app_modules_define'
|
|
}, {
|
|
event: 'app_define',
|
|
method: 'on_app_define'
|
|
}, {
|
|
event: 'framework_modules_init',
|
|
method: '_on_framework_modules_init'
|
|
}, {
|
|
event: 'app_modules_init',
|
|
method: 'on_app_modules_init'
|
|
}, {
|
|
event: 'app_init',
|
|
method: 'on_app_init'
|
|
}, {
|
|
event: 'app_ready',
|
|
method: 'on_app_ready'
|
|
}];
|
|
|
|
// Execute each phase in order
|
|
for (const phase of phases) {
|
|
await Rsx._rsx_call_all_classes(phase.method);
|
|
if (Rsx.__stopped) {
|
|
return;
|
|
}
|
|
Rsx.trigger(phase.event);
|
|
}
|
|
|
|
// Ui refresh callbacks
|
|
Rsx.trigger_refresh();
|
|
|
|
// All phases complete
|
|
console_debug('RSX_INIT', 'Initialization complete');
|
|
|
|
// TODO: Find a good wait to wait for all jqhtml components to load, then trigger on_ready and on('ready') emulating the top level last syntax that jqhtml components operateas, but as a standard js class (such as a page class). The biggest question is, how do we efficiently choose only the top level jqhtml components. do we only consider components cretaed directly on blade templates? that seams reasonable...
|
|
|
|
// Trigger _debug_ready event - this is ONLY for tooling like rsx:debug
|
|
// DO NOT use this in application code - use on_app_ready() phase instead
|
|
// This event exists solely for debugging tools that need to run after full initialization
|
|
Rsx.trigger('_debug_ready');
|
|
}
|
|
|
|
/* Calling this stops the boot process. */
|
|
static async _rsx_core_boot_stop(reason) {
|
|
console.error(reason);
|
|
Rsx.__stopped = true;
|
|
}
|
|
|
|
/**
|
|
* Parse URL hash into key-value object
|
|
* Handles format: #key=value&key2=value2
|
|
*
|
|
* @returns {Object} Parsed hash parameters
|
|
*/
|
|
static _parse_hash() {
|
|
const hash = window.location.hash;
|
|
if (!hash || hash === '#') {
|
|
return {};
|
|
}
|
|
|
|
// Remove leading # and parse as query string
|
|
const hash_string = hash.substring(1);
|
|
const params = {};
|
|
const pairs = hash_string.split('&');
|
|
for (const pair of pairs) {
|
|
const [key, value] = pair.split('=');
|
|
if (key) {
|
|
params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
|
|
}
|
|
}
|
|
return params;
|
|
}
|
|
|
|
/**
|
|
* Serialize object into URL hash format
|
|
* Produces format: #key=value&key2=value2
|
|
*
|
|
* @param {Object} params Key-value pairs to encode
|
|
* @returns {string} Encoded hash string (with leading #, or empty string)
|
|
*/
|
|
static _serialize_hash(params) {
|
|
const pairs = [];
|
|
for (const key in params) {
|
|
const value = params[key];
|
|
if (value !== null && value !== undefined && value !== '') {
|
|
pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
}
|
|
}
|
|
return pairs.length > 0 ? '#' + pairs.join('&') : '';
|
|
}
|
|
|
|
/**
|
|
* Get all page state from URL hash
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* const state = Rsx.get_all_page_state();
|
|
* // Returns: {dg_page: '2', dg_sort: 'name'}
|
|
* ```
|
|
*
|
|
* @returns {Object} All hash parameters as key-value pairs
|
|
*/
|
|
static get_all_page_state() {
|
|
return Rsx._parse_hash();
|
|
}
|
|
|
|
/**
|
|
* Get single value from URL hash state
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* const page = Rsx.get_page_state('dg_page');
|
|
* // Returns: '2' or null if not set
|
|
* ```
|
|
*
|
|
* @param {string} key The key to retrieve
|
|
* @returns {string|null} The value or null if not found
|
|
*/
|
|
static get_page_state(key) {
|
|
var _state$key;
|
|
const state = Rsx._parse_hash();
|
|
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
}
|
|
|
|
/**
|
|
* Set single value in URL hash state (replaces history, doesn't add)
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* Rsx.set_page_state('dg_page', 2);
|
|
* // URL becomes: http://example.com/page#dg_page=2
|
|
*
|
|
* Rsx.set_page_state('dg_page', null); // Remove key
|
|
* ```
|
|
*
|
|
* @param {string} key The key to set
|
|
* @param {string|number|null} value The value (null/empty removes the key)
|
|
*/
|
|
static set_page_state(key, value) {
|
|
const state = Rsx._parse_hash();
|
|
|
|
// Update or remove the key
|
|
if (value === null || value === undefined || value === '') {
|
|
delete state[key];
|
|
} else {
|
|
state[key] = String(value);
|
|
}
|
|
|
|
// Update URL without adding history
|
|
const new_hash = Rsx._serialize_hash(state);
|
|
const url = window.location.pathname + window.location.search + new_hash;
|
|
history.replaceState(null, '', url);
|
|
}
|
|
|
|
/**
|
|
* Set multiple values in URL hash state at once
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* Rsx.set_all_page_state({dg_page: 2, dg_sort: 'name'});
|
|
* // URL becomes: http://example.com/page#dg_page=2&dg_sort=name
|
|
* ```
|
|
*
|
|
* @param {Object} new_state Object with key-value pairs to set
|
|
*/
|
|
static set_all_page_state(new_state) {
|
|
const state = Rsx._parse_hash();
|
|
|
|
// Merge new state
|
|
for (const key in new_state) {
|
|
const value = new_state[key];
|
|
if (value === null || value === undefined || value === '') {
|
|
delete state[key];
|
|
} else {
|
|
state[key] = String(value);
|
|
}
|
|
}
|
|
|
|
// Update URL without adding history
|
|
const new_hash = Rsx._serialize_hash(state);
|
|
const url = window.location.pathname + window.location.search + new_hash;
|
|
history.replaceState(null, '', url);
|
|
}
|
|
|
|
/**
|
|
* Render an error in a DOM element
|
|
*
|
|
* Displays errors from Ajax calls in a standardized format. Handles different
|
|
* error types (fatal, validation, auth, generic) with appropriate formatting.
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* try {
|
|
* const result = await Controller.method();
|
|
* } catch (error) {
|
|
* Rsx.render_error(error, '#error_container');
|
|
* }
|
|
* ```
|
|
*
|
|
* @param {Error|Object} error - Error object from Ajax call
|
|
* @param {jQuery|string} container - jQuery element or selector for error display
|
|
*/
|
|
static render_error(error, container) {
|
|
const $container = $(container);
|
|
if (!$container.exists()) {
|
|
console.error('Rsx.render_error: Container not found', container);
|
|
return;
|
|
}
|
|
|
|
// Clear existing content
|
|
$container.empty();
|
|
let html = '';
|
|
|
|
// Handle different error types
|
|
if (error.type === 'fatal' && error.details) {
|
|
// Fatal PHP error with file/line/error
|
|
const details = error.details;
|
|
const file = details.file || 'Unknown file';
|
|
const line = details.line || '?';
|
|
const message = details.error || error.message || 'Fatal error occurred';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<h5>Uncaught Fatal Error in ${file}:${line}:</h5>
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else if (error.type === 'form_error' && error.details) {
|
|
// Validation errors - show unmatched errors only
|
|
// (matched errors should be handled by Form_Utils.apply_form_errors)
|
|
const errors = error.details;
|
|
const error_list = [];
|
|
for (const field in errors) {
|
|
error_list.push(errors[field]);
|
|
}
|
|
if (error_list.length > 0) {
|
|
html = `
|
|
<div class="alert alert-warning" role="alert">
|
|
<h5>Validation Errors:</h5>
|
|
<ul class="mb-0">
|
|
${error_list.map(err => `<li>${Rsx._escape_html(err)}</li>`).join('')}
|
|
</ul>
|
|
</div>
|
|
`;
|
|
}
|
|
} else if (error.type === 'auth_required' || error.type === 'unauthorized') {
|
|
// Authentication/authorization errors
|
|
const message = error.message || 'Authentication required';
|
|
html = `
|
|
<div class="alert alert-warning" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else if (error.type === 'network') {
|
|
// Network errors
|
|
const message = error.message || 'Unable to reach server. Please check your connection.';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else {
|
|
// Generic/unknown error
|
|
const message = error.message || error.toString() || 'An unknown error occurred';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
}
|
|
$container.html(html);
|
|
}
|
|
|
|
/**
|
|
* Escape HTML to prevent XSS in error messages
|
|
* @private
|
|
*/
|
|
static _escape_html(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
}
|
|
// Gets set to true to interupt startup sequence
|
|
_e8211f5b_defineProperty(Rsx, "__stopped", false);
|
|
_e8211f5b_defineProperty(Rsx, "_routes", {});
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Ajax.js (babel) === */
|
|
"use strict";
|
|
|
|
// @FILE-SUBCLASS-01-EXCEPTION
|
|
|
|
/**
|
|
* Client-side Ajax class for making API calls to RSX controllers
|
|
*
|
|
* Automatically batches multiple calls into single HTTP requests to reduce network overhead.
|
|
* Batches up to 20 calls or flushes after setTimeout(0) debounce.
|
|
*/
|
|
class Ajax {
|
|
/**
|
|
* Initialize Ajax system
|
|
* Called automatically when class is loaded
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Queue of pending calls waiting to be batched
|
|
Ajax._pending_calls = {};
|
|
|
|
// Timer for batching flush
|
|
Ajax._flush_timeout = null;
|
|
|
|
// Call counter for generating unique call IDs
|
|
Ajax._call_counter = 0;
|
|
|
|
// Maximum batch size before forcing immediate flush
|
|
Ajax.MAX_BATCH_SIZE = 20;
|
|
|
|
// Debounce time in milliseconds
|
|
Ajax.DEBOUNCE_MS = 0;
|
|
|
|
// Track promises from Ajax calls to detect uncaught rejections
|
|
Ajax._tracked_promises = new WeakSet();
|
|
|
|
// Set up global unhandled rejection handler for Ajax errors
|
|
window.addEventListener('unhandledrejection', async event => {
|
|
// Only handle rejections from Ajax promises
|
|
if (Ajax._tracked_promises.has(event.promise)) {
|
|
event.preventDefault(); // Prevent browser's default "Uncaught (in promise)" error
|
|
|
|
const error = event.reason;
|
|
console.error('Uncaught Ajax error:', error);
|
|
|
|
// Show Modal.error() for uncaught Ajax errors
|
|
if (typeof Modal !== 'undefined' && Modal.error) {
|
|
await Modal.error(error, 'Uncaught Ajax Error');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Make an AJAX call to an RSX controller action
|
|
*
|
|
* All calls are automatically batched unless window.rsxapp.ajax_disable_batching is true.
|
|
*
|
|
* @param {string|object|function} url - The Ajax URL (e.g., '/_ajax/Controller_Name/action_name') or an object/function with a .path property
|
|
* @param {object} params - Parameters to send to the action
|
|
* @returns {Promise} - Resolves with the return value, rejects with error
|
|
*/
|
|
static async call(url) {
|
|
let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
// If url is an object or function with a .path property, use that as the URL
|
|
if (url && typeof url === 'object' && url.path) {
|
|
url = url.path;
|
|
} else if (url && typeof url === 'function' && url.path) {
|
|
url = url.path;
|
|
}
|
|
|
|
// Validate url is a non-empty string
|
|
if (typeof url !== 'string' || url.length === 0) {
|
|
throw new Error('Ajax.call() requires a non-empty string URL or an object/function with a .path property');
|
|
}
|
|
|
|
// Extract controller and action from URL
|
|
const {
|
|
controller,
|
|
action
|
|
} = Ajax.ajax_url_to_controller_action(url);
|
|
console.log('Ajax:', controller, action, params);
|
|
|
|
// Check if batching is disabled for debugging
|
|
let promise;
|
|
if (window.rsxapp && window.rsxapp.ajax_disable_batching) {
|
|
promise = Ajax._call_direct(controller, action, params);
|
|
} else {
|
|
promise = Ajax._call_batch(controller, action, params);
|
|
}
|
|
|
|
// Track this promise for unhandled rejection detection
|
|
Ajax._tracked_promises.add(promise);
|
|
return promise;
|
|
}
|
|
|
|
/**
|
|
* Make a batched Ajax call
|
|
* @private
|
|
*/
|
|
static _call_batch(controller, action) {
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
console.log('Ajax Batch:', controller, action, params);
|
|
return new Promise((resolve, reject) => {
|
|
// Generate call key for deduplication
|
|
const call_key = Ajax._generate_call_key(controller, action, params);
|
|
|
|
// Check if this exact call is already pending
|
|
if (Ajax._pending_calls[call_key]) {
|
|
const existing_call = Ajax._pending_calls[call_key];
|
|
|
|
// If call already completed (cached), return immediately
|
|
if (existing_call.is_complete) {
|
|
if (existing_call.is_error) {
|
|
reject(existing_call.error);
|
|
} else {
|
|
resolve(existing_call.result);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Call is pending, add this promise to callbacks
|
|
existing_call.callbacks.push({
|
|
resolve,
|
|
reject
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Create new pending call
|
|
const call_id = Ajax._call_counter++;
|
|
const pending_call = {
|
|
call_id: call_id,
|
|
call_key: call_key,
|
|
controller: controller,
|
|
action: action,
|
|
params: params,
|
|
callbacks: [{
|
|
resolve,
|
|
reject
|
|
}],
|
|
is_complete: false,
|
|
is_error: false,
|
|
result: null,
|
|
error: null
|
|
};
|
|
|
|
// Add to pending queue
|
|
Ajax._pending_calls[call_key] = pending_call;
|
|
|
|
// Count pending calls
|
|
const pending_count = Object.keys(Ajax._pending_calls).filter(key => !Ajax._pending_calls[key].is_complete).length;
|
|
|
|
// If we've hit the batch size limit, flush immediately
|
|
if (pending_count >= Ajax.MAX_BATCH_SIZE) {
|
|
clearTimeout(Ajax._flush_timeout);
|
|
Ajax._flush_timeout = null;
|
|
Ajax._flush_pending_calls();
|
|
} else {
|
|
// Schedule batch flush with debounce
|
|
clearTimeout(Ajax._flush_timeout);
|
|
Ajax._flush_timeout = setTimeout(() => {
|
|
Ajax._flush_pending_calls();
|
|
}, Ajax.DEBOUNCE_MS);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Make a direct (non-batched) Ajax call
|
|
* @private
|
|
*/
|
|
static async _call_direct(controller, action) {
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
// Construct URL from controller and action
|
|
const url = `/_ajax/${controller}/${action}`;
|
|
|
|
// Log the AJAX call using console_debug
|
|
if (typeof Debugger !== 'undefined' && Debugger.console_debug) {
|
|
Debugger.console_debug('AJAX', `Calling ${controller}.${action} (unbatched)`, params);
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
$.ajax({
|
|
url: url,
|
|
method: 'POST',
|
|
data: params,
|
|
dataType: 'json',
|
|
__local_integration: true,
|
|
// Bypass $.ajax override
|
|
success: response => {
|
|
// Handle console_debug messages
|
|
if (response.console_debug && Array.isArray(response.console_debug)) {
|
|
response.console_debug.forEach(msg => {
|
|
if (!Array.isArray(msg) || msg.length !== 2) {
|
|
throw new Error('Invalid console_debug message format - expected [channel, [arguments]]');
|
|
}
|
|
const [channel, args] = msg;
|
|
console.log(channel, ...args);
|
|
});
|
|
}
|
|
|
|
// Check if the response was successful
|
|
if (response._success === true) {
|
|
// @JS-AJAX-02-EXCEPTION - Unwrap server responses with _ajax_return_value
|
|
const processed_value = Rsx_Js_Model._instantiate_models_recursive(response._ajax_return_value);
|
|
resolve(processed_value);
|
|
} else {
|
|
// Handle error responses
|
|
const error_type = response.error_type || 'unknown_error';
|
|
const reason = response.reason || 'Unknown error occurred';
|
|
const details = response.details || {};
|
|
|
|
// Handle specific error types
|
|
switch (error_type) {
|
|
case 'fatal':
|
|
// Fatal PHP error with full error details
|
|
const fatal_error_data = response.error || {};
|
|
const error_message = fatal_error_data.error || 'Fatal error occurred';
|
|
console.error('Ajax error response from server:', response.error);
|
|
const fatal_error = new Error(error_message);
|
|
fatal_error.type = 'fatal';
|
|
fatal_error.details = response.error;
|
|
|
|
// Log to server if browser error logging is enabled
|
|
Debugger.log_error({
|
|
message: `Ajax Fatal Error: ${error_message}`,
|
|
type: 'ajax_fatal',
|
|
endpoint: url,
|
|
details: response.error
|
|
});
|
|
reject(fatal_error);
|
|
break;
|
|
case 'response_auth_required':
|
|
console.error('The user is no longer authenticated, this is a placeholder for future code which handles this scenario.');
|
|
const auth_error = new Error(reason);
|
|
auth_error.type = 'auth_required';
|
|
auth_error.details = details;
|
|
reject(auth_error);
|
|
break;
|
|
case 'response_unauthorized':
|
|
console.error('The user is unauthorized to perform this action, this is a placeholder for future code which handles this scenario.');
|
|
const unauth_error = new Error(reason);
|
|
unauth_error.type = 'unauthorized';
|
|
unauth_error.details = details;
|
|
reject(unauth_error);
|
|
break;
|
|
case 'response_form_error':
|
|
const form_error = new Error(reason);
|
|
form_error.type = 'form_error';
|
|
form_error.details = details;
|
|
reject(form_error);
|
|
break;
|
|
default:
|
|
const generic_error = new Error(reason);
|
|
generic_error.type = error_type;
|
|
generic_error.details = details;
|
|
reject(generic_error);
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
error: (xhr, status, error) => {
|
|
const error_message = Ajax._extract_error_message(xhr);
|
|
const network_error = new Error(error_message);
|
|
network_error.type = 'network_error';
|
|
network_error.status = xhr.status;
|
|
network_error.statusText = status;
|
|
|
|
// Log server errors (500+) to the server if browser error logging is enabled
|
|
if (xhr.status >= 500) {
|
|
Debugger.log_error({
|
|
message: `Ajax Server Error ${xhr.status}: ${error_message}`,
|
|
type: 'ajax_server_error',
|
|
endpoint: url,
|
|
status: xhr.status,
|
|
statusText: status
|
|
});
|
|
}
|
|
reject(network_error);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Flush all pending calls by sending batch request
|
|
* @private
|
|
*/
|
|
static async _flush_pending_calls() {
|
|
// Collect all pending calls
|
|
const calls_to_send = [];
|
|
const call_map = {}; // Map call_id to pending_call object
|
|
|
|
for (const call_key in Ajax._pending_calls) {
|
|
const pending_call = Ajax._pending_calls[call_key];
|
|
if (!pending_call.is_complete) {
|
|
calls_to_send.push({
|
|
call_id: pending_call.call_id,
|
|
controller: pending_call.controller,
|
|
action: pending_call.action,
|
|
params: pending_call.params
|
|
});
|
|
call_map[pending_call.call_id] = pending_call;
|
|
}
|
|
}
|
|
|
|
// Nothing to send
|
|
if (calls_to_send.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// Log batch for debugging
|
|
if (typeof Debugger !== 'undefined' && Debugger.console_debug) {
|
|
Debugger.console_debug('AJAX_BATCH', `Sending batch of ${calls_to_send.length} calls`, calls_to_send.map(c => `${c.controller}.${c.action}`));
|
|
}
|
|
try {
|
|
// Send batch request
|
|
const response = await $.ajax({
|
|
url: '/_ajax/_batch',
|
|
method: 'POST',
|
|
data: {
|
|
batch_calls: JSON.stringify(calls_to_send)
|
|
},
|
|
dataType: 'json',
|
|
__local_integration: true // Bypass $.ajax override
|
|
});
|
|
|
|
// Process batch response
|
|
// Response format: { C_0: {success, _ajax_return_value}, C_1: {...}, ... }
|
|
for (const response_key in response) {
|
|
if (!response_key.startsWith('C_')) {
|
|
continue;
|
|
}
|
|
const call_id = parseInt(response_key.substring(2), 10);
|
|
const call_response = response[response_key];
|
|
const pending_call = call_map[call_id];
|
|
if (!pending_call) {
|
|
console.error('Received response for unknown call_id:', call_id);
|
|
continue;
|
|
}
|
|
|
|
// Handle console_debug messages if present
|
|
if (call_response.console_debug && Array.isArray(call_response.console_debug)) {
|
|
call_response.console_debug.forEach(msg => {
|
|
if (!Array.isArray(msg) || msg.length !== 2) {
|
|
throw new Error('Invalid console_debug message format - expected [channel, [arguments]]');
|
|
}
|
|
const [channel, args] = msg;
|
|
console.log(channel, ...args);
|
|
});
|
|
}
|
|
|
|
// Mark call as complete
|
|
pending_call.is_complete = true;
|
|
|
|
// Check if successful
|
|
if (call_response._success === true) {
|
|
// @JS-AJAX-02-EXCEPTION - Batch system unwraps server responses with _ajax_return_value
|
|
const processed_value = Rsx_Js_Model._instantiate_models_recursive(call_response._ajax_return_value);
|
|
pending_call.result = processed_value;
|
|
|
|
// Resolve all callbacks
|
|
pending_call.callbacks.forEach(_ref => {
|
|
let {
|
|
resolve
|
|
} = _ref;
|
|
resolve(processed_value);
|
|
});
|
|
} else {
|
|
// Handle error
|
|
const error_type = call_response.error_type || 'unknown_error';
|
|
let error_message;
|
|
let error_details;
|
|
if (error_type === 'fatal' && call_response.error) {
|
|
// Fatal PHP error with full error details
|
|
const fatal_error_data = call_response.error;
|
|
error_message = fatal_error_data.error || 'Fatal error occurred';
|
|
error_details = call_response.error;
|
|
console.error('Ajax error response from server:', call_response.error);
|
|
} else {
|
|
// Other error types
|
|
error_message = call_response.reason || 'Unknown error occurred';
|
|
error_details = call_response.details || {};
|
|
}
|
|
const error = new Error(error_message);
|
|
error.type = error_type;
|
|
error.details = error_details;
|
|
pending_call.is_error = true;
|
|
pending_call.error = error;
|
|
|
|
// Reject all callbacks
|
|
pending_call.callbacks.forEach(_ref2 => {
|
|
let {
|
|
reject
|
|
} = _ref2;
|
|
reject(error);
|
|
});
|
|
}
|
|
}
|
|
} catch (xhr_error) {
|
|
// Network or server error - reject all pending calls
|
|
const error_message = Ajax._extract_error_message(xhr_error);
|
|
const error = new Error(error_message);
|
|
error.type = 'network_error';
|
|
for (const call_id in call_map) {
|
|
const pending_call = call_map[call_id];
|
|
pending_call.is_complete = true;
|
|
pending_call.is_error = true;
|
|
pending_call.error = error;
|
|
pending_call.callbacks.forEach(_ref3 => {
|
|
let {
|
|
reject
|
|
} = _ref3;
|
|
reject(error);
|
|
});
|
|
}
|
|
console.error('Batch Ajax request failed:', error_message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a unique key for deduplicating calls
|
|
* @private
|
|
*/
|
|
static _generate_call_key(controller, action, params) {
|
|
// Create a stable string representation of the call
|
|
// Sort params keys for consistent hashing
|
|
const sorted_params = {};
|
|
Object.keys(params).sort().forEach(key => {
|
|
sorted_params[key] = params[key];
|
|
});
|
|
return `${controller}::${action}::${JSON.stringify(sorted_params)}`;
|
|
}
|
|
|
|
/**
|
|
* Extract error message from jQuery XHR object
|
|
* @private
|
|
*/
|
|
static _extract_error_message(xhr) {
|
|
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
return xhr.responseJSON.message;
|
|
} else if (xhr.responseText) {
|
|
try {
|
|
const response = JSON.parse(xhr.responseText);
|
|
if (response.message) {
|
|
return response.message;
|
|
}
|
|
} catch (e) {
|
|
// Not JSON
|
|
}
|
|
}
|
|
return `${xhr.status}: ${xhr.statusText || 'Unknown error'}`;
|
|
}
|
|
|
|
/**
|
|
* Parses an AJAX URL into controller and action
|
|
* Supports both /_ajax/ and /_/ URL prefixes
|
|
* @param {string|object|function} url - URL in format '/_ajax/Controller_Name/action_name' or '/_/Controller_Name/action_name', or an object/function with a .path property
|
|
* @returns {Object} Object with {controller: string, action: string}
|
|
* @throws {Error} If URL doesn't start with /_ajax or /_ or has invalid structure
|
|
*/
|
|
static ajax_url_to_controller_action(url) {
|
|
// If url is an object or function with a .path property, use that as the URL
|
|
if (url && typeof url === 'object' && url.path) {
|
|
url = url.path;
|
|
} else if (url && typeof url === 'function' && url.path) {
|
|
url = url.path;
|
|
}
|
|
|
|
// Validate url is a string
|
|
if (typeof url !== 'string') {
|
|
throw new Error(`URL must be a string or have a .path property, got: ${typeof url}`);
|
|
}
|
|
if (!url.startsWith('/_ajax') && !url.startsWith('/_/')) {
|
|
throw new Error(`URL must start with /_ajax or /_, got: ${url}`);
|
|
}
|
|
const parts = url.split('/').filter(part => part !== '');
|
|
if (parts.length < 2) {
|
|
throw new Error(`Invalid AJAX URL structure: ${url}`);
|
|
}
|
|
if (parts.length > 3) {
|
|
throw new Error(`AJAX URL has too many segments: ${url}`);
|
|
}
|
|
const controller = parts[1];
|
|
const action = parts[2] || 'index';
|
|
return {
|
|
controller,
|
|
action
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Auto-initialize static properties when class is first loaded
|
|
*/
|
|
static on_core_define() {
|
|
Ajax._on_framework_core_init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Integrations/Jqhtml/Component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Component - Base class for JQHTML components in RSX framework
|
|
*
|
|
* This class wraps the jqhtml.Component from the npm package and provides
|
|
* the standard interface for RSX components following the Upper_Case naming convention.
|
|
*
|
|
* _Base_Jqhtml_Component is imported from npm via Jqhtml_Bundle.
|
|
*
|
|
* @Instantiatable
|
|
*/
|
|
class Component extends _Base_Jqhtml_Component {}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === app/RSpade/Integrations/Jqhtml/Jqhtml_Integration.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* JQHTML Integration - Automatic component registration and binding
|
|
*
|
|
* This module automatically:
|
|
* 1. Registers component classes that extend Component
|
|
* 2. Binds templates to component classes when names match
|
|
* 3. Enables $(selector).component("Component_Name") syntax
|
|
*/
|
|
class Jqhtml_Integration {
|
|
/**
|
|
* Compiled Jqhtml templates self-register. The developer (the framework in this case) is still
|
|
* responsible for registering es6 component classes with jqhtml. This does so at an early stage
|
|
* of framework init.
|
|
*/
|
|
static _on_framework_modules_define() {
|
|
let jqhtml_components = Manifest.get_extending('Component');
|
|
console_debug('JQHTML_INIT', 'Registering ' + jqhtml_components.length + ' Jqhtml Components');
|
|
for (let component of jqhtml_components) {
|
|
jqhtml.register_component(component.class_name, component.class_object);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Framework modules init phase - Bind components and initialize DOM
|
|
* This runs after templates are registered to bind component classes
|
|
* @param {jQuery} [$scope] Optional scope to search within (defaults to body)
|
|
* @returns {Array<Promise>|undefined} Array of promises for recursive calls, undefined for top-level
|
|
*/
|
|
static _on_framework_modules_init($scope) {
|
|
const is_top_level = !$scope;
|
|
const promises = [];
|
|
const components_needing_init = ($scope || $('body')).find('.Component_Init');
|
|
if (components_needing_init.length > 0) {
|
|
console_debug('JQHTML_INIT', `Initializing ${components_needing_init.length} DOM components`);
|
|
}
|
|
components_needing_init.each(function () {
|
|
const $element = $(this);
|
|
|
|
// Skip if element is no longer attached to the document
|
|
// (may have been removed by a parent component's .empty() call)
|
|
if (!document.contains($element[0])) {
|
|
return;
|
|
}
|
|
|
|
// Check if any parent has Component_Init class - skip nested components
|
|
let parent = $element[0].parentElement;
|
|
while (parent) {
|
|
if (parent.classList.contains('Component_Init')) {
|
|
return; // Skip this element, it's nested
|
|
}
|
|
parent = parent.parentElement;
|
|
}
|
|
const component_name = $element.attr('data-component-init-name');
|
|
|
|
// jQuery's .data() doesn't auto-parse JSON - we need to parse it manually
|
|
let component_args = {};
|
|
const args_string = $element.attr('data-component-args');
|
|
|
|
// Unset component- php side initialization args, it is no longer needed as a compionent attribute
|
|
// Unsetting also prevents undesired access to this code in other parts of the program, prevening an
|
|
// unwanted future dependency on this paradigm
|
|
$element.removeAttr('data-component-init-name');
|
|
$element.removeAttr('data-component-args');
|
|
$element.removeData('component-init-name');
|
|
$element.removeData('component-args');
|
|
if (args_string) {
|
|
try {
|
|
component_args = JSON.parse(args_string);
|
|
} catch (e) {
|
|
console.error(`[JQHTML Integration] Failed to parse component args for ${component_name}:`, e);
|
|
component_args = {};
|
|
}
|
|
}
|
|
if (component_name) {
|
|
// Transform $ prefixed keys to data- attributes
|
|
let component_args_filtered = {};
|
|
for (const [key, value] of Object.entries(component_args)) {
|
|
// if (key.startsWith('$')) {
|
|
// component_args_filtered[key.substring(1)] = value;
|
|
// } else
|
|
if (key.startsWith('data-')) {
|
|
component_args_filtered[key.substring(5)] = value;
|
|
} else {
|
|
component_args_filtered[key] = value;
|
|
}
|
|
}
|
|
try {
|
|
// Store inner HTML as string for nested component processing
|
|
component_args_filtered._inner_html = $element.html();
|
|
$element.empty();
|
|
|
|
// Remove the init class before instantiation to prevent re-initialization
|
|
$element.removeClass('Component_Init');
|
|
|
|
// Create promise for this component's initialization
|
|
const component_promise = new Promise(resolve => {
|
|
// Use jQuery component plugin to create the component
|
|
// Plugin handles element internally, just pass args
|
|
// Get the updated $element from
|
|
let component = $element.component(component_name, component_args_filtered);
|
|
component.on('render', function () {
|
|
// Recursively collect promises from nested components
|
|
|
|
// Getting the updated component here - if the tag name was not div, the element would have been recreated, so we need to get the element set on the component, not from our earlier selector
|
|
|
|
const nested_promises = Jqhtml_Integration._on_framework_modules_init(component.$);
|
|
promises.push(...nested_promises);
|
|
|
|
// Resolve this component's promise
|
|
resolve();
|
|
}).$;
|
|
});
|
|
promises.push(component_promise);
|
|
} catch (error) {
|
|
console.error(`[JQHTML Integration] Failed to initialize component ${component_name}:`, error);
|
|
console.error('Error details:', error.stack || error);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Top-level call: spawn async handler to wait for all promises, then trigger event
|
|
if (is_top_level) {
|
|
(async () => {
|
|
await Promise.all(promises);
|
|
await Rsx._rsx_call_all_classes('on_jqhtml_ready');
|
|
Rsx.trigger('jqhtml_ready');
|
|
})();
|
|
return;
|
|
}
|
|
|
|
// Recursive call: return promises for parent to collect
|
|
return promises;
|
|
}
|
|
|
|
/**
|
|
* Get all registered component names
|
|
* @returns {Array<string>} Array of component names
|
|
*/
|
|
static get_component_names() {
|
|
return jqhtml.get_component_names();
|
|
}
|
|
|
|
/**
|
|
* Check if a component is registered
|
|
* @param {string} name Component name
|
|
* @returns {boolean} True if component is registered
|
|
*/
|
|
static has_component(name) {
|
|
return jqhtml.has_component(name);
|
|
}
|
|
}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === rsx/app/dev/modals/test_modal_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Test_Modal_Form
|
|
*
|
|
* Simple test form component demonstrating modal form functionality.
|
|
*/
|
|
class Test_Modal_Form extends Component {
|
|
on_create() {
|
|
// Initialize with provided data or empty object
|
|
this.data.values = this.args.data || {};
|
|
}
|
|
on_ready() {
|
|
// Set initial values if provided
|
|
if (this.data.values) {
|
|
this.vals(this.data.values);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set form values
|
|
* @param {Object} values - Optional values to set
|
|
* @returns {Object|null} Returns values if getting, null if setting
|
|
*/
|
|
vals(values) {
|
|
if (values) {
|
|
// Setter
|
|
if (values.name !== undefined) {
|
|
this.$sid('name_input').val(values.name);
|
|
}
|
|
if (values.email !== undefined) {
|
|
this.$sid('email_input').val(values.email);
|
|
}
|
|
if (values.role !== undefined) {
|
|
this.$sid('role_select').val(values.role);
|
|
}
|
|
return null;
|
|
} else {
|
|
// Getter
|
|
return {
|
|
name: this.$sid('name_input').val(),
|
|
email: this.$sid('email_input').val(),
|
|
role: this.$sid('role_select').val()
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/dev/modals/dev_modals.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dev_Modals {
|
|
static on_app_ready() {
|
|
if (!$('.Dev_Modals').exists()) return;
|
|
Dev_Modals.init();
|
|
}
|
|
static init() {
|
|
// Simple Dialogs
|
|
$('#test-alert').on('click', async () => {
|
|
await Modal.alert('This is a simple alert message');
|
|
Dev_Modals.show_result('simple', 'Alert acknowledged');
|
|
});
|
|
$('#test-alert-title').on('click', async () => {
|
|
await Modal.alert('Custom Title', 'This alert has a custom title');
|
|
Dev_Modals.show_result('simple', 'Alert with title acknowledged');
|
|
});
|
|
$('#test-confirm').on('click', async () => {
|
|
const result = await Modal.confirm('Are you sure you want to proceed?');
|
|
Dev_Modals.show_result('simple', `Confirm result: ${result}`);
|
|
});
|
|
$('#test-confirm-title').on('click', async () => {
|
|
const result = await Modal.confirm('Delete Item', 'Are you sure you want to delete this item?');
|
|
Dev_Modals.show_result('simple', `Confirm with title result: ${result}`);
|
|
});
|
|
$('#test-prompt').on('click', async () => {
|
|
const result = await Modal.prompt('What is your name?');
|
|
Dev_Modals.show_result('simple', `Prompt result: ${result === false ? 'Cancelled' : result}`);
|
|
});
|
|
$('#test-prompt-default').on('click', async () => {
|
|
const result = await Modal.prompt('Enter your email:', null, 'user@example.com');
|
|
Dev_Modals.show_result('simple', `Prompt with default result: ${result === false ? 'Cancelled' : result}`);
|
|
});
|
|
$('#test-prompt-multiline').on('click', async () => {
|
|
const result = await Modal.prompt('Enter your feedback:', null, 'Type your feedback here...', true);
|
|
Dev_Modals.show_result('simple', `Multiline prompt result: ${result === false ? 'Cancelled' : result}`);
|
|
});
|
|
$('#test-prompt-rich').on('click', async () => {
|
|
// Create rich formatted content above the input
|
|
const $rich_content = $('<div>').append($('<h5 style="color: #2c3e50; margin-bottom: 15px;">').text('User Registration Form')).append($('<p style="margin-bottom: 10px;">').html('Please enter your <strong style="color: #e74c3c;">full name</strong> as it appears on your ' + '<em style="color: #3498db;">official documents</em>.')).append($('<p style="margin-bottom: 10px;">').html('<span style="text-decoration: underline; color: #27ae60;">Required fields</span> must be completed before submission.')).append($('<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin-bottom: 20px;">').html('<strong>⚠ Note:</strong> <span style="font-size: 14px;">Your name will be used for all official correspondence.</span>')).append($('<p style="font-size: 13px; color: #7f8c8d; margin-bottom: 25px;">').text('Example: John Michael Smith'));
|
|
const result = await Modal.prompt($rich_content, null, '', false);
|
|
Dev_Modals.show_result('simple', `Rich text prompt result: ${result === false ? 'Cancelled' : result}`);
|
|
});
|
|
$('#test-prompt-validation').on('click', async () => {
|
|
// Demonstrate validation pattern: keep reopening until valid or cancelled
|
|
let email = '';
|
|
let error = null;
|
|
let valid = false;
|
|
while (!valid) {
|
|
email = await Modal.prompt('Email Validation', 'Please enter a valid email address:', email, false, error);
|
|
|
|
// User cancelled
|
|
if (email === false) {
|
|
Dev_Modals.show_result('simple', 'Prompt cancelled');
|
|
return;
|
|
}
|
|
|
|
// Validate email (simple check)
|
|
if (!email || email.trim() === '') {
|
|
error = 'Email address is required';
|
|
} else if (!email.includes('@') || !email.includes('.')) {
|
|
error = 'Please enter a valid email address (must contain @ and .)';
|
|
} else if (email.length < 5) {
|
|
error = 'Email address is too short';
|
|
} else {
|
|
// Valid!
|
|
valid = true;
|
|
}
|
|
}
|
|
Dev_Modals.show_result('simple', `Valid email entered: ${email}`);
|
|
});
|
|
|
|
// Custom Modals
|
|
$('#test-custom-2btn').on('click', async () => {
|
|
const result = await Modal.show({
|
|
title: 'Custom Two Button Modal',
|
|
body: 'This modal has two custom buttons with different values',
|
|
buttons: [{
|
|
label: 'Option A',
|
|
value: 'option_a',
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: 'Option B',
|
|
value: 'option_b',
|
|
class: 'btn-primary',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('custom', `Two button result: ${result}`);
|
|
});
|
|
$('#test-custom-3btn').on('click', async () => {
|
|
const result = await Modal.show({
|
|
title: 'Three Button Modal',
|
|
body: 'Choose one of three options',
|
|
buttons: [{
|
|
label: 'Cancel',
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: 'Save Draft',
|
|
value: 'draft',
|
|
class: 'btn-info'
|
|
}, {
|
|
label: 'Publish',
|
|
value: 'publish',
|
|
class: 'btn-success',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('custom', `Three button result: ${result}`);
|
|
});
|
|
$('#test-custom-danger').on('click', async () => {
|
|
const result = await Modal.show({
|
|
title: 'Dangerous Action',
|
|
body: 'This action cannot be undone. Are you absolutely sure?',
|
|
buttons: [{
|
|
label: 'Cancel',
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: 'Delete Forever',
|
|
value: true,
|
|
class: 'btn-danger',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('custom', `Dangerous action result: ${result}`);
|
|
});
|
|
$('#test-custom-jquery').on('click', async () => {
|
|
const $content = $('<div>').append($('<p>').text('This modal body contains jQuery elements')).append($('<ul>').append($('<li>').text('First item')).append($('<li>').text('Second item')).append($('<li>').text('Third item'))).append($('<p>').html('<strong>Formatted text</strong> and <em>styling</em>'));
|
|
const result = await Modal.show({
|
|
title: 'jQuery Content',
|
|
body: $content,
|
|
buttons: [{
|
|
label: 'Close',
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('custom', 'jQuery content modal closed');
|
|
});
|
|
$('#test-custom-wide').on('click', async () => {
|
|
const result = await Modal.show({
|
|
title: 'Wide Modal (1200px)',
|
|
body: 'This modal has a max width of 1200px, useful for forms or data tables that need more horizontal space.',
|
|
max_width: 1200,
|
|
buttons: [{
|
|
label: 'Close',
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('custom', 'Wide modal closed');
|
|
});
|
|
|
|
// Special Behaviors
|
|
$('#test-unclosable').on('click', async () => {
|
|
Modal.unclosable('Processing', 'Please wait while we process your request...');
|
|
|
|
// Simulate processing
|
|
setTimeout(async () => {
|
|
await Modal.close();
|
|
Dev_Modals.show_result('special', 'Unclosable modal was closed programmatically after 3 seconds');
|
|
}, 3000);
|
|
});
|
|
$('#test-queue').on('click', async () => {
|
|
// Queue 3 modals
|
|
const promise1 = Modal.alert('First Modal', 'This is the first modal in the queue');
|
|
const promise2 = Modal.alert('Second Modal', 'This is the second modal in the queue');
|
|
const promise3 = Modal.alert('Third Modal', 'This is the third and final modal');
|
|
await Promise.all([promise1, promise2, promise3]);
|
|
Dev_Modals.show_result('special', 'All 3 queued modals completed');
|
|
});
|
|
$('#test-error').on('click', async () => {
|
|
const error_obj = {
|
|
message: 'An error occurred while processing your request'
|
|
};
|
|
await Modal.error(error_obj, 'Error');
|
|
Dev_Modals.show_result('special', 'Error modal shown');
|
|
});
|
|
$('#test-tall').on('click', async () => {
|
|
let tall_content = '<h6>Scrollable Content</h6>';
|
|
for (let i = 1; i <= 50; i++) {
|
|
tall_content += `<p>Paragraph ${i}: This is a long paragraph that helps demonstrate scrolling behavior when content exceeds the 80% viewport height threshold.</p>`;
|
|
}
|
|
const result = await Modal.show({
|
|
title: 'Tall Content (Scrolling Test)',
|
|
body: tall_content,
|
|
buttons: [{
|
|
label: 'Close',
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}]
|
|
});
|
|
Dev_Modals.show_result('special', 'Tall content modal closed');
|
|
});
|
|
|
|
// Form Modals
|
|
$('#test-form-simple').on('click', async () => {
|
|
const result = await Modal.form({
|
|
title: 'User Registration',
|
|
component: 'Test_Modal_Form',
|
|
on_submit: async form => {
|
|
// Get form values
|
|
const values = form.vals();
|
|
|
|
// Simple validation - just check required fields
|
|
if (!values.name || !values.email || !values.role) {
|
|
Form_Utils.apply_form_errors(form.$, 'Please fill in all required fields');
|
|
return false; // Keep modal open
|
|
}
|
|
|
|
// Simulate saving
|
|
await sleep(500);
|
|
|
|
// Return data to close modal
|
|
return values;
|
|
}
|
|
});
|
|
if (result) {
|
|
Dev_Modals.show_result('form', `Form submitted: ${json_encode(result)}`);
|
|
} else {
|
|
Dev_Modals.show_result('form', 'Form cancelled');
|
|
}
|
|
});
|
|
$('#test-form-validation').on('click', async () => {
|
|
const result = await Modal.form({
|
|
title: 'User Registration (With Server Validation)',
|
|
component: 'Test_Modal_Form',
|
|
on_submit: async form => {
|
|
// Get form values
|
|
const values = form.vals();
|
|
|
|
// Simulate server-side validation
|
|
await sleep(500);
|
|
|
|
// Simulate validation errors
|
|
const errors = {};
|
|
if (!values.name || values.name.length < 3) {
|
|
errors.name = 'Name must be at least 3 characters';
|
|
}
|
|
if (!values.email || !values.email.includes('@')) {
|
|
errors.email = 'Please enter a valid email address';
|
|
}
|
|
if (!values.role) {
|
|
errors.role = 'Please select a role';
|
|
}
|
|
|
|
// If there are errors, show them and keep modal open
|
|
if (Object.keys(errors).length > 0) {
|
|
Form_Utils.apply_form_errors(form.$, errors);
|
|
return false; // Keep modal open
|
|
}
|
|
|
|
// Success - return data
|
|
return values;
|
|
}
|
|
});
|
|
if (result) {
|
|
Dev_Modals.show_result('form', `Form submitted successfully: ${json_encode(result)}`);
|
|
} else {
|
|
Dev_Modals.show_result('form', 'Form cancelled');
|
|
}
|
|
});
|
|
$('#test-form-prefilled').on('click', async () => {
|
|
const result = await Modal.form({
|
|
title: 'Edit User Profile',
|
|
component: 'Test_Modal_Form',
|
|
component_args: {
|
|
data: {
|
|
name: 'John Smith',
|
|
email: 'john.smith@example.com',
|
|
role: 'manager'
|
|
}
|
|
},
|
|
submit_label: 'Update',
|
|
on_submit: async form => {
|
|
const values = form.vals();
|
|
|
|
// Simple validation
|
|
if (!values.name || !values.email || !values.role) {
|
|
await Modal.alert('Please fill in all required fields');
|
|
return false;
|
|
}
|
|
|
|
// Simulate update
|
|
await sleep(500);
|
|
return values;
|
|
}
|
|
});
|
|
if (result) {
|
|
Dev_Modals.show_result('form', `Profile updated: ${json_encode(result)}`);
|
|
} else {
|
|
Dev_Modals.show_result('form', 'Update cancelled');
|
|
}
|
|
});
|
|
$('#test-form-pin').on('click', async () => {
|
|
const result = await Modal.form({
|
|
title: 'Enter Verification Code',
|
|
component: 'Pin_Verification_Form',
|
|
submit_label: 'Verify',
|
|
max_width: 450,
|
|
on_submit: async form => {
|
|
const pin = form.val();
|
|
|
|
// Validate PIN is complete
|
|
if (pin.length !== 6) {
|
|
Form_Utils.apply_form_errors(form.$, 'Please enter all 6 digits');
|
|
return false;
|
|
}
|
|
|
|
// Simulate PIN verification
|
|
await sleep(800);
|
|
|
|
// Simulate checking against correct PIN
|
|
const correct_pin = '123456';
|
|
if (pin !== correct_pin) {
|
|
Form_Utils.apply_form_errors(form.$, `Incorrect PIN. (Hint: try ${correct_pin})`);
|
|
// Clear the PIN and refocus first input
|
|
form.val('');
|
|
return false;
|
|
}
|
|
|
|
// Success
|
|
return {
|
|
pin: pin,
|
|
verified: true
|
|
};
|
|
}
|
|
});
|
|
if (result) {
|
|
Dev_Modals.show_result('form', `PIN verified successfully: ${result.pin}`);
|
|
} else {
|
|
Dev_Modals.show_result('form', 'PIN verification cancelled');
|
|
}
|
|
});
|
|
|
|
// Modal State
|
|
$('#check-state').on('click', () => {
|
|
const state = {
|
|
is_open: Modal.is_open(),
|
|
current_modal: Modal.get_current() !== null ? 'Modal instance exists' : null
|
|
};
|
|
const formatted = json_encode(state, null, 2);
|
|
$('#state-result').show();
|
|
$('#state-result-text').text(formatted);
|
|
});
|
|
$('#force-close').on('click', async () => {
|
|
if (Modal.is_open()) {
|
|
await Modal.close();
|
|
Dev_Modals.show_result('special', 'Modal was force closed');
|
|
} else {
|
|
Dev_Modals.show_result('special', 'No modal is currently open');
|
|
}
|
|
});
|
|
}
|
|
static show_result(section, message) {
|
|
const $result = $(`#${section}-result`);
|
|
const $text = $(`#${section}-result-text`);
|
|
$text.text(message);
|
|
$result.show();
|
|
|
|
// Hide after 5 seconds
|
|
setTimeout(() => {
|
|
$result.fadeOut();
|
|
}, 5000);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/dev/attachments/dev_attachments.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dev_Attachments {
|
|
static init() {
|
|
if (!$(".Dev_Attachments").exists()) return;
|
|
console.log('Dev_Attachments initialized');
|
|
|
|
// Handle upload button click - trigger hidden file input
|
|
$('#basic-upload-btn').on('click', function () {
|
|
$('#basic-upload-input').click();
|
|
});
|
|
|
|
// Handle file selection
|
|
$('#basic-upload-input').on('change', e => {
|
|
const file = e.target.files[0];
|
|
if (!file) return;
|
|
|
|
// Update status
|
|
$('#upload-status').text(file.name);
|
|
|
|
// Upload the file
|
|
Dev_Attachments.upload_image(file);
|
|
});
|
|
}
|
|
static upload_image(file) {
|
|
// Show spinner on profile image only
|
|
$('#spinner-profile').removeClass('d-none');
|
|
$('#thumb-profile').css('opacity', '0.3');
|
|
|
|
// Create FormData for file upload
|
|
const form_data = new FormData();
|
|
form_data.append('file', file);
|
|
form_data.append('site_id', '1');
|
|
form_data.append('fileable_type', 'dev_test');
|
|
form_data.append('fileable_category', 'attachment_demo');
|
|
|
|
// Upload file via AJAX
|
|
$.ajax({
|
|
url: '/_upload',
|
|
type: 'POST',
|
|
data: form_data,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function (response) {
|
|
console.log('Upload successful!');
|
|
console.log('Response:', response);
|
|
console.log('File key:', response.attachment.key);
|
|
|
|
// Show thumbnails container
|
|
$('#thumbnails-container').removeClass('d-none');
|
|
|
|
// Generate thumbnail URLs
|
|
const key = response.attachment.key;
|
|
const extension = response.attachment.file_extension;
|
|
$('#thumb-profile').attr('src', `/_thumbnail/${key}/cover/96/96`);
|
|
$('#thumb-200').attr('src', `/_thumbnail/${key}/cover/200/200`);
|
|
$('#thumb-240x180').attr('src', `/_thumbnail/${key}/cover/240/180`);
|
|
|
|
// Use icon endpoint for file type icon
|
|
$('#thumb-icon').attr('src', `/_icon_by_extension/${extension}?width=100&height=100`);
|
|
|
|
// Set download/inline URLs
|
|
$('#btn-view-inline').attr('href', `/_inline/${key}`);
|
|
$('#btn-view-download').attr('href', `/_download/${key}`);
|
|
|
|
// Hide spinner, restore opacity
|
|
$('#spinner-profile').addClass('d-none');
|
|
$('#thumb-profile').css('opacity', '1');
|
|
|
|
// Clear file input for future uploads
|
|
$('#basic-upload-input').val('');
|
|
$('#upload-status').html(`<span class="text-success"><i class="bi bi-check-circle"></i> Upload complete!</span>`);
|
|
},
|
|
error: function (xhr, status, error) {
|
|
var _xhr$responseJSON;
|
|
console.error('Upload failed:', error);
|
|
console.error('Response:', xhr.responseJSON);
|
|
|
|
// Hide spinner, restore opacity
|
|
$('#spinner-profile').addClass('d-none');
|
|
$('#thumb-profile').css('opacity', '1');
|
|
|
|
// Clear file input
|
|
$('#basic-upload-input').val('');
|
|
$('#upload-status').html(`<span class="text-danger"><i class="bi bi-x-circle"></i> Upload failed</span>`);
|
|
|
|
// Show error to user
|
|
alert('Upload failed: ' + (((_xhr$responseJSON = xhr.responseJSON) === null || _xhr$responseJSON === void 0 ? void 0 : _xhr$responseJSON.error) || error));
|
|
}
|
|
});
|
|
}
|
|
static on_app_ready() {
|
|
Dev_Attachments.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/dev/dev_index.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dev_Index {
|
|
static init() {
|
|
if (!$(".Dev_Index").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Dev_Index initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Dev_Index.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/datagrid/datagrid_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* DataGrid Component (Phase 1)
|
|
*
|
|
* Due to the more dynamic nature of this component, we are handling load / render lifecycles
|
|
* directly in this class rather than using the on_load lifecycle event
|
|
*
|
|
* **Features**:
|
|
* - Ajax data fetching
|
|
* - Sorting (click headers)
|
|
* - Pagination (next/prev/page select)
|
|
* - Row selection (checkboxes)
|
|
* - CSV export (selected rows, current page)
|
|
* - URL state synchronization
|
|
*
|
|
* **Usage**:
|
|
* ```html
|
|
* <Contacts_DataGrid $api="Frontend_Contacts_Controller" />
|
|
* ```
|
|
*
|
|
* **Required Args**:
|
|
* - `api` - Controller class name with datagrid_fetch() Ajax endpoint
|
|
*
|
|
* **Optional Args**:
|
|
* - `per_page` - Default rows per page (default: 25)
|
|
* - `sort` - Default sort column (default: first column)
|
|
* - `order` - Default sort order (default: 'asc')
|
|
*/
|
|
class DataGrid_Abstract extends Component {
|
|
// Initialize data before first render
|
|
on_create() {
|
|
let that = this;
|
|
|
|
// Initialize data state immediately so template can render
|
|
that.data.rows = [];
|
|
that.data.loading = true;
|
|
that.data.is_empty = false;
|
|
that.data.loaded = false;
|
|
that.data.total_pages = 0;
|
|
}
|
|
|
|
// Calls when datagrid first initialized
|
|
async on_ready() {
|
|
var _that$args$per_page, _that$args$sort, _that$args$order;
|
|
let that = this;
|
|
if (!that.args.data_source) {
|
|
console.error('Datagrid ' + that.component_name() + ' requires args.data_source set to a Ajax_Endpoint object');
|
|
return;
|
|
}
|
|
|
|
// Store defaults for later comparison
|
|
that.data.default_page = 1;
|
|
that.data.default_per_page = (_that$args$per_page = that.args.per_page) !== null && _that$args$per_page !== void 0 ? _that$args$per_page : 15;
|
|
that.data.default_sort = (_that$args$sort = that.args.sort) !== null && _that$args$sort !== void 0 ? _that$args$sort : null;
|
|
that.data.default_order = (_that$args$order = that.args.order) !== null && _that$args$order !== void 0 ? _that$args$order : 'asc';
|
|
that.data.default_filter = '';
|
|
|
|
// Set configured values
|
|
that.data.per_page = that.data.default_per_page;
|
|
|
|
// Initialize state from URL hash if present, otherwise use defaults
|
|
const hash_page = Rsx.get_page_state(that._cid + '_page');
|
|
const hash_sort = Rsx.get_page_state(that._cid + '_sort');
|
|
const hash_order = Rsx.get_page_state(that._cid + '_order');
|
|
const hash_filter = Rsx.get_page_state(that._cid + '_filter');
|
|
that.data.page = hash_page ? int(hash_page) : that.data.default_page;
|
|
that.data.sort = hash_sort || that.data.default_sort;
|
|
that.data.order = hash_order || that.data.default_order;
|
|
that.data.filter = hash_filter || that.data.default_filter;
|
|
that.register_render_callbacks();
|
|
that.register_filter_handlers();
|
|
|
|
// If hash had a filter value, populate the filter input
|
|
if (that.data.filter) {
|
|
const $filter = that.$sid('filter_input');
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.val(that.data.filter);
|
|
}
|
|
}
|
|
|
|
// Measure row height and set fixed tbody height (all in one frame)
|
|
await that.measure_and_set_fixed_height();
|
|
|
|
// Fetch the initial page (respects hash state)
|
|
that.load_page(that.data.page);
|
|
}
|
|
|
|
// Update header only if sort/order changed
|
|
update_header() {
|
|
let that = this;
|
|
|
|
// Track last rendered state
|
|
if (!that._last_header_state) {
|
|
that._last_header_state = {};
|
|
}
|
|
const current = {
|
|
sort: that.data.sort,
|
|
order: that.data.order
|
|
};
|
|
|
|
// Only render if values changed
|
|
if (that._last_header_state.sort !== current.sort || that._last_header_state.order !== current.order) {
|
|
that._last_header_state = current;
|
|
that.id('datagrid_table_header').render();
|
|
}
|
|
}
|
|
|
|
// Update pagination only if values changed
|
|
update_pagination() {
|
|
let that = this;
|
|
|
|
// Track last rendered state
|
|
if (!that._last_pagination_state) {
|
|
that._last_pagination_state = {};
|
|
}
|
|
const current = {
|
|
page: that.data.page,
|
|
per_page: that.data.per_page,
|
|
total: that.data.total,
|
|
total_pages: that.data.total_pages
|
|
};
|
|
|
|
// Only render if values changed
|
|
if (that._last_pagination_state.page !== current.page || that._last_pagination_state.per_page !== current.per_page || that._last_pagination_state.total !== current.total || that._last_pagination_state.total_pages !== current.total_pages) {
|
|
that._last_pagination_state = current;
|
|
that.id('pagination_info').render();
|
|
that.id('pagination_controls').render();
|
|
}
|
|
}
|
|
|
|
// Load data for specified page and re-render data
|
|
async load_page(page) {
|
|
let that = this;
|
|
|
|
// Set loading state
|
|
that.data.loading = true;
|
|
that.data.page = page;
|
|
|
|
// Update UI with requested values (optimistic update)
|
|
that.update_header();
|
|
that.update_pagination();
|
|
|
|
// Only render loading state if no data yet (initial load)
|
|
if (that.data.rows.length === 0) {
|
|
that.id('datagrid_table_body').render();
|
|
}
|
|
const response = await Ajax.call(that.args.data_source, {
|
|
page: page,
|
|
per_page: that.data.per_page,
|
|
sort: that.data.sort,
|
|
order: that.data.order,
|
|
filter: that.data.filter
|
|
});
|
|
|
|
// Update data
|
|
that.data.loading = false;
|
|
that.data.loaded = true;
|
|
that.data.rows = response.records;
|
|
that.data.page = response.page;
|
|
that.data.per_page = response.per_page;
|
|
that.data.total = response.total;
|
|
that.data.total_pages = response.total_pages;
|
|
that.data.sort = response.sort;
|
|
that.data.order = response.order;
|
|
that.data.is_empty = response.records.length === 0;
|
|
|
|
// Persist state to URL hash for bookmarking/sharing
|
|
// Only set values that differ from defaults (null removes the key)
|
|
const state = {};
|
|
state[that._cid + '_page'] = that.data.page !== that.data.default_page ? that.data.page : null;
|
|
state[that._cid + '_sort'] = that.data.sort !== that.data.default_sort ? that.data.sort : null;
|
|
state[that._cid + '_order'] = that.data.order !== that.data.default_order ? that.data.order : null;
|
|
state[that._cid + '_filter'] = that.data.filter !== that.data.default_filter ? that.data.filter : null;
|
|
Rsx.set_all_page_state(state);
|
|
|
|
// Update UI with server response (only renders if changed)
|
|
that.id('datagrid_table_body').render();
|
|
that.update_header();
|
|
that.update_pagination();
|
|
|
|
// Scroll to top of datagrid if it's not currently visible
|
|
that.scroll_to_top_if_needed();
|
|
}
|
|
|
|
// The callbacks in this function fire after each targeted component re-renders
|
|
register_render_callbacks() {
|
|
let that = this;
|
|
|
|
// Attach row click handler - re-runs every time datagrid_table_body renders
|
|
that.id('datagrid_table_body').on('render', function () {
|
|
console.log('DGTB_R');
|
|
// Step 1: Wrap cells in data-href rows with anchor tags
|
|
$(this).find('tr[data-href]').each(function () {
|
|
let $row = $(this);
|
|
let href = $row.attr('data-href');
|
|
$row.find('td').each(function () {
|
|
// let $col = $(this);
|
|
// // Skip if cell already contains interactive elements
|
|
// if ($col.find('a, button, input, select, textarea').length > 0) {
|
|
// return;
|
|
// }
|
|
// // Wrap entire cell contents in an anchor (preserve DOM nodes for component lifecycle)
|
|
// let $anchor = $('<a>', {
|
|
// href: href,
|
|
// class: 'datagrid-row-link'
|
|
// });
|
|
// // Move existing child nodes into anchor (preserves components and their state)
|
|
// $col.contents().appendTo($anchor);
|
|
// // Add anchor to cell
|
|
// $col.append($anchor);
|
|
});
|
|
});
|
|
|
|
// Step 2: Find all cells with single anchor as only child and apply full-width styling
|
|
$(this).find('td').each(function () {
|
|
let $col = $(this);
|
|
let $children = $col.children();
|
|
|
|
// Check if cell contains exactly one direct child that is an anchor
|
|
if ($children.length === 1 && $children.first().is('a')) {
|
|
// Add class to transfer padding from cell to anchor
|
|
$col.addClass('has-full-link');
|
|
}
|
|
// Check if cell contains only text (no child elements)
|
|
else if ($children.length === 0) {
|
|
// Add class to apply vertical padding to text-only cells
|
|
$col.addClass('has-only-text');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Attach sortable header click handler - re-runs every time datagrid_table_header renders
|
|
that.id('datagrid_table_header').on('render', function () {
|
|
// Transform th[data-sortby] elements by wrapping contents in clickable link
|
|
$(this).find('th[data-sortby]').each(function () {
|
|
let $th = $(this);
|
|
let sortby = $th.attr('data-sortby');
|
|
|
|
// TODO: Find out why this on('render') callback is being called twice/on already-processed HTML
|
|
// This unwrap logic shouldn't be necessary - template should render fresh each time
|
|
// For now, unwrap already-wrapped content to prevent double-wrapping
|
|
let $existing_link = $th.find('a.sortable-header');
|
|
let contents;
|
|
if ($existing_link.length > 0) {
|
|
// Unwrap - get the text content without the wrapper and arrows
|
|
contents = $existing_link.clone().find('i.bi').remove().end().html();
|
|
} else {
|
|
contents = $th.html();
|
|
}
|
|
|
|
// Build the arrow icon HTML if this column is currently sorted
|
|
let arrow = '';
|
|
if (that.data.sort === sortby) {
|
|
arrow = that.data.order === 'desc' ? '<i class="bi bi-chevron-up ms-1"></i>' : '<i class="bi bi-chevron-down ms-1"></i>';
|
|
}
|
|
|
|
// Replace contents with wrapped link (fresh wrapper every time)
|
|
$th.html(`<a href="#" class="sortable-header" data-sortby="${sortby}">${contents}${arrow}</a>`);
|
|
});
|
|
|
|
// Attach click handlers to the sortable links we just created
|
|
$(this).find('a.sortable-header[data-sortby]').on('click', function (e) {
|
|
e.preventDefault();
|
|
const sortby = $(this).attr('data-sortby');
|
|
that.sort_by(sortby);
|
|
});
|
|
});
|
|
|
|
// Attach pagination click handler - re-runs every time pagination_controls renders
|
|
that.id('pagination_controls').on('render', function () {
|
|
$(this).find('.page-link').on('click', function (e) {
|
|
e.preventDefault();
|
|
const $link = $(this);
|
|
const page = int($link.attr('data-page'));
|
|
|
|
// Ignore disabled/ellipsis clicks
|
|
if (!page || isNaN(page) || $link.parent().hasClass('disabled')) {
|
|
return;
|
|
}
|
|
|
|
// Load the requested page
|
|
that.load_page(page);
|
|
});
|
|
});
|
|
|
|
// Attach clear filter button handler - re-runs every time datagrid_table_body renders
|
|
that.id('datagrid_table_body').on('render', function () {
|
|
const $clear_btn = that.$sid('clear_filter_btn');
|
|
if ($clear_btn && $clear_btn.length > 0) {
|
|
$clear_btn.on('click', function (e) {
|
|
e.preventDefault();
|
|
that.clear_filter();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Sort by specified column, toggling order if already sorted by that column
|
|
sort_by(column) {
|
|
let that = this;
|
|
|
|
// Toggle order if clicking same column, otherwise default to asc
|
|
if (that.data.sort === column) {
|
|
that.data.order = that.data.order === 'asc' ? 'desc' : 'asc';
|
|
} else {
|
|
that.data.sort = column;
|
|
that.data.order = 'asc';
|
|
}
|
|
|
|
// Reload current page with new sort
|
|
that.id('datagrid_table_header').render();
|
|
that.load_page(that.data.page);
|
|
}
|
|
|
|
// Register filter input handlers
|
|
register_filter_handlers() {
|
|
let that = this;
|
|
|
|
// Find filter input by common identifiers
|
|
let $filter = that.$sid('filter_input');
|
|
if (!$filter || $filter.length === 0) {
|
|
$filter = that.$.find('input[type="search"], input[type="text"].filter-input');
|
|
}
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.on('input keyup', function () {
|
|
const filter_value = $(this).val();
|
|
that.filter_changed(filter_value);
|
|
});
|
|
}
|
|
}
|
|
filter_changed(filter) {
|
|
let that = this;
|
|
that.data.filter = filter;
|
|
that.load_page(1);
|
|
}
|
|
|
|
// Scroll to datagrid top if the top edge is not currently visible in viewport
|
|
scroll_to_top_if_needed() {
|
|
let that = this;
|
|
const $datagrid = that.$;
|
|
const datagridTop = $datagrid.offset().top;
|
|
const scrollTop = $(window).scrollTop();
|
|
|
|
// If datagrid top is above the current viewport, scroll to show it
|
|
if (datagridTop < scrollTop) {
|
|
// If datagrid is within 300px of page top, scroll to 0
|
|
if (datagridTop <= 300) {
|
|
window.scrollTo({
|
|
top: 0,
|
|
behavior: 'instant'
|
|
});
|
|
} else {
|
|
// Scroll to 20px above datagrid
|
|
window.scrollTo({
|
|
top: datagridTop - 20,
|
|
behavior: 'instant'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Measure actual row height and set fixed tbody min-height
|
|
// All happens in one animation frame so user doesn't see it
|
|
async measure_and_set_fixed_height() {
|
|
let that = this;
|
|
|
|
// Wait for next animation frame to ensure DOM is ready
|
|
await sleep(0);
|
|
const $tbody = that.id('datagrid_table_body').$;
|
|
|
|
// Temporarily render a single measurement row
|
|
const $measurement_row = $('<tr>').css('visibility', 'hidden').html('<td>Measuring...</td>');
|
|
$tbody.append($measurement_row);
|
|
|
|
// Measure the row height
|
|
const row_height = $measurement_row.outerHeight();
|
|
|
|
// Remove measurement row
|
|
$measurement_row.remove();
|
|
|
|
// Calculate and set min-height based on per_page
|
|
const min_height = row_height * that.data.per_page;
|
|
$tbody.css('min-height', min_height + 'px');
|
|
|
|
// Store for future reference
|
|
that.data.row_height = row_height;
|
|
that.data.tbody_min_height = min_height;
|
|
}
|
|
|
|
// Clear filter and reset to page 1
|
|
clear_filter() {
|
|
let that = this;
|
|
that.data.filter = '';
|
|
|
|
// Clear the filter input
|
|
const $filter = that.$sid('filter_input');
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.val('');
|
|
}
|
|
|
|
// Reload from page 1
|
|
that.load_page(1);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Activity_Feed.js (babel) === */
|
|
"use strict";
|
|
|
|
class Activity_Feed extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.activities = await response.json();
|
|
} else if (this.args.activities) {
|
|
this.data.activities = this.args.activities;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Optional: Auto-refresh
|
|
if (this.args.auto_refresh) {
|
|
this.start_auto_refresh();
|
|
}
|
|
}
|
|
start_auto_refresh() {
|
|
const interval = this.args.refresh_interval || 30000; // Default 30 seconds
|
|
|
|
this.refresh_timer = setInterval(() => {
|
|
this.reload_data();
|
|
}, interval);
|
|
}
|
|
stop_auto_refresh() {
|
|
if (this.refresh_timer) {
|
|
clearInterval(this.refresh_timer);
|
|
this.refresh_timer = null;
|
|
}
|
|
}
|
|
async reload_data() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.activities = await response.json();
|
|
this.render();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Actor_Reference.js (babel) === */
|
|
"use strict";
|
|
|
|
class Actor_Reference extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Advanced_Search_Panel.js (babel) === */
|
|
"use strict";
|
|
|
|
class Advanced_Search_Panel extends Component {
|
|
on_ready() {
|
|
// Populate dropdowns if provided
|
|
if (this.args.categories) {
|
|
this.$sid('category').set_options(this.args.categories);
|
|
}
|
|
if (this.args.tags) {
|
|
this.$sid('tags').set_options(this.args.tags);
|
|
}
|
|
|
|
// Search button
|
|
this.$sid('search_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
|
|
// Reset button
|
|
this.$sid('reset_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.reset();
|
|
});
|
|
|
|
// Close button
|
|
this.$sid('close_btn').on('click', () => {
|
|
if (this.args.on_close) {
|
|
this.args.on_close();
|
|
} else {
|
|
this.$.hide();
|
|
}
|
|
});
|
|
|
|
// Form submit
|
|
this.$sid('search_form').on('submit', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
}
|
|
perform_search() {
|
|
const criteria = {
|
|
keywords: this.$sid('keywords').get_value(),
|
|
category: this.$sid('category').get_value(),
|
|
tags: this.$sid('tags').get_value(),
|
|
from_date: this.$sid('from_date').get_value(),
|
|
to_date: this.$sid('to_date').get_value(),
|
|
sort_by: this.$sid('sort_by').val(),
|
|
exact_match: this.$sid('exact_match').is(':checked')
|
|
};
|
|
|
|
// Remove empty values
|
|
Object.keys(criteria).forEach(key => {
|
|
if (!criteria[key] || is_array(criteria[key]) && criteria[key].length === 0) {
|
|
delete criteria[key];
|
|
}
|
|
});
|
|
if (this.args.on_search) {
|
|
this.args.on_search(criteria);
|
|
}
|
|
}
|
|
reset() {
|
|
this.$sid('keywords').set_value('');
|
|
this.$sid('category').set_value('');
|
|
this.$sid('tags').set_value([]);
|
|
this.$sid('from_date').set_value('');
|
|
this.$sid('to_date').set_value('');
|
|
this.$sid('sort_by').val('relevance');
|
|
this.$sid('exact_match').prop('checked', false);
|
|
if (this.args.on_reset) {
|
|
this.args.on_reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Alert_Banner.js (babel) === */
|
|
"use strict";
|
|
|
|
class Alert_Banner extends Component {
|
|
on_ready() {
|
|
// Apply type from args (success, danger, warning, info)
|
|
if (this.args.type) {
|
|
this.$.removeClass('alert-info').addClass(`alert-${this.args.type}`);
|
|
}
|
|
|
|
// Remove dismissible if not needed
|
|
if (this.args.dismissible === false) {
|
|
this.$.removeClass('alert-dismissible');
|
|
this.$.find('.btn-close').remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Avatar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Avatar extends Component {
|
|
on_ready() {
|
|
// Set src from args
|
|
if (this.args.src) {
|
|
this.$.attr('src', this.args.src);
|
|
}
|
|
|
|
// Set size (xs, sm, md, lg, xl)
|
|
const size = this.args.size || 'md';
|
|
const size_map = {
|
|
'xs': '24px',
|
|
'sm': '32px',
|
|
'md': '48px',
|
|
'lg': '64px',
|
|
'xl': '96px'
|
|
};
|
|
this.$.css({
|
|
'width': size_map[size],
|
|
'height': size_map[size],
|
|
'object-fit': 'cover'
|
|
});
|
|
|
|
// Alternative rendering: show initials when no image source provided
|
|
if (!this.args.src && this.args.name) {
|
|
this.show_initials(this.args.name);
|
|
}
|
|
}
|
|
show_initials(name) {
|
|
// Convert img to div with initials
|
|
const initials = name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
|
|
const $div = $('<div>').addClass('rounded-circle d-flex align-items-center justify-content-center bg-primary text-white fw-bold').css({
|
|
'width': this.$.css('width'),
|
|
'height': this.$.css('height')
|
|
}).text(initials);
|
|
this.$.replaceWith($div);
|
|
this.$ = $div;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Blockquote.js (babel) === */
|
|
"use strict";
|
|
|
|
class Blockquote extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Breadcrumbs.js (babel) === */
|
|
"use strict";
|
|
|
|
class Breadcrumbs extends Component {
|
|
// Placeholder component - currently empty in dashboard usage
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Bulk_Action_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Bulk_Action_Bar extends Component {
|
|
on_ready() {
|
|
// Clear selection on close
|
|
this.$sid('close_btn').on('click', () => {
|
|
this.$.hide();
|
|
// Uncheck all boxes
|
|
const $table = this.$.closest('.card').find('table');
|
|
$table.find('input[type="checkbox"]').prop('checked', false);
|
|
});
|
|
}
|
|
set_count(count) {
|
|
this.$.find('.count').text(count);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Bulk_Selection.js (babel) === */
|
|
"use strict";
|
|
|
|
class Bulk_Selection extends Component {
|
|
on_ready() {
|
|
const $checkbox = this.$sid('checkbox');
|
|
|
|
// Toggle all checkboxes in table body
|
|
$checkbox.on('change', e => {
|
|
const checked = e.target.checked;
|
|
const $table = this.$.closest('table');
|
|
$table.find('tbody input[type="checkbox"]').prop('checked', checked);
|
|
|
|
// Trigger update event
|
|
if (this.args.on_change) {
|
|
this.args.on_change(checked);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Group extends Component {
|
|
// Container for grouped buttons with connected borders
|
|
// Bootstrap btn-group handles all visual grouping
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_primary.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Primary extends Component {
|
|
// Primary action button - highest visual hierarchy
|
|
// Bootstrap btn-primary provides all styling
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_secondary.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Secondary extends Component {
|
|
// Secondary action button - lower prominence than primary
|
|
// Bootstrap btn-secondary provides gray color scheme
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button extends Component {
|
|
// Base button component - no special behavior needed
|
|
// Bootstrap handles all states (hover, active, focus, disabled)
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Calendar_Event.js (babel) === */
|
|
"use strict";
|
|
|
|
class Calendar_Event extends Component {
|
|
on_ready() {
|
|
if (this.args.on_click) {
|
|
this.$.on('click', () => {
|
|
this.args.on_click(this.args);
|
|
});
|
|
}
|
|
|
|
// Hover effect
|
|
this.$.on('mouseenter', () => {
|
|
this.$.addClass('shadow-sm');
|
|
});
|
|
this.$.on('mouseleave', () => {
|
|
this.$.removeClass('shadow-sm');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Calendar_Grid.js (babel) === */
|
|
"use strict";
|
|
|
|
class Calendar_Grid extends Component {
|
|
on_ready() {
|
|
this.current_date = new Date();
|
|
this.render_calendar();
|
|
this.$sid('prev_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() - 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$sid('next_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() + 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$sid('today_btn').on('click', () => {
|
|
this.current_date = new Date();
|
|
this.render_calendar();
|
|
});
|
|
}
|
|
render_calendar() {
|
|
const year = this.current_date.getFullYear();
|
|
const month = this.current_date.getMonth();
|
|
|
|
// Update title
|
|
const month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
this.$sid('month_title').text(`${month_names[month]} ${year}`);
|
|
|
|
// Get first day of month and total days
|
|
const first_day = new Date(year, month, 1).getDay();
|
|
const days_in_month = new Date(year, month + 1, 0).getDate();
|
|
const $tbody = this.$sid('calendar_body');
|
|
$tbody.empty();
|
|
let day = 1;
|
|
let $tr = null;
|
|
|
|
// Build calendar grid
|
|
for (let i = 0; i < 6; i++) {
|
|
$tr = $('<tr>');
|
|
for (let j = 0; j < 7; j++) {
|
|
const $td = $('<td>').css({
|
|
'height': '100px',
|
|
'vertical-align': 'top',
|
|
'padding': '8px'
|
|
});
|
|
if (i === 0 && j < first_day) {
|
|
// Empty cell before month starts
|
|
$td.addClass('bg-light');
|
|
} else if (day > days_in_month) {
|
|
// Empty cell after month ends
|
|
$td.addClass('bg-light');
|
|
} else {
|
|
// Day cell
|
|
const $day_num = $('<div>').addClass('fw-bold mb-2').text(day);
|
|
|
|
// Highlight today
|
|
const today = new Date();
|
|
if (day === today.getDate() && month === today.getMonth() && year === today.getFullYear()) {
|
|
$day_num.addClass('text-primary');
|
|
$td.addClass('border-primary');
|
|
}
|
|
$td.append($day_num);
|
|
|
|
// Add events for this day if provided
|
|
if (this.args.events) {
|
|
const events = this.get_events_for_date(year, month, day);
|
|
events.forEach(event => {
|
|
const $event = $('<div>').addClass('badge bg-primary text-truncate w-100 mb-1 text-start').css('cursor', 'pointer').text(event.title);
|
|
$event.on('click', () => {
|
|
if (this.args.on_event_click) {
|
|
this.args.on_event_click(event);
|
|
}
|
|
});
|
|
$td.append($event);
|
|
});
|
|
}
|
|
$td.attr('data-date', `${year}-${str(month + 1).padStart(2, '0')}-${str(day).padStart(2, '0')}`);
|
|
$td.css('cursor', 'pointer');
|
|
$td.on('click', e => {
|
|
if (this.args.on_date_click && !$(e.target).hasClass('badge')) {
|
|
this.args.on_date_click($td.attr('data-date'));
|
|
}
|
|
});
|
|
day++;
|
|
}
|
|
$tr.append($td);
|
|
}
|
|
$tbody.append($tr);
|
|
if (day > days_in_month) break;
|
|
}
|
|
}
|
|
get_events_for_date(year, month, day) {
|
|
if (!this.args.events) return [];
|
|
const date_str = `${year}-${str(month + 1).padStart(2, '0')}-${str(day).padStart(2, '0')}`;
|
|
return this.args.events.filter(event => {
|
|
return event.date === date_str;
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Card.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Card - Bootstrap 5 Content Container Component
|
|
*
|
|
* Purpose: Primary content container using Bootstrap .card class
|
|
* Design: Pure Bootstrap - border-0 with shadow for modern Volt aesthetic
|
|
*/
|
|
class Card extends Component {
|
|
// Card is a pure container component - no lifecycle methods needed
|
|
// All styling comes from Bootstrap classes: card, border-0, shadow
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Chart_Component.js (babel) === */
|
|
"use strict";
|
|
|
|
class Chart_Component extends Component {
|
|
// Placeholder component - no functionality yet
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Checkbox.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Checkbox - Bootstrap 5 Checkbox Input Component
|
|
*
|
|
* Purpose: Single checkbox for yes/no, true/false selections
|
|
* Design: Bootstrap .form-check-input styling
|
|
* Wrapper: Typically used within <div class="form-check"> for proper layout
|
|
*/
|
|
class Checkbox extends Component {
|
|
on_ready() {
|
|
// Set checked state if provided
|
|
if (this.args.checked) {
|
|
this.$.prop('checked', true);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Code_Block.js (babel) === */
|
|
"use strict";
|
|
|
|
class Code_Block extends Component {
|
|
on_ready() {
|
|
// No special behavior (syntax highlighting could be added later)
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Column_Visibility_Toggle.js (babel) === */
|
|
"use strict";
|
|
|
|
class Column_Visibility_Toggle extends Component {
|
|
on_ready() {
|
|
// Build column checkboxes
|
|
if (this.args.columns) {
|
|
this.build_menu(this.args.columns);
|
|
}
|
|
}
|
|
build_menu(columns) {
|
|
const $menu = this.$sid('menu');
|
|
$menu.empty();
|
|
columns.forEach((column, index) => {
|
|
const $li = $('<li>');
|
|
const $label = $('<label>').addClass('dropdown-item');
|
|
const $checkbox = $('<input>').addClass('form-check-input me-2').attr('type', 'checkbox').prop('checked', column.visible !== false).attr('data-column-index', index);
|
|
$label.append($checkbox).append(column.label || column.name);
|
|
$li.append($label);
|
|
$menu.append($li);
|
|
$checkbox.on('change', e => {
|
|
this.toggle_column(index, e.target.checked);
|
|
});
|
|
});
|
|
}
|
|
toggle_column(index, visible) {
|
|
if (this.args.on_toggle) {
|
|
this.args.on_toggle(index, visible);
|
|
}
|
|
|
|
// Find table and toggle column visibility
|
|
const $table = this.args.table ? $(this.args.table) : this.$.closest('.card').find('table');
|
|
const selector = `th:nth-child(${index + 1}), td:nth-child(${index + 1})`;
|
|
if (visible) {
|
|
$table.find(selector).show();
|
|
} else {
|
|
$table.find(selector).hide();
|
|
}
|
|
}
|
|
set_columns(columns) {
|
|
this.build_menu(columns);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Comment_Thread.js (babel) === */
|
|
"use strict";
|
|
|
|
class Comment_Thread extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.comments = await response.json();
|
|
} else if (this.args.comments) {
|
|
this.data.comments = this.args.comments;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Submit new comment
|
|
this.$sid('submit_btn').on('click', () => {
|
|
this.submit_comment();
|
|
});
|
|
|
|
// Reply buttons
|
|
this.$.find('.reply-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.show_reply_form(comment_id);
|
|
});
|
|
|
|
// Edit buttons
|
|
this.$.find('.edit-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.edit_comment(comment_id);
|
|
});
|
|
|
|
// Delete buttons
|
|
this.$.find('.delete-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.delete_comment(comment_id);
|
|
});
|
|
}
|
|
async submit_comment() {
|
|
const text = this.$sid('comment_input').val().trim();
|
|
if (!text) return;
|
|
if (this.args.on_submit) {
|
|
const result = await this.args.on_submit(text);
|
|
if (result) {
|
|
this.$sid('comment_input').val('');
|
|
await this.reload_data();
|
|
}
|
|
}
|
|
}
|
|
show_reply_form(comment_id) {
|
|
// TODO: Implement reply form UI
|
|
console.log('Reply to comment:', comment_id);
|
|
}
|
|
edit_comment(comment_id) {
|
|
if (this.args.on_edit) {
|
|
this.args.on_edit(comment_id);
|
|
}
|
|
}
|
|
async delete_comment(comment_id) {
|
|
if (!confirm('Delete this comment?')) return;
|
|
if (this.args.on_delete) {
|
|
const result = await this.args.on_delete(comment_id);
|
|
if (result) {
|
|
await this.reload_data();
|
|
}
|
|
}
|
|
}
|
|
async reload_data() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.comments = await response.json();
|
|
this.render();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Date_Picker.js (babel) === */
|
|
"use strict";
|
|
|
|
class Date_Picker extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.min) {
|
|
$input.attr('min', this.args.min);
|
|
}
|
|
if (this.args.max) {
|
|
$input.attr('max', this.args.max);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Dropdown_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dropdown_Menu extends Component {
|
|
on_ready() {
|
|
// Wrap bare text children in <li><a> structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const text = $child.text();
|
|
const href = $child.attr('href') || '#';
|
|
const $li = $('<li>').append($('<a>').addClass('dropdown-item').attr('href', href).text(text));
|
|
$child.replaceWith($li);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Empty_State.js (babel) === */
|
|
"use strict";
|
|
|
|
class Empty_State extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Export_Button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Export_Button extends Component {
|
|
on_ready() {
|
|
const that = this;
|
|
this.$.find('[data-format]').on('click', e => {
|
|
e.preventDefault();
|
|
const format = $(e.currentTarget).attr('data-format');
|
|
that.export_data(format);
|
|
});
|
|
}
|
|
async export_data(format) {
|
|
if (this.args.on_export) {
|
|
// Custom export handler
|
|
this.args.on_export(format);
|
|
} else if (this.args.data) {
|
|
// Auto-export provided data
|
|
this.auto_export(format, this.args.data);
|
|
} else if (this.args.export_url) {
|
|
// Fetch export from URL
|
|
const url = `${this.args.export_url}?format=${format}`;
|
|
window.location.href = url;
|
|
}
|
|
}
|
|
auto_export(format, data) {
|
|
if (format === 'csv') {
|
|
this.export_csv(data);
|
|
} else if (format === 'json') {
|
|
this.export_json(data);
|
|
} else {
|
|
console.warn('Auto-export only supports CSV and JSON. Implement custom handler for other formats.');
|
|
}
|
|
}
|
|
export_csv(data) {
|
|
if (data.length === 0) return;
|
|
|
|
// Generate CSV
|
|
const headers = Object.keys(data[0]);
|
|
let csv = headers.join(',') + '\n';
|
|
data.forEach(row => {
|
|
const values = headers.map(header => {
|
|
const value = row[header] || '';
|
|
return `"${str(value).replace(/"/g, '""')}"`;
|
|
});
|
|
csv += values.join(',') + '\n';
|
|
});
|
|
|
|
// Download
|
|
const blob = new Blob([csv], {
|
|
type: 'text/csv'
|
|
});
|
|
const url = window.URL.createObjectURL(blob);
|
|
const $a = $('<a>');
|
|
$a.attr('href', url);
|
|
$a.attr('download', `export_${Date.now()}.csv`);
|
|
$a[0].click();
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
export_json(data) {
|
|
const json = json_encode(data);
|
|
const blob = new Blob([json], {
|
|
type: 'application/json'
|
|
});
|
|
const url = window.URL.createObjectURL(blob);
|
|
const $a = $('<a>');
|
|
$a.attr('href', url);
|
|
$a.attr('download', `export_${Date.now()}.json`);
|
|
$a[0].click();
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/File_Upload.js (babel) === */
|
|
"use strict";
|
|
|
|
class File_Upload extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('file_input');
|
|
const $drop_zone = this.$sid('drop_zone');
|
|
if (this.args.accept) {
|
|
$input.attr('accept', this.args.accept);
|
|
}
|
|
if (this.args.multiple) {
|
|
$input.attr('multiple', true);
|
|
}
|
|
|
|
// Click to upload
|
|
$drop_zone.on('click', () => {
|
|
$input.click();
|
|
});
|
|
|
|
// File selected
|
|
$input.on('change', e => {
|
|
const files = e.target.files;
|
|
if (files.length > 0) {
|
|
this.handle_files(files);
|
|
}
|
|
});
|
|
|
|
// Drag and drop
|
|
$drop_zone.on('dragover', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.addClass('border-primary bg-light');
|
|
});
|
|
$drop_zone.on('dragleave', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.removeClass('border-primary bg-light');
|
|
});
|
|
$drop_zone.on('drop', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.removeClass('border-primary bg-light');
|
|
const files = e.originalEvent.dataTransfer.files;
|
|
if (files.length > 0) {
|
|
this.handle_files(files);
|
|
}
|
|
});
|
|
|
|
// Remove button
|
|
this.$sid('remove_btn').on('click', e => {
|
|
e.stopPropagation();
|
|
this.clear();
|
|
});
|
|
}
|
|
handle_files(files) {
|
|
const file = files[0]; // Single file for now
|
|
|
|
// Validate file size
|
|
if (this.args.max_size_bytes && file.size > this.args.max_size_bytes) {
|
|
alert(`File is too large. Max size is ${this.format_size(this.args.max_size_bytes)}`);
|
|
return;
|
|
}
|
|
this.selected_file = file;
|
|
|
|
// Show file info
|
|
this.$sid('placeholder').hide();
|
|
this.$sid('file_info').show();
|
|
this.$sid('file_name').text(file.name);
|
|
this.$sid('file_size').text(this.format_size(file.size));
|
|
|
|
// Auto-upload if endpoint provided
|
|
if (this.args.upload_url) {
|
|
this.upload();
|
|
}
|
|
|
|
// Trigger callback
|
|
if (this.args.on_select) {
|
|
this.args.on_select(file);
|
|
}
|
|
}
|
|
async upload() {
|
|
if (!this.selected_file || !this.args.upload_url) return;
|
|
|
|
// Show progress
|
|
this.$sid('file_info').hide();
|
|
this.$sid('progress').show();
|
|
const form_data = new FormData();
|
|
form_data.append('file', this.selected_file);
|
|
try {
|
|
const response = await fetch(this.args.upload_url, {
|
|
method: 'POST',
|
|
body: form_data
|
|
});
|
|
const result = await response.json();
|
|
|
|
// Hide progress
|
|
this.$sid('progress').hide();
|
|
this.$sid('file_info').show();
|
|
if (this.args.on_upload) {
|
|
this.args.on_upload(result);
|
|
}
|
|
} catch (error) {
|
|
alert('Upload failed: ' + error.message);
|
|
this.$sid('progress').hide();
|
|
this.$sid('placeholder').show();
|
|
}
|
|
}
|
|
clear() {
|
|
this.selected_file = null;
|
|
this.$sid('file_input').val('');
|
|
this.$sid('file_info').hide();
|
|
this.$sid('progress').hide();
|
|
this.$sid('placeholder').show();
|
|
if (this.args.on_clear) {
|
|
this.args.on_clear();
|
|
}
|
|
}
|
|
get_file() {
|
|
return this.selected_file;
|
|
}
|
|
format_size(bytes) {
|
|
if (bytes < 1024) return bytes + ' B';
|
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Filter_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Filter_Bar extends Component {
|
|
on_ready() {
|
|
this.active_filters = {};
|
|
|
|
// Populate status options if provided
|
|
if (this.args.status_options) {
|
|
const $status = this.$sid('status');
|
|
this.args.status_options.forEach(opt => {
|
|
$status.append($('<option>').val(opt.value).text(opt.label));
|
|
});
|
|
}
|
|
|
|
// Date range change handler
|
|
this.$sid('date_range').on('change', e => {
|
|
if (e.target.value === 'custom') {
|
|
this.$sid('custom_dates').show();
|
|
this.$sid('custom_dates_end').show();
|
|
} else {
|
|
this.$sid('custom_dates').hide();
|
|
this.$sid('custom_dates_end').hide();
|
|
}
|
|
});
|
|
|
|
// Search with debounce
|
|
let search_timeout;
|
|
this.$sid('search').$.find('input').on('input', e => {
|
|
clearTimeout(search_timeout);
|
|
search_timeout = setTimeout(() => {
|
|
this.add_filter('search', e.target.value);
|
|
}, 500);
|
|
});
|
|
|
|
// Apply button
|
|
this.$sid('apply_btn').on('click', () => {
|
|
this.apply_filters();
|
|
});
|
|
|
|
// Clear button
|
|
this.$sid('clear_btn').on('click', () => {
|
|
this.clear_filters();
|
|
});
|
|
}
|
|
add_filter(key, value) {
|
|
if (value) {
|
|
this.active_filters[key] = value;
|
|
} else {
|
|
delete this.active_filters[key];
|
|
}
|
|
this.update_filter_display();
|
|
}
|
|
apply_filters() {
|
|
// Collect all filter values
|
|
const search = this.$sid('search').get_value();
|
|
const status = this.$sid('status').val();
|
|
const date_range = this.$sid('date_range').val();
|
|
this.active_filters = {};
|
|
if (search) this.active_filters.search = search;
|
|
if (status) this.active_filters.status = status;
|
|
if (date_range) this.active_filters.date_range = date_range;
|
|
if (date_range === 'custom') {
|
|
const start_date = this.$sid('start_date').get_value();
|
|
const end_date = this.$sid('end_date').get_value();
|
|
if (start_date) this.active_filters.start_date = start_date;
|
|
if (end_date) this.active_filters.end_date = end_date;
|
|
}
|
|
this.update_filter_display();
|
|
if (this.args.on_apply) {
|
|
this.args.on_apply(this.active_filters);
|
|
}
|
|
}
|
|
clear_filters() {
|
|
this.active_filters = {};
|
|
this.$sid('search').set_value('');
|
|
this.$sid('status').val('');
|
|
this.$sid('date_range').val('');
|
|
this.$sid('custom_dates').hide();
|
|
this.$sid('custom_dates_end').hide();
|
|
this.update_filter_display();
|
|
if (this.args.on_clear) {
|
|
this.args.on_clear();
|
|
}
|
|
}
|
|
update_filter_display() {
|
|
const count = Object.keys(this.active_filters).length;
|
|
const $container = this.$sid('active_filters');
|
|
const $tags = this.$sid('filter_tags');
|
|
if (count === 0) {
|
|
$container.hide();
|
|
return;
|
|
}
|
|
$container.show();
|
|
$tags.empty();
|
|
for (let key in this.active_filters) {
|
|
const $tag = $('<span>').addClass('badge bg-primary me-1');
|
|
$tag.text(`${key}: ${this.active_filters[key]}`);
|
|
const $remove = $('<i>').addClass('bi bi-x-circle ms-1').css('cursor', 'pointer');
|
|
$remove.on('click', () => {
|
|
delete this.active_filters[key];
|
|
this.update_filter_display();
|
|
this.apply_filters();
|
|
});
|
|
$tag.append($remove);
|
|
$tags.append($tag);
|
|
}
|
|
}
|
|
get_filters() {
|
|
return this.active_filters;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_actions_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Actions_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Actions_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$sid('loading').show();
|
|
// Example: this.$.addClass('initializing');
|
|
}
|
|
|
|
/**
|
|
* Fetch data from APIs (parallel, NO DOM modifications)
|
|
* Use for: Loading data from server, fetching configurations
|
|
* WARNING: Do NOT modify DOM here - only load data
|
|
*/
|
|
async on_load() {
|
|
// Example: this.data.users = await Users_Controller.get_users_api();
|
|
// Example: this.data.config = await this.load_config();
|
|
// WARNING: Do NOT modify DOM here - only load data
|
|
}
|
|
|
|
/**
|
|
* Component fully initialized (bottom-up)
|
|
* Use for: Final UI setup, hiding loading indicators, starting animations
|
|
*/
|
|
async on_ready() {
|
|
// Example: this.$sid('loading').hide();
|
|
// Example: this.setup_event_listeners();
|
|
}
|
|
|
|
/**
|
|
* Click handler for the hello button
|
|
* Referenced in template via @click=this.on_click_hello
|
|
*/
|
|
on_click_hello() {
|
|
this.$sid('inner_html').hide();
|
|
this.$sid('hello_world').show();
|
|
}
|
|
|
|
// For more information: php artisan rsx:man jqhtml
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Form_Field_Group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Form_Field_Group extends Component {
|
|
on_ready() {
|
|
// Optional: Add collapsible functionality
|
|
if (this.args.collapsible) {
|
|
this.make_collapsible();
|
|
}
|
|
}
|
|
make_collapsible() {
|
|
const $header = this.$.find('.card-header');
|
|
const $body = this.$.find('.card-body');
|
|
const collapse_id = 'collapse_' + Math.random().toString(36).substr(2, 9);
|
|
$body.attr('id', collapse_id).addClass('collapse show');
|
|
const $toggle = $('<button>').attr('type', 'button').addClass('btn btn-link btn-sm float-end text-decoration-none').attr('data-bs-toggle', 'collapse').attr('data-bs-target', '#' + collapse_id).html('<i class="bi bi-chevron-up"></i>');
|
|
$header.find('h5').append($toggle);
|
|
$body.on('show.bs.collapse', () => {
|
|
$toggle.html('<i class="bi bi-chevron-up"></i>');
|
|
});
|
|
$body.on('hide.bs.collapse', () => {
|
|
$toggle.html('<i class="bi bi-chevron-down"></i>');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_group_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Group_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Group_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
on_create() {
|
|
// Apply responsive column classes
|
|
const col_class = this.args.col_class || 'col-12 col-md-6 col-xl-4';
|
|
this.$.addClass(col_class + ' mb-3');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_row_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Row_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Row_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$sid('loading').show();
|
|
// Example: this.$.addClass('initializing');
|
|
}
|
|
|
|
/**
|
|
* Fetch data from APIs (parallel, NO DOM modifications)
|
|
* Use for: Loading data from server, fetching configurations
|
|
* WARNING: Do NOT modify DOM here - only load data
|
|
*/
|
|
async on_load() {
|
|
// Example: this.data.users = await Users_Controller.get_users_api();
|
|
// Example: this.data.config = await this.load_config();
|
|
// WARNING: Do NOT modify DOM here - only load data
|
|
}
|
|
|
|
/**
|
|
* Component fully initialized (bottom-up)
|
|
* Use for: Final UI setup, hiding loading indicators, starting animations
|
|
*/
|
|
async on_ready() {
|
|
// Example: this.$sid('loading').hide();
|
|
// Example: this.setup_event_listeners();
|
|
}
|
|
|
|
/**
|
|
* Click handler for the hello button
|
|
* Referenced in template via @click=this.on_click_hello
|
|
*/
|
|
on_click_hello() {
|
|
this.$sid('inner_html').hide();
|
|
this.$sid('hello_world').show();
|
|
}
|
|
|
|
// For more information: php artisan rsx:man jqhtml
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Form_Validation_Message.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Validation_Message - Bootstrap 5 Validation Feedback Component
|
|
*
|
|
* Purpose: Display validation feedback messages (success/error) below form inputs
|
|
* Design: Bootstrap .invalid-feedback (default) or .valid-feedback styling
|
|
* Visibility: Only shows when sibling input has .is-valid or .is-invalid class
|
|
*/
|
|
class Form_Validation_Message extends Component {
|
|
on_ready() {
|
|
// Add custom classes if provided (e.g., switching to valid-feedback)
|
|
if (this.args.class) {
|
|
// Replace default invalid-feedback with provided class
|
|
this.$.removeClass('invalid-feedback');
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Gantt_Chart.js (babel) === */
|
|
"use strict";
|
|
|
|
class Gantt_Chart extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
const data = await response.json();
|
|
this.data.tasks = data.tasks;
|
|
this.data.months = data.months;
|
|
} else if (this.args.tasks) {
|
|
this.data.tasks = this.args.tasks;
|
|
this.data.months = this.args.months || this.generate_months();
|
|
}
|
|
}
|
|
generate_months() {
|
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
return months;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/icon_button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_Button extends Component {
|
|
on_ready() {
|
|
// Add aria-label for accessibility (icon-only buttons need labels)
|
|
if (this.args.label) {
|
|
this.$.attr('aria-label', this.args.label);
|
|
}
|
|
|
|
// Add title for tooltip on hover
|
|
if (this.args.title) {
|
|
this.$.attr('title', this.args.title);
|
|
}
|
|
|
|
// Support custom button classes (btn-primary, btn-danger, etc.)
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Icon_With_Label.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_With_Label extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Icon_With_Text.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_With_Text extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/icon.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon extends Component {
|
|
// SVG icon container with size variants
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Info_Box.js (babel) === */
|
|
"use strict";
|
|
|
|
class Info_Box extends Component {
|
|
on_ready() {
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
this.$.removeClass('border-primary').addClass(`border-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Inline_Edit_Field.js (babel) === */
|
|
"use strict";
|
|
|
|
class Inline_Edit_Field extends Component {
|
|
on_ready() {
|
|
this.current_value = this.args.value || '';
|
|
|
|
// Enter edit mode
|
|
this.$sid('display_mode').on('click', () => {
|
|
this.enter_edit_mode();
|
|
});
|
|
|
|
// Save
|
|
this.$sid('save_btn').on('click', () => {
|
|
this.save();
|
|
});
|
|
|
|
// Cancel
|
|
this.$sid('cancel_btn').on('click', () => {
|
|
this.cancel();
|
|
});
|
|
|
|
// Save on Enter, cancel on Escape
|
|
this.$sid('input').on('keydown', e => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
this.save();
|
|
} else if (e.key === 'Escape') {
|
|
e.preventDefault();
|
|
this.cancel();
|
|
}
|
|
});
|
|
}
|
|
enter_edit_mode() {
|
|
const $input = this.$sid('input');
|
|
$input.val(this.current_value);
|
|
this.$sid('display_mode').hide();
|
|
this.$sid('edit_mode').show();
|
|
$input.focus();
|
|
$input.select();
|
|
}
|
|
exit_edit_mode() {
|
|
this.$sid('edit_mode').hide();
|
|
this.$sid('display_mode').show();
|
|
}
|
|
save() {
|
|
const new_value = this.$sid('input').val();
|
|
if (new_value === this.current_value) {
|
|
this.exit_edit_mode();
|
|
return;
|
|
}
|
|
|
|
// Trigger callback
|
|
if (this.args.on_save) {
|
|
const result = this.args.on_save(new_value, this.current_value);
|
|
|
|
// If callback returns false, don't save
|
|
if (result === false) {
|
|
return;
|
|
}
|
|
|
|
// If callback returns a promise, wait for it
|
|
if (result && typeof result.then === 'function') {
|
|
this.show_saving();
|
|
result.then(() => {
|
|
this.current_value = new_value;
|
|
this.update_display();
|
|
this.exit_edit_mode();
|
|
}).catch(() => {
|
|
this.exit_edit_mode();
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
this.current_value = new_value;
|
|
this.update_display();
|
|
this.exit_edit_mode();
|
|
}
|
|
cancel() {
|
|
this.exit_edit_mode();
|
|
}
|
|
update_display() {
|
|
const display = this.current_value || this.args.placeholder || 'Click to edit';
|
|
this.$sid('value_display').text(display);
|
|
}
|
|
show_saving() {
|
|
this.$sid('save_btn').prop('disabled', true).html('<span class="spinner-border spinner-border-sm"></span>');
|
|
this.$sid('cancel_btn').prop('disabled', true);
|
|
}
|
|
get_value() {
|
|
return this.current_value;
|
|
}
|
|
set_value(value) {
|
|
this.current_value = value;
|
|
this.update_display();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input_With_Icon.js (babel) === */
|
|
"use strict";
|
|
|
|
class Input_With_Icon extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
if (this.args.on_input) {
|
|
$input.on('input', e => {
|
|
this.args.on_input(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input_With_Validation.js (babel) === */
|
|
"use strict";
|
|
|
|
class Input_With_Validation extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
|
|
// Real-time validation
|
|
if (this.args.validate) {
|
|
$input.on('blur', () => {
|
|
this.validate();
|
|
});
|
|
$input.on('input', () => {
|
|
if (this.$.hasClass('was-validated')) {
|
|
this.validate();
|
|
}
|
|
});
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
validate() {
|
|
const value = this.$sid('input').val();
|
|
const $input = this.$sid('input');
|
|
this.$.addClass('was-validated');
|
|
|
|
// Run validation function
|
|
if (this.args.validate) {
|
|
const result = this.args.validate(value);
|
|
if (result === true || result === null || result === undefined) {
|
|
this.set_valid();
|
|
return true;
|
|
} else {
|
|
this.set_error(result);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Basic required check
|
|
if (this.args.required && !value) {
|
|
this.set_error('This field is required');
|
|
return false;
|
|
}
|
|
this.set_valid();
|
|
return true;
|
|
}
|
|
set_error(message) {
|
|
const $input = this.$sid('input');
|
|
const $error = this.$sid('error');
|
|
$input.removeClass('is-valid').addClass('is-invalid');
|
|
$error.text(message).css('display', 'block');
|
|
this.$sid('success').css('display', 'none');
|
|
}
|
|
set_valid(message) {
|
|
const $input = this.$sid('input');
|
|
const $success = this.$sid('success');
|
|
$input.removeClass('is-invalid').addClass('is-valid');
|
|
this.$sid('error').css('display', 'none');
|
|
if (message) {
|
|
$success.text(message).css('display', 'block');
|
|
} else {
|
|
$success.css('display', 'none');
|
|
}
|
|
}
|
|
clear_validation() {
|
|
const $input = this.$sid('input');
|
|
$input.removeClass('is-valid is-invalid');
|
|
this.$sid('error').css('display', 'none');
|
|
this.$sid('success').css('display', 'none');
|
|
this.$.removeClass('was-validated');
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
if (this.$.hasClass('was-validated')) {
|
|
this.validate();
|
|
}
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Input - Bootstrap 5 Text Input Component
|
|
*
|
|
* Purpose: Single-line text input field for user data entry
|
|
* Design: Bootstrap .form-control styling
|
|
* Types: text, email, password, number, tel, url, date, etc.
|
|
*/
|
|
class Input extends Component {
|
|
on_ready() {
|
|
// Set type attribute if provided
|
|
if (this.args.type) {
|
|
this.$.attr('type', this.args.type);
|
|
}
|
|
|
|
// Set placeholder if provided
|
|
if (this.args.placeholder) {
|
|
this.$.attr('placeholder', this.args.placeholder);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Kanban_Board.js (babel) === */
|
|
"use strict";
|
|
|
|
class Kanban_Board extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.columns = await response.json();
|
|
} else if (this.args.columns) {
|
|
this.data.columns = this.args.columns;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Drag and drop functionality
|
|
this.setup_drag_and_drop();
|
|
}
|
|
setup_drag_and_drop() {
|
|
let dragged_card = null;
|
|
|
|
// Make cards draggable
|
|
this.$.find('[data-card-id]').each(function () {
|
|
const $card = $(this);
|
|
$card.on('dragstart', function (e) {
|
|
dragged_card = this;
|
|
$(this).css('opacity', '0.5');
|
|
});
|
|
$card.on('dragend', function (e) {
|
|
$(this).css('opacity', '1');
|
|
});
|
|
});
|
|
|
|
// Make columns droppable
|
|
this.$.find('[data-column-cards]').each(function () {
|
|
const $column = $(this);
|
|
$column.on('dragover', function (e) {
|
|
e.preventDefault();
|
|
$column.addClass('bg-light');
|
|
});
|
|
$column.on('dragleave', function (e) {
|
|
$column.removeClass('bg-light');
|
|
});
|
|
$column.on('drop', function (e) {
|
|
e.preventDefault();
|
|
$column.removeClass('bg-light');
|
|
if (dragged_card) {
|
|
$column.append(dragged_card);
|
|
|
|
// Trigger callback
|
|
if (this.args.on_move) {
|
|
const card_id = $(dragged_card).attr('data-card-id');
|
|
const column_id = $column.attr('data-column-cards');
|
|
this.args.on_move(card_id, column_id);
|
|
}
|
|
}
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/link.js (babel) === */
|
|
"use strict";
|
|
|
|
class Link extends Component {
|
|
on_ready() {
|
|
// Support $href attribute for dynamic URLs
|
|
if (this.args.href) {
|
|
this.$.attr('href', this.args.href);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/List.js (babel) === */
|
|
"use strict";
|
|
|
|
class List extends Component {
|
|
on_ready() {
|
|
// Add list-group-item class to each direct child
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('list-group-item');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Loading_Skeleton.js (babel) === */
|
|
"use strict";
|
|
|
|
class Loading_Skeleton extends Component {
|
|
on_ready() {
|
|
// Apply lines from args
|
|
if (this.args.lines) {
|
|
this.$.empty();
|
|
for (let i = 0; i < this.args.lines; i++) {
|
|
const width = 12 - i * 2;
|
|
const $span = $('<span>').addClass(`placeholder col-${Math.max(width, 6)}`);
|
|
this.$.append($span);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Metric_Card.js (babel) === */
|
|
"use strict";
|
|
|
|
class Metric_Card extends Component {
|
|
// Pure container - children already styled
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Mobile_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
class Mobile_Header extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Modal_Dialog.js (babel) === */
|
|
"use strict";
|
|
|
|
class Modal_Dialog extends Component {
|
|
on_ready() {
|
|
// Initialize Bootstrap modal
|
|
this.modal = new bootstrap.Modal(this.$[0]);
|
|
}
|
|
show() {
|
|
this.modal.show();
|
|
}
|
|
hide() {
|
|
this.modal.hide();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Multi_Select.js (babel) === */
|
|
"use strict";
|
|
|
|
class Multi_Select extends Component {
|
|
on_ready() {
|
|
this.selected_values = this.args.value || [];
|
|
this.all_options = this.args.options || [];
|
|
if (this.all_options.length > 0) {
|
|
this.render_options(this.all_options);
|
|
}
|
|
|
|
// Search functionality
|
|
const $search = this.$sid('search');
|
|
$search.on('input', e => {
|
|
this.filter_options(e.target.value);
|
|
});
|
|
|
|
// Prevent dropdown close when clicking inside
|
|
this.$sid('menu').on('click', e => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Clear/Select all buttons
|
|
this.$sid('clear_all').on('click', () => {
|
|
this.clear_all();
|
|
});
|
|
this.$sid('select_all').on('click', () => {
|
|
this.select_all();
|
|
});
|
|
|
|
// Update display
|
|
this.update_display();
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$sid('options');
|
|
$container.empty();
|
|
if (options.length === 0) {
|
|
$container.append($('<div>').addClass('px-3 py-2 text-muted').text('No options found'));
|
|
return;
|
|
}
|
|
options.forEach(option => {
|
|
const $label = $('<label>').addClass('dropdown-item mb-0');
|
|
const $checkbox = $('<input>').attr('type', 'checkbox').addClass('form-check-input me-2').attr('data-value', option.value).prop('checked', this.selected_values.includes(option.value));
|
|
$checkbox.on('change', e => {
|
|
this.toggle_option(option.value, e.target.checked);
|
|
});
|
|
$label.append($checkbox).append(option.label);
|
|
$container.append($label);
|
|
});
|
|
}
|
|
filter_options(query) {
|
|
const filtered = this.all_options.filter(opt => opt.label.toLowerCase().includes(query.toLowerCase()));
|
|
this.render_options(filtered);
|
|
}
|
|
toggle_option(value, checked) {
|
|
if (checked) {
|
|
if (!this.selected_values.includes(value)) {
|
|
this.selected_values.push(value);
|
|
}
|
|
} else {
|
|
this.selected_values = this.selected_values.filter(v => v !== value);
|
|
}
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
update_display() {
|
|
const count = this.selected_values.length;
|
|
const $text = this.$sid('selected_text');
|
|
if (count === 0) {
|
|
$text.text(this.args.placeholder || 'Select options');
|
|
} else if (count === 1) {
|
|
const option = this.all_options.find(opt => opt.value === this.selected_values[0]);
|
|
$text.text(option ? option.label : '1 selected');
|
|
} else {
|
|
$text.text(`${count} selected`);
|
|
}
|
|
}
|
|
clear_all() {
|
|
this.selected_values = [];
|
|
this.$sid('options').find('input[type="checkbox"]').prop('checked', false);
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
select_all() {
|
|
this.selected_values = this.all_options.map(opt => opt.value);
|
|
this.$sid('options').find('input[type="checkbox"]').prop('checked', true);
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.selected_values;
|
|
}
|
|
set_value(values) {
|
|
this.selected_values = values;
|
|
this.$sid('options').find('input[type="checkbox"]').each((i, el) => {
|
|
const $el = $(el);
|
|
$el.prop('checked', values.includes($el.attr('data-value')));
|
|
});
|
|
this.update_display();
|
|
}
|
|
set_options(options) {
|
|
this.all_options = options;
|
|
this.render_options(options);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Notification_Badge.js (babel) === */
|
|
"use strict";
|
|
|
|
class Notification_Badge extends Component {
|
|
on_ready() {
|
|
const $count = this.$sid('count');
|
|
// Update count dynamically
|
|
if (this.args.count === 0 || this.args.count === '0') {
|
|
$count.hide();
|
|
}
|
|
}
|
|
set_count(count) {
|
|
const $count = this.$sid('count');
|
|
$count.text(count);
|
|
if (count > 0) {
|
|
$count.show();
|
|
} else {
|
|
$count.hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Notification_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
class Notification_Dropdown extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Overdue_Indicator.js (babel) === */
|
|
"use strict";
|
|
|
|
class Overdue_Indicator extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Page_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Page_Header - Bootstrap 5 Page Action Bar Component
|
|
*
|
|
* Purpose: Top section of page containing title, breadcrumbs, and actions
|
|
* Design: Flexbox layout using Bootstrap utility classes
|
|
* Layout: Title/breadcrumbs on left, actions/buttons on right
|
|
*/
|
|
class Page_Header extends Component {
|
|
// Page_Header is a pure container component - no lifecycle methods needed
|
|
// All layout from Bootstrap utilities: d-flex, justify-content-between, align-items-center, py-4
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/page_section.js (babel) === */
|
|
"use strict";
|
|
|
|
class Page_Section extends Component {
|
|
// Content section with spacing - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/page.js (babel) === */
|
|
"use strict";
|
|
|
|
class Page extends Component {
|
|
// Semantic page container - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Popover.js (babel) === */
|
|
"use strict";
|
|
|
|
class Popover extends Component {
|
|
on_ready() {
|
|
// Set popover content from args
|
|
if (this.args.title) {
|
|
this.$.attr('data-bs-title', this.args.title);
|
|
}
|
|
if (this.args.content) {
|
|
this.$.attr('data-bs-content', this.args.content);
|
|
}
|
|
|
|
// Set trigger (hover, click, focus)
|
|
this.$.attr('data-bs-trigger', this.args.trigger || 'click');
|
|
|
|
// Initialize Bootstrap popover
|
|
new bootstrap.Popover(this.$[0]);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Progress_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Progress_Bar extends Component {
|
|
on_ready() {
|
|
const $bar = this.$sid('bar');
|
|
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
$bar.addClass(`bg-${this.args.color}`);
|
|
}
|
|
|
|
// Show value text if requested
|
|
if (this.args.show_value) {
|
|
$bar.text(`${this.args.value || 0}%`);
|
|
}
|
|
}
|
|
set_value(value) {
|
|
const $bar = this.$sid('bar');
|
|
$bar.css('width', `${value}%`).attr('aria-valuenow', value);
|
|
if (this.args.show_value) {
|
|
$bar.text(`${value}%`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Radio_Button.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Radio_Button - Bootstrap 5 Radio Input Component
|
|
*
|
|
* Purpose: Radio button for mutually exclusive selections within a group
|
|
* Design: Bootstrap .form-check-input styling with circular shape
|
|
* CRITICAL: All radios in same group must have same "name" attribute
|
|
* Wrapper: Typically used within <div class="form-check"> and <fieldset>
|
|
*/
|
|
class Radio_Button extends Component {
|
|
on_ready() {
|
|
// Set name attribute (CRITICAL for grouping)
|
|
if (this.args.name) {
|
|
this.$.attr('name', this.args.name);
|
|
}
|
|
|
|
// Set checked state if provided
|
|
if (this.args.checked) {
|
|
this.$.prop('checked', true);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Rich_Text_Editor.js (babel) === */
|
|
"use strict";
|
|
|
|
class Rich_Text_Editor extends Component {
|
|
on_ready() {
|
|
const $editor = this.$sid('editor');
|
|
|
|
// Toolbar button handlers
|
|
this.$sid('toolbar').find('[data-command]').on('click', e => {
|
|
e.preventDefault();
|
|
const command = $(e.currentTarget).attr('data-command');
|
|
if (command === 'createLink') {
|
|
const url = prompt('Enter URL:');
|
|
if (url) {
|
|
document.execCommand(command, false, url);
|
|
}
|
|
} else {
|
|
document.execCommand(command, false, null);
|
|
}
|
|
$editor.focus();
|
|
});
|
|
|
|
// Track changes
|
|
$editor.on('input', () => {
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.get_value());
|
|
}
|
|
});
|
|
|
|
// Prevent default behavior on paste (optional - can be customized)
|
|
$editor.on('paste', e => {
|
|
if (this.args.plain_text_paste) {
|
|
e.preventDefault();
|
|
const text = e.originalEvent.clipboardData.getData('text/plain');
|
|
document.execCommand('insertText', false, text);
|
|
}
|
|
});
|
|
}
|
|
get_value() {
|
|
return this.$sid('editor').html();
|
|
}
|
|
get_text() {
|
|
return this.$sid('editor').text();
|
|
}
|
|
set_value(html) {
|
|
this.$sid('editor').html(html);
|
|
}
|
|
clear() {
|
|
this.$sid('editor').empty();
|
|
}
|
|
focus() {
|
|
this.$sid('editor').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Row_Action_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Row_Action_Menu extends Component {
|
|
on_ready() {
|
|
// Wrap children in dropdown structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
if ($child.prop('tagName') === 'HR') {
|
|
const $li = $('<li>').append($('<hr>').addClass('dropdown-divider'));
|
|
$child.replaceWith($li);
|
|
} else {
|
|
$child.addClass('dropdown-item');
|
|
const $li = $('<li>');
|
|
$child.wrap($li);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sample_Datagrid_Component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Sample_Datagrid_Component
|
|
*
|
|
* Full-featured data table with:
|
|
* - Row selection (checkboxes)
|
|
* - Pagination
|
|
* - Row actions (view, edit, delete)
|
|
* - Loading states with placeholders
|
|
* - Empty states
|
|
*
|
|
* Usage:
|
|
* <Sample_Datagrid_Component
|
|
* $title="Client List"
|
|
* $entity_name="clients"
|
|
* $selectable=true
|
|
* $pagination=true
|
|
* $allow_delete=true
|
|
* $view_url="/clients/{id}"
|
|
* $edit_url="/clients/{id}/edit"
|
|
* $api_url="/api/clients"
|
|
* $columns=columns_definition
|
|
* />
|
|
*/
|
|
class Sample_Datagrid_Component extends Component {
|
|
async on_load() {
|
|
const that = this;
|
|
// If API URL provided, fetch data
|
|
if (that.args.api_url) {
|
|
const response = await fetch(that.args.api_url);
|
|
that.data = await response.json();
|
|
} else {
|
|
// Generate sample data for demonstration
|
|
that.data = that.generate_sample_data();
|
|
}
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
// Select all checkbox
|
|
if (that.args.selectable) {
|
|
that.$sid('select_all').on('change', e => {
|
|
const checked = e.target.checked;
|
|
that.$.find('tbody input[type="checkbox"]').prop('checked', checked);
|
|
that.update_selection_count();
|
|
});
|
|
|
|
// Individual row checkboxes
|
|
that.$.find('tbody input[type="checkbox"]').on('change', () => {
|
|
that.update_selection_count();
|
|
});
|
|
}
|
|
|
|
// Delete buttons
|
|
if (that.args.allow_delete) {
|
|
that.$.find('button[data-id]').on('click', e => {
|
|
const $button = $(e.currentTarget);
|
|
const id = $button.data('id');
|
|
that.confirm_delete(id);
|
|
});
|
|
}
|
|
|
|
// Pagination
|
|
if (that.args.pagination !== false) {
|
|
that.$sid('prev_page').on('click', e => {
|
|
e.preventDefault();
|
|
that.go_to_page(that.data.pagination.current_page - 1);
|
|
});
|
|
that.$sid('next_page').on('click', e => {
|
|
e.preventDefault();
|
|
that.go_to_page(that.data.pagination.current_page + 1);
|
|
});
|
|
that.$.find('.page-link[data-page]').on('click', e => {
|
|
e.preventDefault();
|
|
const $link = $(e.currentTarget);
|
|
const page = int($link.data('page'));
|
|
that.go_to_page(page);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update UI to show how many rows are selected
|
|
*/
|
|
update_selection_count() {
|
|
const that = this;
|
|
const selected = that.$.find('tbody input[type="checkbox"]:checked').length;
|
|
if (selected > 0) {
|
|
// Could show a banner: "3 items selected"
|
|
console.log(`${selected} items selected`);
|
|
|
|
// Fire event for parent components to listen to
|
|
that.$.trigger('selection:changed', {
|
|
count: selected
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get array of selected IDs
|
|
*/
|
|
get_selected_ids() {
|
|
const that = this;
|
|
const ids = [];
|
|
that.$.find('tbody input[type="checkbox"]:checked').each((i, checkbox) => {
|
|
const $checkbox = $(checkbox);
|
|
const id = $checkbox.data('id');
|
|
if (id) ids.push(id);
|
|
});
|
|
return ids;
|
|
}
|
|
|
|
/**
|
|
* Clear all selections
|
|
*/
|
|
clear_selection() {
|
|
const that = this;
|
|
that.$.find('input[type="checkbox"]').prop('checked', false);
|
|
that.update_selection_count();
|
|
}
|
|
|
|
/**
|
|
* Confirm deletion of a row
|
|
*/
|
|
confirm_delete(id) {
|
|
const that = this;
|
|
// In a real app, show a Bootstrap modal
|
|
if (confirm('Are you sure you want to delete this item?')) {
|
|
that.delete_row(id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a row (would typically make API call)
|
|
*/
|
|
async delete_row(id) {
|
|
const that = this;
|
|
try {
|
|
// Make API call
|
|
// await fetch(`${that.args.api_url}/${id}`, { method: 'DELETE' });
|
|
|
|
// Remove row from data
|
|
that.data.rows = that.data.rows.filter(row => row.id !== id);
|
|
|
|
// Re-render component
|
|
that.refresh();
|
|
|
|
// Show success message
|
|
console.log(`Deleted item ${id}`);
|
|
} catch (error) {
|
|
console.error('Delete failed:', error);
|
|
alert('Failed to delete item');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Navigate to a specific page
|
|
*/
|
|
async go_to_page(page) {
|
|
const that = this;
|
|
if (page < 1 || page > that.data.pagination.total_pages) {
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
that.$.find('tbody').css('opacity', '0.5');
|
|
try {
|
|
// Fetch new page
|
|
const url = `${that.args.api_url}?page=${page}`;
|
|
const response = await fetch(url);
|
|
that.data = await response.json();
|
|
|
|
// Re-render
|
|
that.refresh();
|
|
} catch (error) {
|
|
console.error('Pagination failed:', error);
|
|
that.$.find('tbody').css('opacity', '1');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh the table (reload data and re-render)
|
|
*/
|
|
async reload_data() {
|
|
const that = this;
|
|
that.data = {}; // Clear data to show loading state
|
|
that.refresh();
|
|
await that.on_load();
|
|
that.refresh();
|
|
}
|
|
|
|
/**
|
|
* Generate sample data for demonstration purposes
|
|
*/
|
|
generate_sample_data() {
|
|
const that = this;
|
|
const statuses = [{
|
|
label: 'Active',
|
|
color: 'success'
|
|
}, {
|
|
label: 'Pending',
|
|
color: 'warning'
|
|
}, {
|
|
label: 'Inactive',
|
|
color: 'secondary'
|
|
}, {
|
|
label: 'Suspended',
|
|
color: 'danger'
|
|
}];
|
|
const first_names = ['John', 'Sarah', 'Michael', 'Emily', 'David', 'Lisa', 'Robert', 'Jennifer', 'William', 'Amanda'];
|
|
const last_names = ['Smith', 'Johnson', 'Brown', 'Garcia', 'Martinez', 'Lee', 'Anderson', 'Thompson', 'White', 'Davis'];
|
|
const companies = ['Acme Corp', 'Tech Solutions', 'Global Enterprises', 'Innovation Labs', 'Digital Systems', 'Cloud Services', 'Smart Industries', 'Future Networks', 'Prime Consulting', 'Elite Partners'];
|
|
const rows = [];
|
|
const count = that.args.showing || 10;
|
|
for (let i = 0; i < count; i++) {
|
|
const first_name = first_names[Math.floor(Math.random() * first_names.length)];
|
|
const last_name = last_names[Math.floor(Math.random() * last_names.length)];
|
|
const company = companies[Math.floor(Math.random() * companies.length)];
|
|
const status = statuses[Math.floor(Math.random() * statuses.length)];
|
|
rows.push({
|
|
id: `C${str(i + 1).padStart(3, '0')}`,
|
|
name: `${first_name} ${last_name}`,
|
|
company: company,
|
|
email: `${first_name.toLowerCase()}.${last_name.toLowerCase()}@${company.toLowerCase().replace(/\s+/g, '')}.com`,
|
|
phone: `(555) ${str(Math.floor(Math.random() * 900) + 100)}-${str(Math.floor(Math.random() * 9000) + 1000)}`,
|
|
status: status.label,
|
|
status_color: status.color,
|
|
created: that.random_date()
|
|
});
|
|
}
|
|
return {
|
|
rows: rows,
|
|
pagination: {
|
|
current_page: 1,
|
|
total_pages: Math.ceil((that.args.total || 100) / count),
|
|
from: 1,
|
|
to: count,
|
|
total: that.args.total || 100,
|
|
pages: [1, 2, 3, '...', Math.ceil((that.args.total || 100) / count)]
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Generate random date for sample data
|
|
*/
|
|
random_date() {
|
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
const month = months[Math.floor(Math.random() * 12)];
|
|
const day = Math.floor(Math.random() * 28) + 1;
|
|
return `${month} ${str(day).padStart(2, '0')}, 2024`;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Search_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Search_Bar extends Component {
|
|
on_ready() {
|
|
// Bind search event
|
|
const $input = this.$sid('input');
|
|
$input.on('input', e => {
|
|
if (this.args.on_search) {
|
|
this.args.on_search(e.target.value);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Searchable_Select.js (babel) === */
|
|
"use strict";
|
|
|
|
class Searchable_Select extends Component {
|
|
on_ready() {
|
|
this.selected_value = this.args.value || null;
|
|
this.all_options = this.args.options || [];
|
|
if (this.all_options.length > 0) {
|
|
this.render_options(this.all_options);
|
|
}
|
|
|
|
// Search functionality
|
|
const $search = this.$sid('search');
|
|
$search.on('input', e => {
|
|
this.filter_options(e.target.value);
|
|
});
|
|
|
|
// Prevent dropdown close when clicking search input
|
|
$search.on('click', e => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Update selected text if initial value provided
|
|
if (this.selected_value) {
|
|
const selected_option = this.all_options.find(opt => opt.value == this.selected_value);
|
|
if (selected_option) {
|
|
this.$sid('selected_text').text(selected_option.label);
|
|
}
|
|
}
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$sid('options');
|
|
$container.empty();
|
|
if (options.length === 0) {
|
|
$container.append($('<div>').addClass('px-3 py-2 text-muted').text('No options found'));
|
|
return;
|
|
}
|
|
options.forEach(option => {
|
|
const $item = $('<a>').addClass('dropdown-item').attr('href', '#').text(option.label).attr('data-value', option.value);
|
|
if (option.value == this.selected_value) {
|
|
$item.addClass('active');
|
|
}
|
|
$item.on('click', e => {
|
|
e.preventDefault();
|
|
this.select_option(option);
|
|
});
|
|
$container.append($item);
|
|
});
|
|
}
|
|
filter_options(query) {
|
|
const filtered = this.all_options.filter(opt => opt.label.toLowerCase().includes(query.toLowerCase()));
|
|
this.render_options(filtered);
|
|
}
|
|
select_option(option) {
|
|
this.selected_value = option.value;
|
|
this.$sid('selected_text').text(option.label);
|
|
|
|
// Update active state
|
|
this.$sid('options').find('.dropdown-item').removeClass('active');
|
|
this.$sid('options').find(`[data-value="${option.value}"]`).addClass('active');
|
|
|
|
// Close dropdown
|
|
const dropdown = bootstrap.Dropdown.getInstance(this.$sid('button')[0]);
|
|
if (dropdown) {
|
|
dropdown.hide();
|
|
}
|
|
|
|
// Clear search
|
|
this.$sid('search').val('');
|
|
this.render_options(this.all_options);
|
|
|
|
// Trigger callback
|
|
if (this.args.on_change) {
|
|
this.args.on_change(option.value, option);
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.selected_value;
|
|
}
|
|
set_value(value) {
|
|
this.selected_value = value;
|
|
const option = this.all_options.find(opt => opt.value == value);
|
|
if (option) {
|
|
this.$sid('selected_text').text(option.label);
|
|
this.$sid('options').find('.dropdown-item').removeClass('active');
|
|
this.$sid('options').find(`[data-value="${value}"]`).addClass('active');
|
|
}
|
|
}
|
|
set_options(options) {
|
|
this.all_options = options;
|
|
this.render_options(options);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Select_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Select_Dropdown - Bootstrap 5 Dropdown Selection Component
|
|
*
|
|
* Purpose: Dropdown menu for selecting one option from a list
|
|
* Design: Bootstrap .form-select styling with dropdown arrow
|
|
* Content: Contains <option> elements
|
|
*/
|
|
class Select_Dropdown extends Component {
|
|
on_ready() {
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sidebar_Nav.js (babel) === */
|
|
"use strict";
|
|
|
|
class Sidebar_Nav extends Component {
|
|
on_ready() {
|
|
// Auto-wrap children in nav structure if needed
|
|
const $nav_items = this.$sid('nav_items');
|
|
$nav_items.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
|
|
// Set active state based on current URL
|
|
const current_path = window.location.pathname;
|
|
$nav_items.find('a.nav-link').each(function () {
|
|
const $link = $(this);
|
|
if ($link.attr('href') === current_path) {
|
|
$link.addClass('active');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sortable_Column_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
class Sortable_Column_Header extends Component {
|
|
on_ready() {
|
|
// Click to toggle sort
|
|
this.$.on('click', () => {
|
|
this.toggle_sort();
|
|
});
|
|
|
|
// Set initial sort state
|
|
if (this.args.sort) {
|
|
this.set_sort(this.args.sort); // 'asc' or 'desc'
|
|
}
|
|
}
|
|
toggle_sort() {
|
|
const current = this.$.attr('data-sort') || 'none';
|
|
const next = current === 'none' ? 'asc' : current === 'asc' ? 'desc' : 'asc';
|
|
this.set_sort(next);
|
|
|
|
// Call callback if provided
|
|
if (this.args.on_sort) {
|
|
this.args.on_sort(this.args.column, next);
|
|
}
|
|
}
|
|
set_sort(direction) {
|
|
this.$.attr('data-sort', direction);
|
|
const $icon = this.$sid('sort_icon');
|
|
if (direction === 'asc') {
|
|
$icon.html('<i class="text-primary">↑</i>');
|
|
} else if (direction === 'desc') {
|
|
$icon.html('<i class="text-primary">↓</i>');
|
|
} else {
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Spinner.js (babel) === */
|
|
"use strict";
|
|
|
|
class Spinner extends Component {
|
|
on_ready() {
|
|
// Apply size (sm)
|
|
if (this.args.size === 'sm') {
|
|
this.$.addClass('spinner-border-sm');
|
|
}
|
|
|
|
// Apply color
|
|
if (this.args.color) {
|
|
this.$.addClass(`text-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Stat_Card.js (babel) === */
|
|
"use strict";
|
|
|
|
class Stat_Card extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Status_Badge.js (babel) === */
|
|
"use strict";
|
|
|
|
class Status_Badge extends Component {
|
|
on_ready() {
|
|
// Apply color based on content or args
|
|
const status = this.args.status || this.$.text().trim().toLowerCase();
|
|
|
|
// Default color mappings
|
|
const color_map = {
|
|
'active': 'bg-success',
|
|
'pending': 'bg-warning',
|
|
'completed': 'bg-primary',
|
|
'cancelled': 'bg-danger',
|
|
'draft': 'bg-secondary',
|
|
'archived': 'bg-dark'
|
|
};
|
|
const bg_class = this.args.bg_class || color_map[status] || 'bg-secondary';
|
|
this.$.addClass(bg_class);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tab_Content.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tab_Content extends Component {
|
|
on_ready() {
|
|
// Ensure children have tab-pane class
|
|
this.$.children().each(function () {
|
|
const $child = $(this);
|
|
$child.addClass('tab-pane fade');
|
|
|
|
// Set first pane as active if none active
|
|
if ($child.parent().find('.tab-pane.active').length === 0 && $child.index() === 0) {
|
|
$child.addClass('show active');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Table_Pagination.js (babel) === */
|
|
"use strict";
|
|
|
|
class Table_Pagination extends Component {
|
|
on_ready() {
|
|
// Generate pagination if pages provided via args
|
|
if (this.args.current_page && this.args.total_pages) {
|
|
this.generate_pagination(this.args.current_page, this.args.total_pages);
|
|
}
|
|
}
|
|
generate_pagination(current, total) {
|
|
const $pagination = this.$sid('pagination');
|
|
$pagination.empty();
|
|
|
|
// Previous button
|
|
const $prev = $('<li>').addClass('page-item' + (current === 1 ? ' disabled' : ''));
|
|
$prev.append($('<a>').addClass('page-link').attr('href', '#').text('Previous'));
|
|
$pagination.append($prev);
|
|
|
|
// Page numbers (show 5 pages max)
|
|
let start = Math.max(1, current - 2);
|
|
let end = Math.min(total, current + 2);
|
|
for (let i = start; i <= end; i++) {
|
|
const $li = $('<li>').addClass('page-item' + (i === current ? ' active' : ''));
|
|
$li.append($('<a>').addClass('page-link').attr('href', '#').text(i));
|
|
$pagination.append($li);
|
|
}
|
|
|
|
// Next button
|
|
const $next = $('<li>').addClass('page-item' + (current === total ? ' disabled' : ''));
|
|
$next.append($('<a>').addClass('page-link').attr('href', '#').text('Next'));
|
|
$pagination.append($next);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Table.js (babel) === */
|
|
"use strict";
|
|
|
|
class Table extends Component {
|
|
on_ready() {
|
|
// Apply variant from args
|
|
if (this.args.variant) {
|
|
this.$.addClass(`table-${this.args.variant}`); // striped, bordered, borderless
|
|
}
|
|
|
|
// Apply size
|
|
if (this.args.size === 'sm') {
|
|
this.$.addClass('table-sm');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tabs.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tabs extends Component {
|
|
on_ready() {
|
|
// Wrap children in nav-item structure
|
|
this.$.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
|
|
// Set first tab as active if none active
|
|
if (this.$.find('.nav-link.active').length === 0) {
|
|
this.$.find('.nav-link').first().addClass('active');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tag_Group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tag_Group extends Component {
|
|
on_ready() {
|
|
// No special behavior needed
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tag.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tag extends Component {
|
|
on_ready() {
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
this.$.removeClass('bg-secondary').addClass(`bg-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/text_display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Text_Display extends Component {
|
|
// Generic text display - inherits Bootstrap typography
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Textarea.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Textarea - Bootstrap 5 Multi-line Text Input Component
|
|
*
|
|
* Purpose: Multi-line text input for longer content like descriptions, comments, notes
|
|
* Design: Bootstrap .form-control styling (same as Input)
|
|
*/
|
|
class Textarea extends Component {
|
|
on_ready() {
|
|
// Set rows if provided
|
|
if (this.args.rows) {
|
|
this.$.attr('rows', this.args.rows);
|
|
}
|
|
|
|
// Set placeholder if provided
|
|
if (this.args.placeholder) {
|
|
this.$.attr('placeholder', this.args.placeholder);
|
|
}
|
|
|
|
// Set value if provided (overrides content())
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Three_Column_Layout.js (babel) === */
|
|
"use strict";
|
|
|
|
class Three_Column_Layout extends Component {
|
|
on_ready() {
|
|
// Wrap each direct child in responsive column classes
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('col-12 col-md-6 col-xl-4 mb-4');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Time_Picker.js (babel) === */
|
|
"use strict";
|
|
|
|
class Time_Picker extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.min) {
|
|
$input.attr('min', this.args.min);
|
|
}
|
|
if (this.args.max) {
|
|
$input.attr('max', this.args.max);
|
|
}
|
|
if (this.args.step) {
|
|
$input.attr('step', this.args.step);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timeline.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timeline extends Component {
|
|
// Pure Bootstrap flexbox - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timestamp_Display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timestamp_Display extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tooltip.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tooltip extends Component {
|
|
on_ready() {
|
|
// Set tooltip text from args
|
|
if (this.args.text) {
|
|
this.$.attr('data-bs-title', this.args.text);
|
|
}
|
|
|
|
// Set placement
|
|
if (this.args.placement) {
|
|
this.$.attr('data-bs-placement', this.args.placement);
|
|
}
|
|
|
|
// Initialize Bootstrap tooltip
|
|
new bootstrap.Tooltip(this.$[0]);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Top_Nav.js (babel) === */
|
|
"use strict";
|
|
|
|
class Top_Nav extends Component {
|
|
on_ready() {
|
|
// Wrap children in nav structure
|
|
const $nav = this.$sid('nav_items');
|
|
$nav.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Trend_Indicator.js (babel) === */
|
|
"use strict";
|
|
|
|
class Trend_Indicator extends Component {
|
|
on_ready() {
|
|
const text = this.$.text().trim();
|
|
const is_positive = text.startsWith('+');
|
|
const is_negative = text.startsWith('-');
|
|
if (is_positive) {
|
|
this.$.addClass('text-success fw-bold');
|
|
} else if (is_negative) {
|
|
this.$.addClass('text-danger fw-bold');
|
|
} else {
|
|
this.$.addClass('text-muted fw-bold');
|
|
}
|
|
this.$.addClass('d-block mt-1');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Two_Column_Layout.js (babel) === */
|
|
"use strict";
|
|
|
|
class Two_Column_Layout extends Component {
|
|
on_ready() {
|
|
// Wrap each direct child in responsive column classes
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('col-12 col-lg-6 mb-4');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/User_Avatar_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
class User_Avatar_Dropdown extends Component {
|
|
on_ready() {
|
|
// Ensure proper dropdown item structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>');
|
|
if ($child.prop('tagName') === 'HR') {
|
|
$li.append($('<hr>').addClass('dropdown-divider'));
|
|
$child.replaceWith($li);
|
|
} else {
|
|
$child.addClass('dropdown-item');
|
|
$child.wrap($li);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/modal_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Modal_Abstract - Base class for modal orchestration classes
|
|
*
|
|
* **Philosophy**:
|
|
* Modal classes are orchestration layers that manage the lifecycle of showing
|
|
* a modal, collecting user input, and returning results. They do NOT contain
|
|
* form validation or business logic - that belongs in jqhtml components and
|
|
* controller endpoints.
|
|
*
|
|
* **Purpose**:
|
|
* - Provides a common base class for type identification
|
|
* - Enforces file naming conventions (modal classes end with _Modal)
|
|
* - Documents the modal class pattern
|
|
* - Enables framework-level features (future: discovery, validation)
|
|
*
|
|
* **Responsibilities of Modal Classes**:
|
|
* - Invoke Modal.form() / Modal.show() / Modal.confirm() with appropriate configuration
|
|
* - Handle modal lifecycle (show, submit, cancel, errors)
|
|
* - Return Promise that resolves with data or false
|
|
* - Encapsulate modal-specific UI logic
|
|
*
|
|
* **Contract**:
|
|
* All modal classes extending Modal_Abstract must implement:
|
|
* - `static async show(params)`: Primary entry point, returns Promise
|
|
*
|
|
* **Return Values**:
|
|
* - Success: Resolve with data object (e.g., created user record)
|
|
* - Cancel/Close: Resolve with false
|
|
* - Error: Show error in modal, keep open, don't resolve until user acts
|
|
*
|
|
* **Integration**:
|
|
* Modal classes use Modal.js static API (Modal.form(), Modal.show(), etc.)
|
|
* as building blocks. Form validation handled by Rsx_Form and Form_Utils.
|
|
* Page JS orchestrates modal flow but doesn't contain modal UI logic.
|
|
*
|
|
* **Pattern Examples**:
|
|
*
|
|
* Simple form modal:
|
|
* ```
|
|
* class Add_User_Modal extends Modal_Abstract {
|
|
* static async show() {
|
|
* const result = await Modal.form({
|
|
* title: 'Add User',
|
|
* component: 'Add_User_Modal_Form',
|
|
* on_submit: async (form) => {
|
|
* try {
|
|
* const values = form.vals();
|
|
* const result = await Controller.add_user(values);
|
|
* return result; // Close modal, return data
|
|
* } catch (error) {
|
|
* await form.render_error(error);
|
|
* return false; // Keep modal open
|
|
* }
|
|
* },
|
|
* });
|
|
* return result || false;
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* Custom content modal:
|
|
* ```
|
|
* class Confirm_Delete_Modal extends Modal_Abstract {
|
|
* static async show({item_name}) {
|
|
* return await Modal.confirm(
|
|
* 'Confirm Delete',
|
|
* `Are you sure you want to delete ${item_name}?`
|
|
* );
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* Modal with backend call:
|
|
* ```
|
|
* class Send_Invite_Modal extends Modal_Abstract {
|
|
* static async show(user_id) {
|
|
* const result = await Controller.send_invite({user_id});
|
|
* if (result.invite_url) {
|
|
* await Modal.alert('Invite Sent', result.invite_url);
|
|
* }
|
|
* return result;
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* **Usage Pattern**:
|
|
* ```
|
|
* // Page JS orchestrates flow, modals handle UI
|
|
* const user = await Add_User_Modal.show();
|
|
* if (user) {
|
|
* $('.Users_DataGrid').component().reload();
|
|
* await Send_User_Invite_Modal.show(user.id);
|
|
* }
|
|
* ```
|
|
*
|
|
* **Best Practices**:
|
|
* - Keep modal classes focused: one modal = one class
|
|
* - Page JS orchestrates sequence, modal classes handle individual modals
|
|
* - Modal classes don't call each other directly
|
|
* - Modal classes don't update UI (grids, lists) - page JS does that
|
|
* - Use descriptive names ending in _Modal (Add_User_Modal, Send_Invite_Modal)
|
|
* - Place feature-specific modals in feature directory
|
|
* - Place reusable modals in theme/components/modal/
|
|
*
|
|
* **When to Use Modal Classes**:
|
|
* - Multi-step forms
|
|
* - Forms with complex validation
|
|
* - Modals called from multiple places
|
|
* - Modals with backend interactions
|
|
*
|
|
* **When NOT to Use Modal Classes**:
|
|
* - Simple alerts: `await Modal.alert('Saved!')`
|
|
* - Simple confirmations: `if (await Modal.confirm('Delete?')) {...}`
|
|
* - One-off prompts: `const name = await Modal.prompt('Enter name:')`
|
|
*/
|
|
class Modal_Abstract {
|
|
// This class provides structure and documentation for modal patterns.
|
|
// Concrete modal classes extend this and implement static show() method.
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/rsx_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Modal Component
|
|
*
|
|
* Instance of a modal dialog. Handles lifecycle, sizing, and user interaction.
|
|
* Typically created and managed by the Modal static API class.
|
|
*/
|
|
class Rsx_Modal extends Component {
|
|
on_create() {
|
|
this.data.title = '';
|
|
this.data.body_content = null;
|
|
this.data.buttons = [];
|
|
this.data.closable = true;
|
|
this.data.max_width = 800;
|
|
this.data.close_on_submit = true;
|
|
this.data.is_visible = false;
|
|
this.data.result_promise = null;
|
|
this.data.resolve_fn = null;
|
|
|
|
// Store reference to bootstrap modal instance
|
|
this._bs_modal = null;
|
|
this._resize_handler = null;
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
|
|
// Set up close button handler
|
|
this.$sid('close_btn').on('click', function (e) {
|
|
e.preventDefault();
|
|
if (that.data.closable) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up backdrop click handler
|
|
this.$sid('backdrop').on('click', function (e) {
|
|
if (that.data.closable && e.target === this) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up ESC key handler
|
|
$(document).on('keydown.rsx_modal_' + this._cid, function (e) {
|
|
if (e.key === 'Escape' && that.data.closable && that.data.is_visible) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up resize handler
|
|
this._resize_handler = debounce(() => {
|
|
if (that.data.is_visible) {
|
|
that._apply_sizing();
|
|
}
|
|
}, 100);
|
|
$(window).on('resize.rsx_modal_' + this._cid, this._resize_handler);
|
|
}
|
|
|
|
/**
|
|
* Configure and show the modal
|
|
* @param {Object} options - Modal options (title, body, buttons, etc.)
|
|
* @param {Object} internal_options - Internal options (skip_backdrop, animate)
|
|
*/
|
|
async show(options) {
|
|
let internal_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
const that = this;
|
|
const skip_backdrop = internal_options.skip_backdrop || false;
|
|
const should_animate = internal_options.animate || false;
|
|
console.log('[Rsx_Modal] show() called with options:', options);
|
|
|
|
// Store options
|
|
this.data.title = options.title || '';
|
|
this.data.closable = options.closable !== undefined ? options.closable : true;
|
|
this.data.max_width = options.max_width || 800;
|
|
this.data.close_on_submit = options.close_on_submit !== undefined ? options.close_on_submit : true;
|
|
this.data.buttons = options.buttons || [];
|
|
this.data.skip_backdrop = skip_backdrop;
|
|
this.data.icon = options.icon || null;
|
|
console.log('[Rsx_Modal] Setting title to:', this.data.title);
|
|
console.log('[Rsx_Modal] Title element:', this.$sid('title'));
|
|
|
|
// Set title
|
|
this.$sid('title').text(this.data.title);
|
|
|
|
// Show/hide close button based on closable
|
|
if (this.data.closable) {
|
|
this.$sid('close_btn').show();
|
|
} else {
|
|
this.$sid('close_btn').hide();
|
|
}
|
|
|
|
// Set body content (with optional icon)
|
|
this._set_body_content(options.body, this.data.icon);
|
|
|
|
// Set buttons
|
|
this._set_buttons();
|
|
|
|
// Create promise that will resolve when modal closes
|
|
const result_promise = new Promise(resolve => {
|
|
that.data.resolve_fn = resolve;
|
|
});
|
|
|
|
// Show modal and backdrop
|
|
this.data.is_visible = true;
|
|
|
|
// Append to body so it's on top (don't append backdrop if using shared)
|
|
if (!skip_backdrop) {
|
|
$('body').append(this.$sid('backdrop'));
|
|
}
|
|
$('body').append(this.$);
|
|
|
|
// Apply sizing before showing
|
|
this._apply_sizing();
|
|
|
|
// Fade in modal (and backdrop if not using shared)
|
|
await this._fade_in(should_animate);
|
|
|
|
// Auto-focus first input element
|
|
this._focus_first_input();
|
|
return result_promise;
|
|
}
|
|
|
|
/**
|
|
* Set body content with optional icon
|
|
*/
|
|
_set_body_content(body, icon) {
|
|
const $body = this.$sid('body');
|
|
$body.empty();
|
|
|
|
// If icon provided, add it
|
|
if (icon) {
|
|
const $icon = $(`<i class="bi bi-${icon} modal-icon"></i>`);
|
|
$body.append($icon);
|
|
$body.addClass('has-icon');
|
|
} else {
|
|
$body.removeClass('has-icon');
|
|
}
|
|
|
|
// Get or create body content wrapper
|
|
let $content = this.$sid('body_content');
|
|
if (!$content.exists()) {
|
|
$content = $('<div class="modal-body-content"></div>');
|
|
$body.append($content);
|
|
}
|
|
if (typeof body === 'string') {
|
|
// Text content - escape and convert newlines
|
|
const escaped = $('<div>').text(body).html().replace(/\n/g, '<br>');
|
|
$content.html(escaped);
|
|
} else if (body instanceof jQuery) {
|
|
// jQuery element
|
|
$content.append(body);
|
|
} else if (body && typeof body === 'object') {
|
|
// Assume it's a jqhtml component instance
|
|
$content.append(body.$);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set buttons in footer
|
|
*/
|
|
_set_buttons() {
|
|
const that = this;
|
|
const $footer = this.$sid('footer');
|
|
$footer.empty();
|
|
if (this.data.buttons.length === 0) {
|
|
$footer.hide();
|
|
return;
|
|
}
|
|
$footer.show();
|
|
for (let button_def of this.data.buttons) {
|
|
const $button = $('<button>').attr('type', 'button').addClass('btn').addClass(button_def.class || 'btn-secondary').text(button_def.label || 'Button');
|
|
$button.on('click', async function () {
|
|
let result = button_def.value;
|
|
let had_callback = false;
|
|
|
|
// If button has a callback, call it and use return value as result
|
|
if (button_def.callback && typeof button_def.callback === 'function') {
|
|
had_callback = true;
|
|
result = await button_def.callback();
|
|
}
|
|
|
|
// If callback returned false, keep modal open (but not if just button value is false)
|
|
if (result === false && had_callback) {
|
|
return;
|
|
}
|
|
|
|
// Close modal with result
|
|
that.close(result);
|
|
});
|
|
$footer.append($button);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate and apply responsive sizing
|
|
*/
|
|
_apply_sizing() {
|
|
const viewport_width = $(window).width();
|
|
const viewport_height = $(window).height();
|
|
const is_mobile = viewport_width < 768;
|
|
|
|
// Calculate max width based on viewport
|
|
let max_width = this.data.max_width;
|
|
const viewport_limit = is_mobile ? viewport_width * 0.9 : viewport_width * 0.8;
|
|
max_width = Math.min(max_width, viewport_limit);
|
|
|
|
// Try to constrain to 60% width for better proportions on desktop
|
|
if (!is_mobile) {
|
|
const preferred_width = viewport_width * 0.6;
|
|
if (preferred_width < max_width) {
|
|
max_width = preferred_width;
|
|
}
|
|
}
|
|
|
|
// Apply width
|
|
this.$sid('dialog').css('max-width', max_width + 'px');
|
|
|
|
// Check if content exceeds 80% height
|
|
const content_height = this.$sid('dialog').outerHeight();
|
|
const max_height = viewport_height * 0.8;
|
|
if (content_height > max_height) {
|
|
// Enable scrolling
|
|
this.$sid('dialog').css('max-height', max_height + 'px');
|
|
this.$sid('body').css({
|
|
'overflow-y': 'auto',
|
|
'max-height': max_height - 150 + 'px' // Account for header/footer
|
|
});
|
|
} else {
|
|
// Reset scrolling
|
|
this.$sid('dialog').css('max-height', '');
|
|
this.$sid('body').css({
|
|
'overflow-y': '',
|
|
'max-height': ''
|
|
});
|
|
}
|
|
|
|
// Mobile edge spacing
|
|
if (is_mobile) {
|
|
this.$sid('dialog').css('margin', '5%');
|
|
} else {
|
|
this.$sid('dialog').css('margin', '0');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show animation (instant or with fly-in)
|
|
* @param {boolean} animate - Whether to animate the modal entrance
|
|
*/
|
|
async _fade_in() {
|
|
let animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
if (animate) {
|
|
// Initial state: modal positioned above final position
|
|
this.$.css('display', 'flex').css('opacity', '0');
|
|
this.$sid('modal').css({
|
|
'transform': 'translate(0, -50px)',
|
|
'opacity': '0'
|
|
});
|
|
this.$sid('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow
|
|
this.$sid('modal')[0].offsetHeight;
|
|
|
|
// Trigger animation
|
|
this.$sid('modal').addClass('show').css({
|
|
'transform': 'translate(0, 0)',
|
|
'opacity': '1'
|
|
});
|
|
this.$.css('opacity', '1');
|
|
|
|
// Wait for animation to complete
|
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
} else {
|
|
// Disable transitions temporarily for instant display
|
|
this.$sid('dialog').css('transition', 'none');
|
|
|
|
// Show modal and backdrop instantly
|
|
this.$.css('display', 'flex').css('opacity', '1');
|
|
this.$sid('modal').addClass('show').css('opacity', '1');
|
|
this.$sid('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow to apply the no-transition state
|
|
this.$sid('dialog')[0].offsetHeight;
|
|
|
|
// Re-enable transitions for future animations
|
|
this.$sid('dialog').css('transition', '');
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
|
|
/**
|
|
* Focus the first input element in the modal
|
|
*/
|
|
_focus_first_input() {
|
|
// Find first input/textarea/select in modal body
|
|
const $first_input = this.$sid('body').find('input:not([type="hidden"]), textarea, select').first();
|
|
if ($first_input.exists()) {
|
|
requestAnimationFrame(() => {
|
|
$first_input.focus();
|
|
// Select text if it's an input with existing value
|
|
if ($first_input.is('input[type="text"], input[type="email"]') && $first_input.val()) {
|
|
$first_input.select();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close the modal instantly
|
|
*/
|
|
async close(result) {
|
|
const that = this;
|
|
|
|
// Mark as not visible
|
|
this.data.is_visible = false;
|
|
|
|
// Remove event listeners
|
|
$(document).off('keydown.rsx_modal_' + this._cid);
|
|
$(window).off('resize.rsx_modal_' + this._cid);
|
|
|
|
// Hide instantly (no fade out)
|
|
this.$.hide();
|
|
this.$sid('backdrop').hide();
|
|
|
|
// Remove from DOM
|
|
this.$.remove();
|
|
this.$sid('backdrop').remove();
|
|
|
|
// Resolve promise
|
|
if (this.data.resolve_fn) {
|
|
this.data.resolve_fn(result);
|
|
this.data.resolve_fn = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply validation errors to form fields in modal body
|
|
*/
|
|
apply_errors(errors) {
|
|
// Use Form_Utils to apply errors to elements within modal body
|
|
Form_Utils.apply_form_errors(this.$sid('body'), errors);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/Modal.js (babel) === */
|
|
"use strict";
|
|
|
|
function _d1f5a3cb_defineProperty(e, r, t) { return (r = _d1f5a3cb_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _d1f5a3cb_toPropertyKey(t) { var i = _d1f5a3cb_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _d1f5a3cb_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
/**
|
|
* Modal Static API
|
|
*
|
|
* Primary interface for displaying modals throughout the application.
|
|
* Provides simple methods for common dialogs and flexible options for custom modals.
|
|
*
|
|
* Usage:
|
|
* await Modal.alert("File saved")
|
|
* if (await Modal.confirm("Delete?")) { ... }
|
|
* let name = await Modal.prompt("Enter name:")
|
|
* let result = await Modal.show({ title, body, buttons })
|
|
*/
|
|
class Modal {
|
|
/**
|
|
* Initialize global handlers (called automatically on first modal)
|
|
* @private
|
|
*/
|
|
static _init() {
|
|
if (this._initialized) return;
|
|
this._initialized = true;
|
|
|
|
// Create shared backdrop element
|
|
this._backdrop = $('<div class="modal-backdrop fade"></div>');
|
|
$('body').append(this._backdrop);
|
|
}
|
|
|
|
/**
|
|
* Calculate scrollbar width
|
|
* @private
|
|
* @returns {number}
|
|
*/
|
|
static _get_scrollbar_width() {
|
|
// Create temporary element to measure scrollbar width
|
|
const $outer = $('<div>').css({
|
|
visibility: 'hidden',
|
|
overflow: 'scroll',
|
|
width: '100px',
|
|
position: 'absolute',
|
|
top: '-9999px'
|
|
});
|
|
$('body').append($outer);
|
|
const width_with_scrollbar = $outer[0].offsetWidth;
|
|
const $inner = $('<div>').css('width', '100%');
|
|
$outer.append($inner);
|
|
const width_without_scrollbar = $inner[0].offsetWidth;
|
|
$outer.remove();
|
|
return width_with_scrollbar - width_without_scrollbar;
|
|
}
|
|
|
|
/**
|
|
* Lock body scroll and compensate for scrollbar width
|
|
* Only locks if we haven't already saved the original state (first modal in chain)
|
|
* @private
|
|
*/
|
|
static _lock_body_scroll() {
|
|
// Cancel any pending unlock timeout
|
|
if (this._unlock_timeout) {
|
|
clearTimeout(this._unlock_timeout);
|
|
this._unlock_timeout = null;
|
|
}
|
|
|
|
// Only lock scroll if we haven't already saved state (first modal)
|
|
// This is the true indicator - not backdrop visibility which can be transitional
|
|
if (this._original_body_overflow === null) {
|
|
const $body = $('body');
|
|
|
|
// Store original values
|
|
this._original_body_overflow = $body.css('overflow');
|
|
this._original_body_padding = $body.css('padding-right');
|
|
|
|
// Check if body currently has vertical scroll
|
|
const has_scrollbar = document.body.scrollHeight > window.innerHeight;
|
|
|
|
// If there's a scrollbar, add padding to compensate for its removal
|
|
if (has_scrollbar) {
|
|
const scrollbar_width = this._get_scrollbar_width();
|
|
const current_padding = int(this._original_body_padding) || 0;
|
|
$body.css('padding-right', current_padding + scrollbar_width + 'px');
|
|
}
|
|
|
|
// Lock scroll
|
|
$body.css('overflow', 'hidden');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unlock body scroll and restore original state
|
|
* Uses delayed check to ensure no other modals are opening
|
|
* @private
|
|
*/
|
|
static _unlock_body_scroll() {
|
|
// Clear any existing timeout
|
|
if (this._unlock_timeout) {
|
|
clearTimeout(this._unlock_timeout);
|
|
}
|
|
|
|
// Minimal delay before unlocking
|
|
this._unlock_timeout = setTimeout(() => {
|
|
// Double-check no modal is currently open and queue is empty
|
|
if (!this._current && this._queue.length === 0) {
|
|
const $body = $('body');
|
|
|
|
// Restore original values
|
|
if (this._original_body_overflow !== null) {
|
|
$body.css('overflow', this._original_body_overflow);
|
|
this._original_body_overflow = null;
|
|
}
|
|
if (this._original_body_padding !== null) {
|
|
$body.css('padding-right', this._original_body_padding);
|
|
this._original_body_padding = null;
|
|
}
|
|
}
|
|
this._unlock_timeout = null;
|
|
}, 50); // Minimal safety buffer
|
|
}
|
|
|
|
/**
|
|
* Show the shared backdrop (instant - no animation)
|
|
* @private
|
|
*/
|
|
static async _show_backdrop() {
|
|
if (!this._backdrop.hasClass('show')) {
|
|
// Lock body scroll before showing backdrop
|
|
this._lock_body_scroll();
|
|
this._backdrop.css('display', 'block').addClass('show');
|
|
// No delay - return immediately
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hide the shared backdrop (instant - no animation)
|
|
* @private
|
|
*/
|
|
static async _hide_backdrop() {
|
|
this._backdrop.removeClass('show').css('display', 'none');
|
|
|
|
// Unlock body scroll after backdrop is hidden
|
|
this._unlock_body_scroll();
|
|
}
|
|
|
|
/**
|
|
* Create a new Rsx_Modal instance
|
|
* @private
|
|
*/
|
|
static async _create_modal() {
|
|
// Create modal component using jQuery plugin
|
|
const $modal_element = $('<div>');
|
|
|
|
// Create component instance directly (returns the component)
|
|
const modal_instance = $modal_element.component('Rsx_Modal', {});
|
|
|
|
// Wait for component to be fully ready (DOM elements queryable)
|
|
await new Promise(resolve => {
|
|
modal_instance.on('ready', () => {
|
|
console.log('[Modal] Component ready, elements:', {
|
|
title: modal_instance.$sid('title').length,
|
|
body: modal_instance.$sid('body').length,
|
|
footer: modal_instance.$sid('footer').length
|
|
});
|
|
resolve();
|
|
});
|
|
});
|
|
return modal_instance;
|
|
}
|
|
|
|
/**
|
|
* Show a modal and manage queue
|
|
* @private
|
|
*/
|
|
static async _show_modal(options) {
|
|
return new Promise(resolve => {
|
|
this._queue.push({
|
|
options,
|
|
resolve
|
|
});
|
|
|
|
// Process queue if no modal currently showing
|
|
if (!this._current) {
|
|
this._process_queue();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Process the modal queue
|
|
* @private
|
|
*/
|
|
static async _process_queue() {
|
|
if (this._queue.length === 0) {
|
|
this._current = null;
|
|
// Hide backdrop when queue is empty
|
|
await this._hide_backdrop();
|
|
return;
|
|
}
|
|
const {
|
|
options,
|
|
resolve
|
|
} = this._queue.shift();
|
|
|
|
// Ensure initialized
|
|
this._init();
|
|
|
|
// Show backdrop if not already visible (instant - no delay between modals)
|
|
const backdrop_visible = this._backdrop.hasClass('show');
|
|
if (!backdrop_visible) {
|
|
await this._show_backdrop();
|
|
}
|
|
// No delay between sequential modals - immediate transition
|
|
|
|
// Create modal instance
|
|
const modal_instance = await this._create_modal();
|
|
this._current = modal_instance;
|
|
|
|
// Determine if we should animate based on:
|
|
// 1. Desktop viewport (>= 1000px)
|
|
// 2. More than 1 second since last modal closed
|
|
const viewport_width = $(window).width();
|
|
const is_desktop = viewport_width >= 1000;
|
|
const time_since_last_close = Date.now() - this._last_close_timestamp;
|
|
const should_animate = is_desktop && time_since_last_close > 1000;
|
|
|
|
// Show modal and wait for result (modal won't create its own backdrop)
|
|
const result = await modal_instance.show(options, {
|
|
skip_backdrop: true,
|
|
animate: should_animate
|
|
});
|
|
|
|
// Record close timestamp BEFORE resolving (ensures it's set before next modal can start)
|
|
this._last_close_timestamp = Date.now();
|
|
|
|
// Resolve the promise with the result
|
|
resolve(result);
|
|
|
|
// Clear current and process next
|
|
this._current = null;
|
|
this._process_queue();
|
|
}
|
|
|
|
// ================================================================================
|
|
// State Management Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Check if a modal is currently open
|
|
* @returns {boolean}
|
|
*/
|
|
static is_open() {
|
|
return this._current !== null;
|
|
}
|
|
|
|
/**
|
|
* Get the currently open modal instance
|
|
* @returns {Rsx_Modal|null}
|
|
*/
|
|
static get_current() {
|
|
return this._current;
|
|
}
|
|
|
|
/**
|
|
* Force close the current modal
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async close() {
|
|
if (this._current) {
|
|
await this._current.close(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply validation errors to the current modal
|
|
* @param {Object} errors - Error object {field: message}
|
|
*/
|
|
static apply_errors(errors) {
|
|
if (this._current) {
|
|
this._current.apply_errors(errors);
|
|
}
|
|
}
|
|
|
|
// ================================================================================
|
|
// Simple Dialog Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show an alert dialog
|
|
* @param {string|jQuery} title_or_body - Message (if only 1 arg) or Title (if 2 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (if 2 args). Can be string or jQuery element.
|
|
* @param {string} button_label - Button text (default: "OK")
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async alert(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let button_label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'OK';
|
|
let title = 'Notice';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [{
|
|
label: button_label,
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show a confirmation dialog
|
|
* @param {string|jQuery} title_or_body - Message (if 1-2 args) or Title (if 3-4 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (optional). Can be string or jQuery element.
|
|
* @param {string} confirm_label - Confirm button text (default: "Confirm")
|
|
* @param {string} cancel_label - Cancel button text (default: "Cancel")
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
static async confirm(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let confirm_label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Confirm';
|
|
let cancel_label = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'Cancel';
|
|
let title = 'Confirm';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
const result = await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [{
|
|
label: cancel_label,
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: confirm_label,
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
return result === true;
|
|
}
|
|
|
|
/**
|
|
* Show a prompt dialog for text input
|
|
* @param {string|jQuery} title_or_body - Message (if 1-3 args) or Title (if 4 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (optional). Can be string or jQuery element.
|
|
* @param {string} default_value - Default input value
|
|
* @param {boolean} multiline - Show textarea instead of input
|
|
* @param {string} error - Optional error message to display as validation feedback
|
|
* @returns {Promise<string|false>}
|
|
*/
|
|
static async prompt(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let default_value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
|
let multiline = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
let error = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
let title = 'Input';
|
|
let message = title_or_body;
|
|
|
|
// Handle overloaded arguments
|
|
if (typeof body === 'string' && body !== '') {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
|
|
// Create input element with minimum width constraints
|
|
const $input = multiline ? $('<textarea class="form-control" rows="4" style="min-width: 315px;"></textarea>') : $('<input type="text" class="form-control" style="min-width: 245px;">');
|
|
$input.val(default_value);
|
|
|
|
// Mark as invalid if there's an error
|
|
if (error) {
|
|
$input.addClass('is-invalid');
|
|
}
|
|
|
|
// Create body with message and input
|
|
let $body;
|
|
if (message instanceof jQuery) {
|
|
// If message is a jQuery element, use it as the container and append input
|
|
$body = message.append($input);
|
|
} else {
|
|
// If message is a string, create wrapper with text and input (36px spacing)
|
|
$body = $('<div class="form-group">').append($('<div style="margin-bottom: 36px;">').text(message)).append($input);
|
|
}
|
|
|
|
// Add error message if provided
|
|
if (error) {
|
|
const $error = $('<div class="invalid-feedback d-block"></div>').text(error);
|
|
$body.append($error);
|
|
}
|
|
const result = await this._show_modal({
|
|
title: title,
|
|
body: $body,
|
|
buttons: [{
|
|
label: 'Cancel',
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: 'Submit',
|
|
value: null,
|
|
// Will be replaced by callback
|
|
class: 'btn-primary',
|
|
default: true,
|
|
callback: function () {
|
|
return $input.val();
|
|
}
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true,
|
|
max_width: 500
|
|
});
|
|
|
|
// Focus and select input after modal shows
|
|
requestAnimationFrame(() => {
|
|
$input.focus();
|
|
if (!multiline) {
|
|
$input.select();
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Show an error dialog with red alert styling
|
|
*
|
|
* Can appear over other modals to show critical uncaught exceptions.
|
|
* Used primarily for Ajax errors that weren't caught by application code.
|
|
*
|
|
* @param {string|Error|Object} error - Error message string, Error object, or structured error
|
|
* @param {string} title - Modal title (default: "Error")
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async error(error) {
|
|
let title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Error';
|
|
let message = '';
|
|
|
|
// Handle different error types
|
|
if (typeof error === 'string') {
|
|
message = error;
|
|
} else if (error instanceof Error) {
|
|
message = error.message || error.toString();
|
|
} else if (error && error.message) {
|
|
message = error.message;
|
|
} else if (error && error.error) {
|
|
// Fatal error with details
|
|
const details = error.error;
|
|
if (details.file && details.line) {
|
|
message = `Uncaught Fatal Error in ${details.file}:${details.line}:\n\n${details.error}`;
|
|
} else {
|
|
message = details.error || 'An unknown error occurred';
|
|
}
|
|
} else {
|
|
message = 'An unknown error occurred';
|
|
}
|
|
|
|
// Create error body with red alert styling
|
|
const $body = $('<div class="alert alert-danger mb-0" role="alert">').append($('<pre class="mb-0" style="white-space: pre-wrap; word-wrap: break-word; font-family: monospace; font-size: 0.9em;">').text(message));
|
|
await this._show_modal({
|
|
title: title,
|
|
body: $body,
|
|
buttons: [{
|
|
label: 'Close',
|
|
value: true,
|
|
class: 'btn-danger',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true,
|
|
max_width: 600
|
|
});
|
|
}
|
|
|
|
// ================================================================================
|
|
// Custom Modal Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show a custom modal with specified content and buttons
|
|
* @param {Object} options
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async show(options) {
|
|
const defaults = {
|
|
title: 'Modal',
|
|
body: '',
|
|
buttons: [],
|
|
max_width: 800,
|
|
closable: true,
|
|
close_on_submit: true
|
|
};
|
|
const final_options = Object.assign({}, defaults, options);
|
|
return await this._show_modal(final_options);
|
|
}
|
|
|
|
/**
|
|
* Show a modal with a jqhtml form component
|
|
* @param {Object} options
|
|
* @param {string} options.component - Component class name
|
|
* @param {Object} options.component_args - Arguments to pass to component
|
|
* @param {Function} options.on_submit - Callback function called on submit. Receives form component instance.
|
|
* Return false to keep modal open, or return data to close and resolve.
|
|
* @returns {Promise<Object|false>}
|
|
*/
|
|
static async form(options) {
|
|
const defaults = {
|
|
title: 'Form',
|
|
component: null,
|
|
component_args: {},
|
|
max_width: 800,
|
|
closable: true,
|
|
submit_label: 'Submit',
|
|
cancel_label: 'Cancel',
|
|
on_submit: null
|
|
};
|
|
const final_options = Object.assign({}, defaults, options);
|
|
if (!final_options.component) {
|
|
console.error('Modal.form() requires a component');
|
|
return false;
|
|
}
|
|
|
|
// Create component instance
|
|
let $component_container = $('<div>');
|
|
let component_instance = $component_container.component(final_options.component, final_options.component_args);
|
|
|
|
// Wait for component to be ready
|
|
await new Promise(resolve => {
|
|
component_instance.on('ready', () => resolve());
|
|
});
|
|
|
|
// Find a form instance if component instance doesnt have .vals()
|
|
if (!component_instance.vals) {
|
|
let $form = component_instance.$.find('.Rsx_Form');
|
|
if ($form.exists()) {
|
|
component_instance = $form.component();
|
|
}
|
|
}
|
|
|
|
// Create buttons
|
|
const buttons = [{
|
|
label: final_options.cancel_label,
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: final_options.submit_label,
|
|
value: null,
|
|
class: 'btn-primary',
|
|
default: true,
|
|
callback: async function () {
|
|
// If on_submit callback provided, use it
|
|
if (final_options.on_submit && typeof final_options.on_submit === 'function') {
|
|
const result = await final_options.on_submit(component_instance);
|
|
// If callback returns null/undefined, keep modal open
|
|
if (result === null || result === undefined) {
|
|
return false;
|
|
}
|
|
// Otherwise (including false), return the result to close modal
|
|
return result;
|
|
}
|
|
|
|
// No on_submit callback - get form data and close modal
|
|
if (component_instance.submit && typeof component_instance.submit === 'function') {
|
|
return await component_instance.submit();
|
|
} else if (component_instance.vals && typeof component_instance.vals === 'function') {
|
|
return component_instance.vals();
|
|
} else {
|
|
console.warn('Form component has no submit() or vals() method');
|
|
return true;
|
|
}
|
|
}
|
|
}];
|
|
return await this._show_modal({
|
|
title: final_options.title,
|
|
body: component_instance.$,
|
|
buttons: buttons,
|
|
max_width: final_options.max_width,
|
|
closable: final_options.closable
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show an unclosable modal
|
|
* @param {string} title_or_body
|
|
* @param {string} body
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async unclosable(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let title = 'Please Wait';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
|
|
// Don't wait for this promise - it never resolves until closed manually
|
|
this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [],
|
|
// No buttons
|
|
closable: false,
|
|
// Can't close
|
|
close_on_submit: false
|
|
});
|
|
|
|
// Wait for next animation frame for modal to render
|
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
|
}
|
|
|
|
/**
|
|
* Show a modal with custom jQuery content
|
|
* @param {Object} options
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async custom(options) {
|
|
// Alias for show() - same functionality
|
|
return await this.show(options);
|
|
}
|
|
|
|
// ================================================================================
|
|
// Helper Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show an error alert
|
|
* @param {*} errors
|
|
* @param {string} title
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async error(errors) {
|
|
let title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Error';
|
|
let message = 'An error occurred';
|
|
|
|
// Handle various error formats
|
|
if (typeof errors === 'string') {
|
|
message = errors;
|
|
} else if (errors && 'responseJSON' in errors && 'message' in errors.responseJSON) {
|
|
message = errors.responseJSON.message;
|
|
} else if (errors && 'message' in errors) {
|
|
message = errors.message;
|
|
} else if (errors && typeof errors === 'object') {
|
|
// Try to format error object
|
|
const error_messages = [];
|
|
for (const key in errors) {
|
|
if (is_array(errors[key])) {
|
|
error_messages.push(errors[key][0]);
|
|
} else {
|
|
error_messages.push(errors[key]);
|
|
}
|
|
}
|
|
if (error_messages.length > 0) {
|
|
message = error_messages.join('\n');
|
|
}
|
|
}
|
|
await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
icon: 'exclamation-circle',
|
|
buttons: [{
|
|
label: 'OK',
|
|
value: true,
|
|
class: 'btn-danger',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reopen current modal with validation errors
|
|
* @param {Object} errors
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async reopen_with_errors(errors) {
|
|
if (this._current) {
|
|
// Modal is still open, just apply errors
|
|
this.apply_errors(errors);
|
|
} else {
|
|
console.warn('No modal open to apply errors to');
|
|
}
|
|
}
|
|
}
|
|
// Internal state
|
|
_d1f5a3cb_defineProperty(Modal, "_queue", []);
|
|
_d1f5a3cb_defineProperty(Modal, "_current", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_initialized", false);
|
|
_d1f5a3cb_defineProperty(Modal, "_backdrop", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_original_body_overflow", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_original_body_padding", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_unlock_timeout", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_last_close_timestamp", 0);
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/breadcrumb_item.js (babel) === */
|
|
"use strict";
|
|
|
|
class Breadcrumb_Item extends Component {
|
|
on_create() {
|
|
// Read href from HTML attribute if present
|
|
const href = this.$.attr('href');
|
|
if (href) {
|
|
this.args.href = href;
|
|
}
|
|
|
|
// Read active from HTML attribute if present
|
|
const active = this.$.attr('active');
|
|
if (active !== undefined) {
|
|
this.args.active = true;
|
|
this.$.addClass('active');
|
|
this.$.attr('aria-current', 'page');
|
|
this.$.removeAttr('active'); // Remove the attribute after reading
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/client_label_link.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Label_Link extends Component {
|
|
on_create() {
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Convert client_id to number if it's a numeric string
|
|
if (this.args.client_id) {
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(this.args.client_id);
|
|
}
|
|
}
|
|
async on_load() {
|
|
// Load client data if we have an ID
|
|
if (this.args.client_id) {
|
|
try {
|
|
this.data.client = await Frontend_Contacts_Controller.get_client({
|
|
client_id: this.args.client_id
|
|
});
|
|
this.data.loading = false;
|
|
} catch (error) {
|
|
console.error('Failed to load client:', error);
|
|
this.data.loading = false;
|
|
}
|
|
} else {
|
|
this.data.loading = false;
|
|
}
|
|
}
|
|
on_render() {
|
|
// Set href dynamically after each render
|
|
if (this.args.client_id) {
|
|
const href = Rsx.Route('Frontend_Clients_Controller', 'view', this.args.client_id);
|
|
this.$.attr('href', href);
|
|
} else {
|
|
this.$.attr('href', '#');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set the client_id
|
|
* @param {number} [client_id] - If provided, sets the client_id and reloads
|
|
* @returns {number} Current client_id when called as getter
|
|
*/
|
|
val(client_id) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.args.client_id;
|
|
} else {
|
|
// Setter - update client_id and reload
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(client_id);
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Reload client data and re-render (on_render will update href)
|
|
this.on_load().then(() => {
|
|
this.render();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/client_label.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Label extends Component {
|
|
on_create() {
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Convert client_id to number if it's a numeric string
|
|
if (this.args.client_id) {
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(this.args.client_id);
|
|
}
|
|
}
|
|
async on_load() {
|
|
// Load client data if we have an ID
|
|
if (this.args.client_id) {
|
|
try {
|
|
this.data.client = await Frontend_Contacts_Controller.get_client({
|
|
client_id: this.args.client_id
|
|
});
|
|
this.data.loading = false;
|
|
} catch (error) {
|
|
console.error('Failed to load client:', error);
|
|
this.data.loading = false;
|
|
}
|
|
} else {
|
|
this.data.loading = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set the client_id
|
|
* @param {number} [client_id] - If provided, sets the client_id and reloads
|
|
* @returns {number} Current client_id when called as getter
|
|
*/
|
|
val(client_id) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.args.client_id;
|
|
} else {
|
|
// Setter - update client_id and reload
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(client_id);
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Reload client data and re-render (on_render will update href)
|
|
this.on_load().then(() => {
|
|
this.render();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/form_input_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Input_Abstract - Base class for all form input widgets
|
|
*
|
|
* Defines the interface that all form widgets must implement.
|
|
* This ensures consistency across all input types (text, select, wysiwyg, etc.)
|
|
*
|
|
* REQUIRED METHODS (must be implemented by subclasses):
|
|
* - val() - Get current value (no arguments)
|
|
* - val(value) - Set value (one argument)
|
|
* - seed() - Fills the widget with random test data (optional)
|
|
*
|
|
* All widgets must:
|
|
* - Have .Widget CSS class
|
|
* - Have data-name attribute set by Form_Field
|
|
*/
|
|
class Form_Input_Abstract extends Component {
|
|
/**
|
|
* val() - Get or set the current value
|
|
* Subclasses MUST implement this method
|
|
*
|
|
* @param {*} [value] - If provided, sets the value. If omitted, returns the value.
|
|
* @returns {*} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
throw new Error(`${this.constructor.name} must implement val() getter`);
|
|
} else {
|
|
// Setter
|
|
throw new Error(`${this.constructor.name} must implement val(value) setter`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Seed - Fill with random test data (optional)
|
|
* Subclasses MAY implement this method
|
|
*/
|
|
async seed() {
|
|
// Optional - widgets can override if they support seeding
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/text_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Text_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.value = '';
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the input value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.$sid('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this.data.value);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
if (this.args.seeder) {
|
|
// TODO: Implement Rsx_Random_Values endpoint
|
|
// let value = await Rsx_Random_Values[this.args.seeder]();
|
|
// For now, just use placeholder text
|
|
let value = 'Test ' + (this.args.seeder || 'Value');
|
|
this.val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/checkbox_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Checkbox_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.checked = false;
|
|
this.checked_value = this.args.checked_value || '1';
|
|
this.unchecked_value = this.args.unchecked_value || '0';
|
|
}
|
|
on_ready() {
|
|
// Connect label clicks to checkbox
|
|
const $input = this.$sid('input');
|
|
const $label = this.$sid('label');
|
|
if ($label.exists()) {
|
|
const input_id = $input.attr('id');
|
|
$label.attr('for', input_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the checkbox state
|
|
* @param {string|boolean} [value] - If provided, sets the checked state
|
|
* @returns {string} The checked_value or unchecked_value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
const is_checked = this.$sid('input').prop('checked');
|
|
return is_checked ? this.checked_value : this.unchecked_value;
|
|
} else {
|
|
// Setter - accepts boolean, checked_value, or unchecked_value
|
|
let should_check = false;
|
|
if (typeof value === 'boolean') {
|
|
should_check = value;
|
|
} else if (value === this.checked_value || value === '1' || value === 1 || value === true) {
|
|
should_check = true;
|
|
}
|
|
this.data.checked = should_check;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').prop('checked', should_check);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
// Randomly check or uncheck
|
|
this.val(Math.random() > 0.5);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/wysiwyg_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Wysiwyg_Input - WYSIWYG editor widget using Quill
|
|
*
|
|
* Implements the form widget interface:
|
|
* - val() - Get/set HTML content
|
|
* - seed() - Fills with random content
|
|
*/
|
|
class Wysiwyg_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.quill = null;
|
|
}
|
|
on_ready() {
|
|
// Wait for Quill to be loaded, then initialize
|
|
const that = this;
|
|
quill_ready(function () {
|
|
that._initialize_quill();
|
|
});
|
|
}
|
|
_initialize_quill() {
|
|
// Initialize Quill editor
|
|
this.quill = new Quill(this.$sid('editor')[0], {
|
|
theme: 'snow',
|
|
placeholder: this.args.placeholder || 'Enter text...',
|
|
modules: {
|
|
toolbar: [[{
|
|
'header': [1, 2, 3, false]
|
|
}], ['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{
|
|
'list': 'ordered'
|
|
}, {
|
|
'list': 'bullet'
|
|
}], [{
|
|
'indent': '-1'
|
|
}, {
|
|
'indent': '+1'
|
|
}], ['link', 'image'], ['clean']]
|
|
}
|
|
});
|
|
|
|
// Update hidden input on text change
|
|
const that = this;
|
|
this.quill.on('text-change', function () {
|
|
that.$sid('hidden_input').val(that.quill.root.innerHTML);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set HTML content
|
|
* @param {string} [value] - If provided, sets the HTML content
|
|
* @returns {string} The HTML content when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (!this.quill) return '';
|
|
return this.quill.root.innerHTML;
|
|
} else {
|
|
// Setter
|
|
if (!this.quill) {
|
|
// Quill not ready yet, wait and try again
|
|
const that = this;
|
|
setTimeout(() => that.val(value), 100);
|
|
return;
|
|
}
|
|
if (value) {
|
|
this.quill.root.innerHTML = value;
|
|
this.$sid('hidden_input').val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Seed - Fill with random content for testing
|
|
*/
|
|
async seed() {
|
|
if (!this.quill) return;
|
|
const sample_content = `
|
|
<h2>Sample Heading</h2>
|
|
<p>This is a sample paragraph with <strong>bold text</strong> and <em>italic text</em>.</p>
|
|
<ul>
|
|
<li>First bullet point</li>
|
|
<li>Second bullet point</li>
|
|
<li>Third bullet point</li>
|
|
</ul>
|
|
<p>Another paragraph with <a href="#">a sample link</a>.</p>
|
|
`;
|
|
this.val(sample_content);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Select_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.value = '';
|
|
|
|
// Parse options if passed as JSON string
|
|
if (typeof this.args.options === 'string') {
|
|
try {
|
|
// Decode HTML entities before parsing JSON
|
|
// This handles cases where JSON is passed through Blade {!! !!} syntax
|
|
const decoded = $('<textarea>').html(this.args.options).text();
|
|
this.args.options = json_decode(decoded);
|
|
} catch (e) {
|
|
console.error('Failed to parse options JSON:', e);
|
|
this.args.options = [];
|
|
}
|
|
}
|
|
|
|
// Convert object options to array format
|
|
if (this.args.options && typeof this.args.options === 'object' && !is_array(this.args.options)) {
|
|
this.args.options = Object.entries(this.args.options).map(_ref => {
|
|
let [value, label] = _ref;
|
|
return {
|
|
value,
|
|
label
|
|
};
|
|
});
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Initialize Tom Select
|
|
let config = {
|
|
placeholder: this.args.placeholder || '',
|
|
allowEmptyOption: true,
|
|
create: false,
|
|
maxOptions: null,
|
|
// Show all options (default is 50)
|
|
plugins: ['dropdown_input'],
|
|
// Enable search in dropdown
|
|
onInitialize: function () {
|
|
// Keep Bootstrap form-select class
|
|
this.control.classList.add('form-select');
|
|
}
|
|
};
|
|
this.tom_select = new TomSelect(this.$sid('input').get(0), config);
|
|
|
|
// Set initial value if provided
|
|
if (this.data.value) {
|
|
this.tom_select.setValue(this.data.value, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the selected value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (this.tom_select) {
|
|
return this.tom_select.getValue();
|
|
}
|
|
return this.$sid('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.tom_select) {
|
|
this.tom_select.setValue(this.data.value, true);
|
|
} else if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this.data.value);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
if (this.args.seeder) {
|
|
// TODO: Implement Rsx_Random_Values endpoint
|
|
let value = 'Test ' + (this.args.seeder || 'Value');
|
|
this.val(value);
|
|
} else if (this.args.options && this.args.options.length > 0) {
|
|
// Select random option
|
|
let random_index = Math.floor(Math.random() * this.args.options.length);
|
|
let random_opt = this.args.options[random_index];
|
|
let random_value = typeof random_opt === 'object' ? random_opt.value : random_opt;
|
|
this.val(random_value);
|
|
}
|
|
}
|
|
on_destroy() {
|
|
// Clean up Tom Select instance
|
|
if (this.tom_select) {
|
|
this.tom_select.destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/ajax_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Ajax_Select_Input extends Select_Input {
|
|
on_create() {
|
|
// Initialize empty select values array
|
|
this.data.select_values = [];
|
|
|
|
// Store for value set before initialization completes
|
|
this._pending_value = null;
|
|
|
|
// Call parent to do basic setup
|
|
super.on_create();
|
|
}
|
|
async on_load() {
|
|
// Load options from Ajax endpoint if provided
|
|
if (this.args.data) {
|
|
try {
|
|
const response = await fetch(this.args.data);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
this.data.select_values = data;
|
|
} catch (error) {
|
|
console.error('Failed to load select options:', error);
|
|
this.data.select_values = [];
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// If a value was set before initialization, apply it now
|
|
if (this._pending_value !== null) {
|
|
if (this.tom_select) {
|
|
this.tom_select.setValue(this._pending_value, true);
|
|
} else if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this._pending_value);
|
|
}
|
|
this.data.value = this._pending_value;
|
|
this._pending_value = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the selected value
|
|
* Handles calls before Tom Select initialization completes
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (this.tom_select) {
|
|
// Initialized - get from Tom Select
|
|
return this.tom_select.getValue();
|
|
} else if (this._pending_value !== null) {
|
|
// Not yet initialized - return pending value
|
|
return this._pending_value;
|
|
} else if (this.data.value) {
|
|
// Return data value
|
|
return this.data.value;
|
|
}
|
|
return '';
|
|
} else {
|
|
// Setter
|
|
if (this.tom_select) {
|
|
// Initialized - set via Tom Select
|
|
this.data.value = value || '';
|
|
this.tom_select.setValue(this.data.value, true);
|
|
} else {
|
|
// Not yet initialized - store for later
|
|
this._pending_value = value || '';
|
|
this.data.value = value || '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/currency_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Currency_Input
|
|
*
|
|
* Extends Text_Input to provide automatic currency formatting.
|
|
*
|
|
* Features:
|
|
* - Adds thousands separators (commas) every 3 digits
|
|
* - Optional currency symbol prefix (default: hidden)
|
|
* - Optional decimal support (default: disabled)
|
|
* - Smart backspace over formatting characters
|
|
* - No mid-string formatting (waits for blur)
|
|
*
|
|
* Arguments:
|
|
* - $allow_decimals - Allow 2 decimal places (default: false)
|
|
* - $show_symbol - Show currency symbol (default: false)
|
|
* - $currency_symbol - Currency symbol to use (default: "$")
|
|
*
|
|
* Usage:
|
|
* <Currency_Input />
|
|
* <Currency_Input $show_symbol=true />
|
|
* <Currency_Input $allow_decimals=true />
|
|
* <Currency_Input $show_symbol=true $allow_decimals=true $currency_symbol="€" />
|
|
*
|
|
* Behavior:
|
|
* - Type "1234567" -> displays "1,234,567", val() returns "1234567"
|
|
* - Type "1234567.89" (with decimals) -> displays "1,234,567.89", val() returns "1234567.89"
|
|
* - With symbol: displays "$1,234,567", val() still returns "1234567"
|
|
*/
|
|
class Currency_Input extends Text_Input {
|
|
on_create() {
|
|
super.on_create();
|
|
|
|
// Set defaults for options
|
|
if (this.args.allow_decimals === undefined) {
|
|
this.args.allow_decimals = false;
|
|
}
|
|
if (this.args.show_symbol === undefined) {
|
|
this.args.show_symbol = false;
|
|
}
|
|
if (this.args.currency_symbol === undefined) {
|
|
this.args.currency_symbol = '$';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format currency with commas and optional symbol
|
|
* @param {string} value - Numeric value (may include decimal)
|
|
* @returns {string} Formatted currency string
|
|
*/
|
|
_format_currency(value) {
|
|
if (!value) {
|
|
return '';
|
|
}
|
|
|
|
// Split into integer and decimal parts
|
|
let parts = value.split('.');
|
|
let integer_part = parts[0];
|
|
let decimal_part = parts[1];
|
|
|
|
// Add commas to integer part
|
|
integer_part = integer_part.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
|
|
// Reconstruct with decimal if allowed
|
|
let formatted = integer_part;
|
|
if (this.args.allow_decimals && decimal_part !== undefined) {
|
|
// Limit to 2 decimal places
|
|
decimal_part = decimal_part.substr(0, 2);
|
|
formatted += '.' + decimal_part;
|
|
}
|
|
|
|
// Add currency symbol if enabled
|
|
if (this.args.show_symbol) {
|
|
formatted = this.args.currency_symbol + formatted;
|
|
}
|
|
return formatted;
|
|
}
|
|
|
|
/**
|
|
* Extract numeric value from formatted string
|
|
* @param {string} formatted - Formatted currency string
|
|
* @returns {string} Clean numeric value (digits and decimal only)
|
|
*/
|
|
_get_numeric_value(formatted) {
|
|
if (!formatted) {
|
|
return '';
|
|
}
|
|
|
|
// Remove currency symbol and commas
|
|
let cleaned = formatted.replace(/[^0-9.]/g, '');
|
|
|
|
// Ensure only one decimal point
|
|
const decimal_count = (cleaned.match(/\./g) || []).length;
|
|
if (decimal_count > 1) {
|
|
// Keep only first decimal point
|
|
const first_decimal = cleaned.indexOf('.');
|
|
cleaned = cleaned.substr(0, first_decimal + 1) + cleaned.substr(first_decimal + 1).replace(/\./g, '');
|
|
}
|
|
return cleaned;
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the currency value
|
|
* Getter returns numeric string (no commas, no symbol)
|
|
* Setter accepts anything and formats with commas/symbol
|
|
* @param {string} [value]
|
|
* @returns {string}
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return numeric value only
|
|
const raw = this.$sid('input').val();
|
|
return this._get_numeric_value(raw);
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val('');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Clean the input value
|
|
const numeric = this._get_numeric_value(str(value));
|
|
const formatted = this._format_currency(numeric);
|
|
this.data.value = formatted;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$sid('input');
|
|
|
|
// Handle keydown to intercept backspace at end of string
|
|
$input.on('keydown', e => {
|
|
const raw = $input.val();
|
|
|
|
// Only handle backspace key
|
|
if (e.key !== 'Backspace') {
|
|
return;
|
|
}
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const cursor_end = input_element.selectionEnd;
|
|
const value_length = raw.length;
|
|
|
|
// Only handle if cursor is at the end and no selection
|
|
if (cursor_pos === value_length && cursor_pos === cursor_end) {
|
|
// Check if character before cursor is non-numeric
|
|
if (cursor_pos > 0) {
|
|
const char_before = raw.charAt(cursor_pos - 1);
|
|
if (!/[0-9]/.test(char_before)) {
|
|
// Character before cursor is not a digit
|
|
// Delete the last digit instead
|
|
e.preventDefault();
|
|
const numeric = this._get_numeric_value(raw);
|
|
if (numeric.length > 0) {
|
|
// Remove last character from numeric value
|
|
const new_numeric = numeric.substr(0, numeric.length - 1);
|
|
const formatted = this._format_currency(new_numeric);
|
|
$input.val(formatted);
|
|
|
|
// Place cursor at end
|
|
setTimeout(() => {
|
|
const new_length = $input.val().length;
|
|
input_element.setSelectionRange(new_length, new_length);
|
|
}, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle input event for live formatting
|
|
$input.on('input', () => {
|
|
const raw = $input.val();
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const value_length = raw.length;
|
|
|
|
// Only apply live formatting if cursor is at the end
|
|
if (cursor_pos === value_length) {
|
|
// Extract numeric value
|
|
let numeric = this._get_numeric_value(raw);
|
|
|
|
// Limit decimal places to 2 if decimals allowed
|
|
if (this.args.allow_decimals) {
|
|
const parts = numeric.split('.');
|
|
if (parts[1] && parts[1].length > 2) {
|
|
numeric = parts[0] + '.' + parts[1].substr(0, 2);
|
|
}
|
|
}
|
|
|
|
// Format the numeric value
|
|
const formatted = this._format_currency(numeric);
|
|
$input.val(formatted);
|
|
} else {
|
|
// Cursor is not at end - user is editing in the middle
|
|
// Don't format, just clean invalid characters
|
|
const numeric = this._get_numeric_value(raw);
|
|
|
|
// Only update if we removed invalid characters
|
|
if (this._format_currency(numeric) !== raw) {
|
|
// Preserve just the numeric characters
|
|
const symbol_offset = this.args.show_symbol ? this.args.currency_symbol.length : 0;
|
|
const cleaned = (this.args.show_symbol ? this.args.currency_symbol : '') + numeric;
|
|
if (cleaned !== raw) {
|
|
$input.val(cleaned);
|
|
// Restore cursor position (approximately)
|
|
const new_cursor = Math.min(cursor_pos, cleaned.length);
|
|
input_element.setSelectionRange(new_cursor, new_cursor);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle blur to reformat when done editing
|
|
$input.on('blur', () => {
|
|
const raw = $input.val();
|
|
if (!raw) {
|
|
return;
|
|
}
|
|
|
|
// Reformat the entire value on blur
|
|
const numeric = this._get_numeric_value(raw);
|
|
const formatted = this._format_currency(numeric);
|
|
$input.val(formatted);
|
|
});
|
|
|
|
// Handle focus to select all for easy replacement
|
|
$input.on('focus', () => {
|
|
setTimeout(() => {
|
|
$input[0].select();
|
|
}, 0);
|
|
});
|
|
|
|
// Initialize formatting if there's a value
|
|
const initial_value = $input.val();
|
|
if (initial_value) {
|
|
this.val(initial_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/phone_text_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Phone_Text_Input
|
|
*
|
|
* Extends Text_Input to provide automatic phone number formatting.
|
|
*
|
|
* Features:
|
|
* - US Mode (default): Formats as (XXX) XXX-XXXX on every keystroke
|
|
* - International Mode: Triggered by starting with '+', disables formatting
|
|
* - val() getter returns formatted string as displayed
|
|
* - val() setter accepts any format and displays appropriately
|
|
*
|
|
* Usage:
|
|
* <Phone_Text_Input $placeholder="Phone number" />
|
|
*
|
|
* Behavior:
|
|
* - Type "5551234567" -> displays "(555) 123-4567", val() returns "(555) 123-4567"
|
|
* - Type "+44 20 7123 4567" -> displays as typed, val() returns "+44 20 7123 4567"
|
|
* - Leading "1" is stripped: "15551234567" -> "(555) 123-4567"
|
|
*/
|
|
class Phone_Text_Input extends Text_Input {
|
|
on_create() {
|
|
super.on_create();
|
|
this._is_international = false;
|
|
}
|
|
|
|
/**
|
|
* Check if input is in international mode (starts with +)
|
|
* @param {string} value
|
|
* @returns {boolean}
|
|
*/
|
|
_check_international_mode(value) {
|
|
return value && str(value).charAt(0) === '+';
|
|
}
|
|
|
|
/**
|
|
* Format US phone number as (XXX) XXX-XXXX
|
|
* @param {string} digits - Clean numeric string (should be 10 digits or less after processing)
|
|
* @returns {string} Formatted phone number
|
|
*/
|
|
_format_us_phone(digits) {
|
|
// Format based on length (assumes digits are already cleaned and limited to 10)
|
|
if (digits.length >= 6) {
|
|
// (XXX) XXX-XXXX
|
|
return '(' + digits.substr(0, 3) + ') ' + digits.substr(3, 3) + '-' + digits.substr(6);
|
|
} else if (digits.length >= 3) {
|
|
// (XXX) XXX
|
|
return '(' + digits.substr(0, 3) + ') ' + digits.substr(3);
|
|
} else if (digits.length > 0) {
|
|
// (XX
|
|
return '(' + digits;
|
|
}
|
|
return digits;
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the phone number
|
|
* Getter returns formatted value as displayed (with parens, dashes, etc)
|
|
* Setter accepts anything and formats appropriately
|
|
* @param {string} [value]
|
|
* @returns {string}
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return the formatted value as displayed
|
|
return this.$sid('input').val() || '';
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val('');
|
|
}
|
|
return;
|
|
}
|
|
const str_value = str(value);
|
|
if (this._check_international_mode(str_value)) {
|
|
// International mode - no formatting
|
|
this.data.value = str_value;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(str_value);
|
|
}
|
|
} else {
|
|
// US mode - clean digits and format
|
|
const digits = str_value.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Strip US country code
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// Take first 10
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// Use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
this.data.value = formatted;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$sid('input');
|
|
let _last_cursor_position = null;
|
|
|
|
// Handle keydown to intercept backspace at end of string
|
|
$input.on('keydown', e => {
|
|
const raw = $input.val();
|
|
|
|
// Skip if international mode
|
|
if (this._check_international_mode(raw)) {
|
|
return;
|
|
}
|
|
|
|
// Only handle backspace key
|
|
if (e.key !== 'Backspace') {
|
|
return;
|
|
}
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const cursor_end = input_element.selectionEnd;
|
|
const value_length = raw.length;
|
|
|
|
// Only handle if cursor is at the end and no selection
|
|
if (cursor_pos === value_length && cursor_pos === cursor_end) {
|
|
// Check if character before cursor is non-numeric
|
|
if (cursor_pos > 0) {
|
|
const char_before = raw.charAt(cursor_pos - 1);
|
|
if (!/[0-9]/.test(char_before)) {
|
|
// Character before cursor is not a digit
|
|
// Delete the last digit instead
|
|
e.preventDefault();
|
|
const digits = raw.replace(/[^0-9]/g, '');
|
|
if (digits.length > 0) {
|
|
const new_digits = digits.substr(0, digits.length - 1);
|
|
const formatted = this._format_us_phone(new_digits);
|
|
$input.val(formatted);
|
|
|
|
// Place cursor at end
|
|
setTimeout(() => {
|
|
const new_length = $input.val().length;
|
|
input_element.setSelectionRange(new_length, new_length);
|
|
}, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle input event for live formatting
|
|
$input.on('input', () => {
|
|
const raw = $input.val();
|
|
if (this._check_international_mode(raw)) {
|
|
// International mode - allow anything
|
|
this._is_international = true;
|
|
// No formatting, no restrictions
|
|
return;
|
|
}
|
|
|
|
// US mode
|
|
this._is_international = false;
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const value_length = raw.length;
|
|
|
|
// Only apply live formatting if cursor is at the end
|
|
if (cursor_pos === value_length) {
|
|
// Remove any non-digit, non-formatting characters
|
|
const cleaned = raw.replace(/[^0-9\s\-()]/g, '');
|
|
const digits = cleaned.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Exactly 11 digits starting with "1" followed by valid area code digit (2-9)
|
|
// This is a US country code - strip the leading 1
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// More than 10 digits - just take the first 10 and ignore the rest
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// 10 or fewer digits - use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
|
|
// Format the digits
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
$input.val(formatted);
|
|
} else {
|
|
// Cursor is not at end - user is editing in the middle
|
|
// Don't format, just clean invalid characters
|
|
const cleaned = raw.replace(/[^0-9\s\-()]/g, '');
|
|
if (cleaned !== raw) {
|
|
$input.val(cleaned);
|
|
// Restore cursor position
|
|
input_element.setSelectionRange(cursor_pos, cursor_pos);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle blur to reformat when done editing
|
|
$input.on('blur', () => {
|
|
const raw = $input.val();
|
|
|
|
// Skip if international mode or empty
|
|
if (this._check_international_mode(raw) || !raw) {
|
|
return;
|
|
}
|
|
|
|
// Reformat the entire value on blur
|
|
const digits = raw.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Exactly 11 digits starting with "1" followed by valid area code digit (2-9)
|
|
// This is a US country code - strip the leading 1
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// More than 10 digits - just take the first 10
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// 10 or fewer digits - use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
$input.val(formatted);
|
|
});
|
|
|
|
// Initialize formatting if there's a value
|
|
const initial_value = $input.val();
|
|
if (initial_value) {
|
|
this.val(initial_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/state_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class State_Select_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Initialize country code from args or default to US
|
|
if (!this.data.country_code) {
|
|
this.data.country_code = this.args.country_code || 'US';
|
|
}
|
|
|
|
// Load states via Ajax endpoint if country code is set
|
|
if (this.data.country_code) {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.states({
|
|
country: this.data.country_code
|
|
});
|
|
|
|
// If no states returned, add N/A option
|
|
if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
this.data.select_values = [{
|
|
value: 'N/A',
|
|
label: 'N/A'
|
|
}];
|
|
}
|
|
} else {
|
|
this.data.select_values = [];
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select State...';
|
|
}
|
|
|
|
// Initialize country code in data
|
|
this.data.country_code = this.args.country_code || '';
|
|
|
|
// Cache for selected state per country code
|
|
this._state_cache = {};
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// Check if this is N/A case (no states for country)
|
|
const is_na = this.data.select_values.length === 1 && this.data.select_values[0].value === 'N/A';
|
|
|
|
// Disable if no country code or N/A case
|
|
if ((!this.data.country_code || is_na) && this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
|
|
// Set value to N/A if that's the only option
|
|
if (is_na) {
|
|
this.val('N/A');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set country code and reload state list
|
|
* @param {string} country_code - ISO country code (e.g., 'US', 'CA')
|
|
*/
|
|
async set_country_code(country_code) {
|
|
// Cache the current value for the current country before switching
|
|
const current_country = this.data.country_code;
|
|
const current_value = this.val();
|
|
if (current_country && current_value && current_value !== 'N/A') {
|
|
this._state_cache[current_country] = current_value;
|
|
}
|
|
|
|
// Update country code
|
|
this.data.country_code = country_code;
|
|
|
|
// Disable the selector while loading
|
|
if (this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
|
|
// Load new state list
|
|
try {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.states({
|
|
country: country_code
|
|
});
|
|
|
|
// Race condition check: verify country hasn't changed during the request
|
|
if (this.data.country_code !== country_code) {
|
|
// Country changed while request was in flight - ignore this response
|
|
return;
|
|
}
|
|
|
|
// If no states returned, add N/A option
|
|
if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
this.data.select_values = [{
|
|
value: 'N/A',
|
|
label: 'N/A'
|
|
}];
|
|
}
|
|
|
|
// Re-render the widget with new states
|
|
this.redraw();
|
|
|
|
// Re-initialize Tom Select after redraw
|
|
if (this.tom_select) {
|
|
this.tom_select.destroy();
|
|
}
|
|
|
|
// Re-run on_ready to set up Tom Select again
|
|
this.on_ready();
|
|
|
|
// Check if this is N/A case
|
|
const is_na = this.data.select_values.length === 1 && this.data.select_values[0].value === 'N/A';
|
|
if (is_na) {
|
|
// Set to N/A and keep disabled
|
|
this.val('N/A');
|
|
if (this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
} else {
|
|
// Try to restore cached value for this country
|
|
const cached_value = this._state_cache[country_code];
|
|
if (cached_value) {
|
|
const value_exists = this.data.select_values.some(opt => (typeof opt === 'object' ? opt.value : opt) === cached_value);
|
|
if (value_exists) {
|
|
this.val(cached_value);
|
|
} else {
|
|
this.val(''); // Clear if cached value not in new list
|
|
}
|
|
} else {
|
|
this.val(''); // No cached value - leave empty
|
|
}
|
|
|
|
// Enable the widget now that we have a country with states
|
|
if (this.tom_select) {
|
|
this.tom_select.enable();
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load states for country:', country_code, error);
|
|
this.data.select_values = [];
|
|
|
|
// Re-enable even on error
|
|
if (this.tom_select) {
|
|
this.tom_select.enable();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override val() to update cache when user manually selects a state
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - use parent implementation
|
|
return super.val();
|
|
} else {
|
|
// Setter - update cache and call parent
|
|
if (this.data.country_code && value && value !== 'N/A') {
|
|
this._state_cache[this.data.country_code] = value;
|
|
}
|
|
return super.val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/country_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Country_Select_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Load countries via Ajax endpoint if data not provided
|
|
if (!this.args.data) {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.countries();
|
|
} else {
|
|
// Use parent on_load for custom data endpoints
|
|
await super.on_load();
|
|
}
|
|
|
|
// Reorder select_values to put default country first in the list
|
|
if (this.args.default_country && this.data.select_values && is_array(this.data.select_values)) {
|
|
const default_country_code = this.args.default_country;
|
|
|
|
// Find the default country in the array
|
|
const default_country_index = this.data.select_values.findIndex(opt => (typeof opt === 'object' ? opt.value : opt) === default_country_code);
|
|
if (default_country_index !== -1) {
|
|
// Remove it from its current position
|
|
const [default_country] = this.data.select_values.splice(default_country_index, 1);
|
|
|
|
// Add it to the beginning
|
|
this.data.select_values.unshift(default_country);
|
|
}
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select Country...';
|
|
}
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
|
|
// Handle default country value
|
|
if (this.args.default_country && !this.data.value) {
|
|
this.data.value = this.args.default_country;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// Update state selector with initial/default country
|
|
this._update_state_selector();
|
|
|
|
// Listen for country changes and update state selector
|
|
if (this.tom_select) {
|
|
this.tom_select.on('change', () => {
|
|
this._update_state_selector();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Find State_Select_Input sibling and update its country code
|
|
* @private
|
|
*/
|
|
_update_state_selector() {
|
|
const current_country = this.val();
|
|
|
|
// Find State_Select_Input component using closest_sibling
|
|
const state_component = this.$.closest_sibling('.State_Select_Input').component();
|
|
if (state_component && typeof state_component.set_country_code === 'function') {
|
|
state_component.set_country_code(current_country);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/profile_photo_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Profile_Photo_Input
|
|
*
|
|
* Profile photo upload widget with thumbnail display and upload handling.
|
|
* See profile_photo_input.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Handle file selection and upload
|
|
* - Update thumbnail on successful upload
|
|
* - Manage loading state with spinner
|
|
* - Provide val() getter/setter for attachment key
|
|
* - Handle remove button functionality
|
|
*/
|
|
class Profile_Photo_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
// Initialize data
|
|
this.data.attachment_key = '';
|
|
this.data.thumbnail_url = '';
|
|
}
|
|
on_render() {
|
|
// Handle upload button click - trigger hidden file input
|
|
this.$sid('upload_btn').on('click', () => {
|
|
this.$sid('file_input').click();
|
|
});
|
|
|
|
// Handle file selection
|
|
this.$sid('file_input').on('change', () => {
|
|
const file = this.$sid('file_input')[0].files[0];
|
|
if (!file) return;
|
|
this.upload_photo(file);
|
|
});
|
|
|
|
// Handle remove button
|
|
if (this.args.show_remove) {
|
|
this.$sid('remove_btn').on('click', () => {
|
|
this.remove_photo();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the attachment key
|
|
* @param {string} [key] - If provided, sets the attachment key and updates thumbnail
|
|
* @returns {string} The current attachment key when called as getter
|
|
*/
|
|
val(key) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return attachment key
|
|
return this.data.attachment_key || '';
|
|
} else {
|
|
// Setter - set attachment key and update thumbnail
|
|
this.data.attachment_key = key || '';
|
|
if (this.data.attachment_key) {
|
|
// Generate thumbnail URL from attachment key
|
|
const width = this.args.width || 96;
|
|
const height = this.args.height || 96;
|
|
this.data.thumbnail_url = `/_thumbnail/${this.data.attachment_key}/cover/${width}/${height}`;
|
|
} else {
|
|
// No key - clear thumbnail
|
|
this.data.thumbnail_url = '';
|
|
}
|
|
console.log('Rerender');
|
|
// Re-render to switch between icon and image
|
|
this.render();
|
|
}
|
|
}
|
|
upload_photo(file) {
|
|
// Validate file size
|
|
const max_size = (this.args.max_size || 2) * 1024 * 1024; // Convert MB to bytes
|
|
if (file.size > max_size) {
|
|
alert(`File size must be less than ${this.args.max_size || 2}MB`);
|
|
this.$sid('file_input').val(''); // Clear selection
|
|
return;
|
|
}
|
|
|
|
// Show spinner, dim image
|
|
this.$sid('spinner').removeClass('d-none');
|
|
this.$sid('photo').css('opacity', '0.3');
|
|
|
|
// Create FormData for file upload
|
|
const form_data = new FormData();
|
|
form_data.append('file', file);
|
|
form_data.append('site_id', '1'); // TODO: Get from session/config
|
|
// Do NOT set fileable_type/fileable_category - file uploads unattached
|
|
// The parent form will assign it via attach_to() on save
|
|
|
|
// Upload file via AJAX
|
|
$.ajax({
|
|
url: '/_upload',
|
|
type: 'POST',
|
|
data: form_data,
|
|
processData: false,
|
|
contentType: false,
|
|
success: response => {
|
|
console.log('Profile photo upload successful:', response);
|
|
|
|
// Update attachment key (this will also update thumbnail)
|
|
this.val(response.attachment.key);
|
|
|
|
// Hide spinner, restore opacity
|
|
this.$sid('spinner').addClass('d-none');
|
|
this.$sid('photo').css('opacity', '1');
|
|
|
|
// Clear file input for future uploads
|
|
this.$sid('file_input').val('');
|
|
|
|
// Trigger change event for form tracking
|
|
this.$.trigger('change');
|
|
},
|
|
error: (xhr, status, error) => {
|
|
var _xhr$responseJSON;
|
|
console.error('Profile photo upload failed:', error);
|
|
console.error('Response:', xhr.responseJSON);
|
|
|
|
// Hide spinner, restore opacity
|
|
this.$sid('spinner').addClass('d-none');
|
|
this.$sid('photo').css('opacity', '1');
|
|
|
|
// Clear file input
|
|
this.$sid('file_input').val('');
|
|
|
|
// Show error to user
|
|
alert('Upload failed: ' + (((_xhr$responseJSON = xhr.responseJSON) === null || _xhr$responseJSON === void 0 ? void 0 : _xhr$responseJSON.error) || error));
|
|
}
|
|
});
|
|
}
|
|
update_photo() {
|
|
// <% if (this.args.show_remove && this.data.attachment_key) { %>
|
|
}
|
|
remove_photo() {
|
|
// Clear attachment key (sets to placeholder)
|
|
this.val('');
|
|
|
|
// Trigger change event for form tracking
|
|
this.$.trigger('change');
|
|
}
|
|
async seed() {
|
|
// For testing - set a placeholder key
|
|
// In production, this would use actual test data
|
|
this.val('');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_tabs.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Tabs
|
|
*
|
|
* Tab container component with form-aware error handling integration.
|
|
* See rsx_tabs.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Builds tab navigation dynamically from registered Rsx_Tab children
|
|
* - Manages tab activation and switching behavior
|
|
* - Persists active tab to URL hash for bookmarking
|
|
* - Integrates with form validation to show error badges on tabs
|
|
* - Auto-switches to first tab with errors on validation failure
|
|
* - Provides API for parent forms to report validation errors
|
|
*/
|
|
class Rsx_Tabs extends Component {
|
|
on_create() {
|
|
this.tabs = []; // Registered Rsx_Tab components
|
|
this.active_tab_id = null;
|
|
this.form = null;
|
|
}
|
|
on_ready() {
|
|
// Find parent form if it exists
|
|
this.form = this.closest('.Rsx_Form');
|
|
|
|
// Build tab navigation from registered tabs
|
|
this._build_nav();
|
|
|
|
// Restore active tab from URL hash or activate first tab
|
|
const hash = window.location.hash;
|
|
if (hash) {
|
|
const tab_id = hash.substring(1);
|
|
this.activate_tab(tab_id);
|
|
} else if (this.tabs.length > 0) {
|
|
this.activate_tab(this.tabs[0].args.id);
|
|
}
|
|
|
|
// Persist active tab to URL hash
|
|
const that = this;
|
|
this.$sid('nav').on('click', 'a[data-bs-toggle="tab"]', function (e) {
|
|
const tab_id = $(e.currentTarget).data('tab-id');
|
|
window.location.hash = '#' + tab_id;
|
|
});
|
|
}
|
|
register_tab(tab_component) {
|
|
this.tabs.push(tab_component);
|
|
}
|
|
_build_nav() {
|
|
const $nav = this.$sid('nav');
|
|
$nav.empty();
|
|
for (let i = 0; i < this.tabs.length; i++) {
|
|
const tab = this.tabs[i];
|
|
const is_active = i === 0 ? 'active' : '';
|
|
const $li = $(`
|
|
<li class="nav-item" role="presentation">
|
|
<a class="nav-link ${is_active}"
|
|
data-bs-toggle="tab"
|
|
href="#${tab.args.id}"
|
|
data-tab-id="${tab.args.id}"
|
|
aria-selected="${i === 0 ? 'true' : 'false'}"
|
|
role="tab">
|
|
${tab.args.icon ? `<i class="${tab.args.icon}"></i> ` : ''}
|
|
${tab.args.label}
|
|
<span class="badge bg-danger ms-2" style="display: none;" data-error-badge="${tab.args.id}">0</span>
|
|
</a>
|
|
</li>
|
|
`);
|
|
$nav.append($li);
|
|
}
|
|
}
|
|
activate_tab(tab_id) {
|
|
// Find the tab
|
|
const tab = this.tabs.find(t => t.args.id === tab_id);
|
|
if (!tab) return;
|
|
|
|
// Remove active show from all tab panes
|
|
for (let t of this.tabs) {
|
|
t.$.removeClass('active show');
|
|
}
|
|
|
|
// Add active show to the selected tab pane
|
|
tab.$.addClass('active show');
|
|
|
|
// Update Bootstrap tab navigation
|
|
this.$sid('nav').find('a[data-bs-toggle="tab"]').removeClass('active').attr('aria-selected', 'false');
|
|
this.$sid('nav').find('a[data-tab-id="' + tab_id + '"]').addClass('active').attr('aria-selected', 'true');
|
|
this.active_tab_id = tab_id;
|
|
}
|
|
handle_validation_errors(errors) {
|
|
// Count errors per tab
|
|
const tab_errors = {};
|
|
for (let tab of this.tabs) {
|
|
const error_count = tab.count_errors(errors);
|
|
tab_errors[tab.args.id] = error_count;
|
|
|
|
// Update badge
|
|
const $badge = this.$sid('nav').find(`[data-error-badge="${tab.args.id}"]`);
|
|
if (error_count > 0) {
|
|
$badge.text(error_count).show();
|
|
} else {
|
|
$badge.hide();
|
|
}
|
|
}
|
|
|
|
// Find first tab with errors
|
|
const first_errored_tab = this.tabs.find(t => tab_errors[t.args.id] > 0);
|
|
|
|
// Switch to first errored tab if not currently on an errored tab
|
|
if (first_errored_tab && tab_errors[this.active_tab_id] === 0) {
|
|
this.activate_tab(first_errored_tab.args.id);
|
|
}
|
|
}
|
|
clear_error_badges() {
|
|
this.$sid('nav').find('[data-error-badge]').hide();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_tab.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Tab
|
|
*
|
|
* Individual tab pane component that works with Rsx_Tabs for form validation.
|
|
* See rsx_tab.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Auto-registers with parent Rsx_Tabs component on creation
|
|
* - Sets tab pane ID attribute from $id argument
|
|
* - Discovers and tracks child Form_Field components
|
|
* - Counts validation errors within this tab's fields
|
|
* - Provides error count to parent for badge display
|
|
*/
|
|
class Rsx_Tab extends Component {
|
|
on_create() {
|
|
let that = this;
|
|
|
|
// Set the tab ID dynamically from args
|
|
if (that.args.id) {
|
|
that.$.attr('id', that.args.id);
|
|
}
|
|
|
|
// Find parent Rsx_Tabs and register
|
|
that.tabs_container = that.closest('.Rsx_Tabs');
|
|
if (that.tabs_container) {
|
|
that.tabs_container.register_tab(that);
|
|
}
|
|
|
|
// Store reference to all Form_Field components within this tab
|
|
that.fields = [];
|
|
}
|
|
on_ready() {
|
|
let that = this;
|
|
|
|
// Find all Form_Field components within this tab
|
|
that.$.find('.Form_Field').each((index, element) => {
|
|
const field_component = $(element).component();
|
|
if (field_component) {
|
|
that.fields.push(field_component);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Count validation errors in Form_Field components within this tab
|
|
* @param {Object} errors - Error object from form validation {field_name: error_message}
|
|
* @returns {number} Count of errors in this tab
|
|
*/
|
|
count_errors(errors) {
|
|
let that = this;
|
|
let count = 0;
|
|
for (let field of that.fields) {
|
|
if (errors[field.args.name]) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Form
|
|
*
|
|
* Form container with validation, submission, and widget value management.
|
|
* See rsx_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Parses and stores initial form data from $data attribute (JSON or object)
|
|
* - Discovers and manages child Widget components via vals() getter/setter
|
|
* - Handles form submission via Ajax to controller/method endpoints
|
|
* - Applies validation errors to fields using Form_Utils
|
|
* - Integrates with Rsx_Tabs for tab-aware error handling
|
|
* - Provides seed() functionality for debug/testing
|
|
* - Manages form state (values, errors) throughout lifecycle
|
|
*/
|
|
class Rsx_Form extends Component {
|
|
on_create() {
|
|
this.data.values = {}; // Current form values {name: value}
|
|
this.data.errors = {}; // Validation errors {name: error_message}
|
|
this.tabs = null; // Reference to Rsx_Tabs component if present
|
|
|
|
// Parse initial data from $data attribute (e.g., from $data=$client)
|
|
let data = this.args.data;
|
|
if (typeof data === 'string') {
|
|
try {
|
|
// Decode HTML entities before parsing JSON
|
|
// This handles cases where JSON is passed through Blade {!! !!} syntax
|
|
const decoded = $('<textarea>').html(data).text();
|
|
data = json_decode(decoded);
|
|
} catch (e) {
|
|
console.error('Form: Failed to parse data JSON string', e);
|
|
data = {};
|
|
}
|
|
}
|
|
if (data && typeof data === 'object') {
|
|
this.data.values = data;
|
|
}
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
|
|
// Validate that error container exists
|
|
if (!this.$sid('error').exists()) {
|
|
console.log(this.$.html());
|
|
throw new Error('Rsx_Form requires an error container with $id="error". ' + 'Add <div $id="error"></div> to your form template for displaying validation and error messages.');
|
|
}
|
|
|
|
// Set up seed button handler if in debug mode
|
|
if (window.rsxapp.debug && this.$sid('seed_btn').exists()) {
|
|
that.$sid('seed_btn').on('click', function () {
|
|
that.seed();
|
|
});
|
|
}
|
|
|
|
// Find child Rsx_Tabs component if present for error handling integration
|
|
const tabs_el = this.$.find('.Rsx_Tabs').first();
|
|
if (tabs_el.length) {
|
|
that.tabs = tabs_el.component();
|
|
}
|
|
|
|
// Automatically wire all submit buttons to call form submit()
|
|
this.$.find('button[type="submit"]').each(function () {
|
|
$(this).on('click', function (e) {
|
|
e.preventDefault();
|
|
that.submit();
|
|
});
|
|
});
|
|
|
|
// Notify all fields to load their initial values
|
|
// This happens in on_ready to ensure all Form_Field children are initialized
|
|
this.vals(this.data.values);
|
|
|
|
// Hide loading spinner and show form content (without re-rendering)
|
|
this.$sid('loader').hide();
|
|
this.$sid('form_content').show();
|
|
}
|
|
|
|
// Getter or setter for all form values, similar to jquery val
|
|
vals(values) {
|
|
if (values) {
|
|
// Setter
|
|
|
|
this.$.shallowFind('.Widget').each(function () {
|
|
let $widget = $(this);
|
|
let component = $widget.component();
|
|
if (component && 'val' in component) {
|
|
let widget_name = $widget.data('name');
|
|
if (widget_name in values) {
|
|
component.val(values[widget_name]);
|
|
}
|
|
}
|
|
});
|
|
return null;
|
|
} else {
|
|
// Getter
|
|
let data = {};
|
|
|
|
// Get widget values
|
|
this.$.shallowFind('.Widget').each(function () {
|
|
let $widget = $(this);
|
|
let component = $widget.component();
|
|
if (component && 'val' in component) {
|
|
let widget_name = $widget.data('name');
|
|
data[widget_name] = component.val();
|
|
}
|
|
});
|
|
|
|
// Also get regular hidden inputs (non-widget inputs)
|
|
this.$.find('input[type="hidden"][name]').each(function () {
|
|
let $input = $(this);
|
|
let name = $input.attr('name');
|
|
if (name) {
|
|
data[name] = $input.val();
|
|
}
|
|
});
|
|
return data;
|
|
}
|
|
}
|
|
get_error(name) {
|
|
return this.data.errors[name];
|
|
}
|
|
|
|
/**
|
|
* Render an error in the form's error container
|
|
*
|
|
* Handles both field-specific validation errors and generic errors.
|
|
* Can be called by external handlers (e.g., modal on_submit) or internally
|
|
* by the form's own submit() method.
|
|
*
|
|
* @param {Error|Object} error - Error object from Ajax call
|
|
*/
|
|
async render_error(error) {
|
|
// Handle validation errors - apply to fields
|
|
if (error.type === 'form_error' && error.details) {
|
|
await Form_Utils.apply_form_errors(this.$, error.details);
|
|
|
|
// Notify tabs of validation errors for error badges and auto-switching
|
|
if (this.tabs) {
|
|
this.tabs.handle_validation_errors(error.details);
|
|
}
|
|
|
|
// Form_Utils handles all rendering (inline errors + unmatched errors alert)
|
|
// Don't call Rsx.render_error() to avoid duplicate alerts
|
|
return;
|
|
}
|
|
|
|
// For non-form errors (fatal, auth, network, etc.), render in form's error container
|
|
Rsx.render_error(error, this.$sid('error'));
|
|
}
|
|
async submit() {
|
|
// Clear any previous errors
|
|
Form_Utils.reset_form_errors(this.$);
|
|
this.$sid('error').empty();
|
|
|
|
// Clear tab error badges if tabs are present
|
|
if (this.tabs) {
|
|
this.tabs.clear_error_badges();
|
|
}
|
|
|
|
// Serialize all field values
|
|
let values = this.vals();
|
|
|
|
// Call submit handler
|
|
if (!this.args.controller || !this.args.method) {
|
|
console.error('Form: No controller/method provided');
|
|
throw new Error('Form configuration error: Missing controller or method');
|
|
}
|
|
try {
|
|
// Build Ajax URL from controller and method
|
|
const ajax_url = `/_ajax/${this.args.controller}/${this.args.method}`;
|
|
|
|
// Call Ajax endpoint - response is directly what PHP returned
|
|
const result = await Ajax.call(ajax_url, values);
|
|
|
|
// Success! Handle result
|
|
if (result && result.redirect) {
|
|
// Redirect to URL
|
|
window.location.href = result.redirect;
|
|
} else {
|
|
// Success without redirect
|
|
console.log('Form submitted successfully', result);
|
|
}
|
|
} catch (error) {
|
|
// Render error (handles both validation and generic errors)
|
|
await this.render_error(error);
|
|
}
|
|
}
|
|
async seed() {
|
|
const promises = [];
|
|
this.$.shallowFind('.Form_Field').each(function () {
|
|
let component = $(this).component();
|
|
if (component && 'seed' in component) {
|
|
promises.push(component.seed());
|
|
}
|
|
});
|
|
await Promise.all(promises);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/pin_verification_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Pin_Verification_Form
|
|
*
|
|
* Specialized 6-digit PIN entry form with auto-navigation between inputs.
|
|
* See pin_verification_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Auto-advances to next input when digit is entered
|
|
* - Smart backspace: clears current box and moves to previous
|
|
* - Paste support: distributes pasted digits across all 6 inputs
|
|
* - Arrow key navigation between inputs
|
|
* - Numeric-only input validation
|
|
* - Select-all on focus for easy digit replacement
|
|
* - Validates all 6 digits entered before allowing submission
|
|
* - Provides val() getter/setter for programmatic PIN access
|
|
*/
|
|
class Pin_Verification_Form extends Rsx_Form {
|
|
on_create() {
|
|
super.on_create();
|
|
this.pin_length = 6;
|
|
}
|
|
|
|
/**
|
|
* Get or set the PIN value
|
|
* @param {string} [value] - If provided, sets the PIN (distributes across inputs)
|
|
* @returns {string} Current PIN value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - collect all digits
|
|
let pin = '';
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
pin += this.$sid(`digit_${i}`).val() || '';
|
|
}
|
|
return pin;
|
|
} else {
|
|
// Setter - distribute digits across inputs
|
|
const digits = str(value || '').replace(/[^0-9]/g, '');
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
this.$sid(`digit_${i}`).val(digits[i] || '');
|
|
}
|
|
// Focus first empty input or last input
|
|
const first_empty = this._find_first_empty_index();
|
|
if (first_empty !== -1) {
|
|
this.$sid(`digit_${first_empty}`)[0].focus();
|
|
} else {
|
|
this.$sid(`digit_${this.pin_length - 1}`)[0].focus();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Find the first empty input index
|
|
* @returns {number} Index of first empty input, or -1 if all filled
|
|
*/
|
|
_find_first_empty_index() {
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
if (!this.$sid(`digit_${i}`).val()) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Move focus to specific input index
|
|
* @param {number} index
|
|
*/
|
|
_focus_input(index) {
|
|
if (index >= 0 && index < this.pin_length) {
|
|
const $input = this.$sid(`digit_${index}`);
|
|
if ($input.exists()) {
|
|
$input[0].focus();
|
|
// Select the content if there is any
|
|
$input[0].select();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle paste event - distribute digits across inputs
|
|
* @param {ClipboardEvent} e
|
|
* @param {number} start_index
|
|
*/
|
|
_handle_paste(e, start_index) {
|
|
e.preventDefault();
|
|
|
|
// Get pasted data
|
|
const paste = (e.originalEvent || e).clipboardData.getData('text');
|
|
const digits = paste.replace(/[^0-9]/g, '');
|
|
if (!digits) {
|
|
return;
|
|
}
|
|
|
|
// Distribute digits starting from current input
|
|
for (let i = 0; i < digits.length && start_index + i < this.pin_length; i++) {
|
|
this.$sid(`digit_${start_index + i}`).val(digits[i]);
|
|
}
|
|
|
|
// Focus next empty input or last input
|
|
const next_index = Math.min(start_index + digits.length, this.pin_length - 1);
|
|
this._focus_input(next_index);
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const that = this;
|
|
|
|
// Set up event handlers for each input
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
const $input = this.$sid(`digit_${i}`);
|
|
const index = i;
|
|
|
|
// Handle input event - auto-advance
|
|
$input.on('input', function (e) {
|
|
const value = $(this).val();
|
|
|
|
// Only allow numeric input
|
|
const numeric = value.replace(/[^0-9]/g, '');
|
|
if (numeric !== value) {
|
|
$(this).val(numeric);
|
|
}
|
|
|
|
// If multiple digits were entered (paste), distribute them
|
|
if (numeric.length > 1) {
|
|
that._handle_paste({
|
|
preventDefault: () => {},
|
|
originalEvent: {
|
|
clipboardData: {
|
|
getData: () => numeric
|
|
}
|
|
}
|
|
}, index);
|
|
return;
|
|
}
|
|
|
|
// Auto-advance to next input if digit was entered
|
|
if (numeric.length === 1 && index < that.pin_length - 1) {
|
|
that._focus_input(index + 1);
|
|
}
|
|
});
|
|
|
|
// Handle keydown for backspace
|
|
$input.on('keydown', function (e) {
|
|
// Backspace key
|
|
if (e.key === 'Backspace') {
|
|
const current_value = $(this).val();
|
|
|
|
// If current input is empty, move to previous and clear it
|
|
if (!current_value && index > 0) {
|
|
e.preventDefault();
|
|
that.$sid(`digit_${index - 1}`).val('');
|
|
that._focus_input(index - 1);
|
|
}
|
|
// If current input has value, it will be cleared by default behavior
|
|
// and we stay on current input
|
|
}
|
|
|
|
// Arrow left
|
|
if (e.key === 'ArrowLeft' && index > 0) {
|
|
e.preventDefault();
|
|
that._focus_input(index - 1);
|
|
}
|
|
|
|
// Arrow right
|
|
if (e.key === 'ArrowRight' && index < that.pin_length - 1) {
|
|
e.preventDefault();
|
|
that._focus_input(index + 1);
|
|
}
|
|
});
|
|
|
|
// Handle paste event
|
|
$input.on('paste', function (e) {
|
|
that._handle_paste(e, index);
|
|
});
|
|
|
|
// Select all on focus for easy replacement
|
|
$input.on('focus', function () {
|
|
$(this)[0].select();
|
|
});
|
|
}
|
|
|
|
// Focus first input on load
|
|
this._focus_input(0);
|
|
}
|
|
|
|
/**
|
|
* Override submit to validate PIN is complete
|
|
*/
|
|
async submit() {
|
|
const pin = this.val();
|
|
|
|
// Clear previous errors
|
|
this.$sid('error_container').hide().empty();
|
|
|
|
// Validate PIN is 6 digits
|
|
if (pin.length !== this.pin_length) {
|
|
this.$sid('error_container').text('Please enter all 6 digits').show();
|
|
|
|
// Mark inputs as invalid
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
if (!this.$sid(`digit_${i}`).val()) {
|
|
this.$sid(`digit_${i}`).addClass('is-invalid');
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Remove invalid class from all inputs
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
this.$sid(`digit_${i}`).removeClass('is-invalid');
|
|
}
|
|
|
|
// Call parent submit (which will use controller/method if provided)
|
|
await super.submit();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_field_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Field_Abstract
|
|
*
|
|
* Abstract base class for form field wrappers. Provides core functionality without visual formatting.
|
|
* See form_field_abstract.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Discovers and configures child Widget component
|
|
* - Sets data-name attribute on widget for form value collection
|
|
* - Sets name attribute on native inputs for Form_Utils compatibility
|
|
* - Wires label 'for' attribute to input element ID for accessibility (if label exists)
|
|
* - Provides seed() support for debug/testing data
|
|
* - Bridges between form validation state and child widget
|
|
*/
|
|
class Form_Field_Abstract extends Component {
|
|
on_create() {
|
|
// Find parent form for error display
|
|
this.form = this.closest('.Rsx_Form');
|
|
if (!this.form) {
|
|
shouldnt_happen('Form_Field_Abstract must be inside a Rsx_Form component');
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Find child widget and set its data-name attribute
|
|
let $widget = this.$.find('.Widget').first();
|
|
if (!$widget.exists()) {
|
|
shouldnt_happen(`Form_Field_Abstract "${this.args.name}" has no .Widget child. Every Form_Field must contain exactly one widget (Text_Input, Wysiwyg_Input, etc.)`);
|
|
}
|
|
|
|
// Set data-name on the widget so Rsx_Form can collect values
|
|
$widget.attr('data-name', this.args.name);
|
|
let $input = this.$.find('input, select, textarea').first();
|
|
if ($input.exists()) {
|
|
// Also set name attribute on native inputs for Form_Utils compatibility
|
|
// Todo: clever way to deal with this for non standard input elements
|
|
$input.attr('name', this.args.name);
|
|
|
|
// Set the for field to the element if label exists (for child classes)
|
|
// Todo: clever way to deal with this for non standard input elements
|
|
let $label = this.$sid('form_label');
|
|
if ($label.exists()) {
|
|
$label.attr('for', $input.attr('id'));
|
|
}
|
|
}
|
|
}
|
|
get_error() {
|
|
return this.form.get_error(this.args.name);
|
|
}
|
|
has_error() {
|
|
return !!this.get_error();
|
|
}
|
|
async seed() {
|
|
if (!this.args.seeder) {
|
|
return;
|
|
}
|
|
|
|
// Find child widget
|
|
let $widget = this.$.find('.Widget').first();
|
|
if (!$widget.exists()) {
|
|
return;
|
|
}
|
|
let widget_component = $widget.component();
|
|
if (!widget_component || !widget_component.val) {
|
|
return;
|
|
}
|
|
|
|
// Call the seeder endpoint (Ajax route reference like form $action)
|
|
try {
|
|
let value = await Ajax.call(this.args.seeder, {});
|
|
widget_component.val(value);
|
|
} catch (error) {
|
|
console.error(`Seeder error for ${this.args.name}:`, error);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_field.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Field
|
|
*
|
|
* Form field wrapper that adds labels, help text, and required indicators.
|
|
* See form_field.jqhtml for full documentation.
|
|
*
|
|
* Extends Form_Field_Abstract to inherit all core functionality.
|
|
* This class exists primarily for template inheritance and any future
|
|
* formatted-field-specific behavior.
|
|
*/
|
|
class Form_Field extends Form_Field_Abstract {
|
|
// All functionality inherited from Form_Field_Abstract
|
|
// This class provides the formatted visual wrapper via its template
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_hidden_field.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Hidden_Field - Hidden input field component
|
|
*
|
|
* Extends Form_Field_Abstract but IS the input element itself (using tag="input" type="hidden").
|
|
* See form_hidden_field.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Sets value attribute dynamically in on_create()
|
|
* - Overrides on_ready() to handle that this.$ IS both the widget and the input
|
|
* - Provides val() method for getting/setting the hidden value
|
|
*/
|
|
class Form_Hidden_Field extends Form_Field_Abstract {
|
|
on_create() {
|
|
// Call parent to set up form reference
|
|
super.on_create();
|
|
|
|
// Set initial value attribute (can't be done in Define tag)
|
|
this.$.attr('value', '');
|
|
}
|
|
on_ready() {
|
|
// Override parent on_ready() because this.$ IS the widget and the input
|
|
// Set data-name on this.$ (which is the input element)
|
|
this.$.attr('data-name', this.args.name);
|
|
|
|
// Set name attribute on this.$ for Form_Utils compatibility
|
|
this.$.attr('name', this.args.name);
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the hidden input value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - this.$ is the input element itself
|
|
return this.$.val();
|
|
} else {
|
|
// Setter - update the input value directly (this.$ is the input)
|
|
this.$.val(value || '');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ac3759f51f05106a.js === */
|
|
/* Compiled from: rsx/app/dev/modals/test_modal_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Test_Modal_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Test_Modal_Form',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mb-4"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "text-muted mb-3"}, false]}); _output.push("User Information"); _output.push("</h5>");
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"id": "error_container" + ":" + this._cid, "data-id": "error_container"}, false]}); _output.push("</div>");
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "form-group mb-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"for": "name", "class": "form-label"}, false]}); _output.push("Full Name ");_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "text", "class": "form-control", "id": "name_input" + ":" + this._cid, "data-id": "name_input", "name": "name", "placeholder": "Enter your full name"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"class": "form-group mb-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"for": "email", "class": "form-label"}, false]}); _output.push("Email Address ");_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "email", "class": "form-control", "id": "email_input" + ":" + this._cid, "data-id": "email_input", "name": "email", "placeholder": "user@example.com"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"class": "form-group mb-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"for": "role", "class": "form-label"}, false]}); _output.push("Role ");_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "role_select" + ":" + this._cid, "data-id": "role_select", "name": "role"}, false]});
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); _output.push("-- Select a role --"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "admin"}, false]}); _output.push("Administrator"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "manager"}, false]}); _output.push("Manager"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "user"}, false]}); _output.push("User"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "guest"}, false]}); _output.push("Guest"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Test_Modal_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4c789804a2735328.js === */
|
|
/* Compiled from: rsx/theme/components/datagrid/datagrid_abstract.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_DataGrid_Abstract = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'DataGrid_Abstract',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({comp: ["Card_Header", {}, function(Card_Header) { let _output = [];
|
|
_output.push(" "); (() => { const result = content('DG_Card_Header');; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; }.bind(this)]});
|
|
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Redrawable", {"id": "datagrid_table_header" + ":" + this._cid, "data-id": "datagrid_table_header", "_tag": "thead"}, function(Redrawable) { let _output = [];
|
|
_output.push(" "); (() => { const result = content('DG_Table_Header');; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; }.bind(this)]});
|
|
_output.push({comp: ["Redrawable", {"id": "datagrid_table_body" + ":" + this._cid, "data-id": "datagrid_table_body", "class": ((this.data.loading && this.data.rows.length === 0) ? 'is-loading' : (this.data.is_empty ? 'is-empty' : '')), "_tag": "tbody"}, function(Redrawable) { let _output = [];
|
|
_output.push(" "); if (this.data.loading && this.data.rows.length === 0) {
|
|
_output.push({tag: ["tr", {"class": "loading-row"}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "999", "class": "text-center py-5"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "spinner-border text-primary mb-3", "role": "status"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>"); _output.push(" "); _output.push("</div>"); _output.push({tag: ["p", {"class": "text-muted"}, false]}); _output.push("Loading..."); _output.push("</p>"); _output.push(" "); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (this.data.is_empty) {
|
|
_output.push({tag: ["tr", {"class": "empty-row"}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "999", "class": "text-center py-5"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-inbox", "style": "font-size: 3rem; color: #6c757d;"}, false]}); _output.push("</i>"); _output.push(" "); if (this.data.filter) { _output.push({tag: ["p", {"class": "text-muted mt-3"}, false]}); _output.push("No results found for \""); (() => { const result = this.data.filter ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("\""); _output.push("</p>"); _output.push(" "); _output.push({tag: ["button", {"id": "clear_filter_btn" + ":" + this._cid, "data-id": "clear_filter_btn", "class": "btn btn-sm btn-secondary mt-2"}, false]}); _output.push("Clear Filter"); _output.push("</button>"); _output.push(" "); } else { _output.push({tag: ["p", {"class": "text-muted mt-3"}, false]}); _output.push("No results found"); _output.push("</p>"); _output.push(" "); } _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
for(let row of this.data.rows) {
|
|
(() => { const result = content('row', row);; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); }
|
|
}
|
|
return [_output, this]; }.bind(this)]});
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({comp: ["Card_Footer", {}, function(Card_Footer) { let _output = [];
|
|
_output.push(" "); _output.push({tag: ["div", {"class": "d-flex gap-2 align-items-center"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "dropdown"}, false]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown"}, false]}); _output.push(" "); _output.push(" Actions "); _output.push("</button>"); _output.push(" "); _output.push({tag: ["ul", {"class": "dropdown-menu"}, false]}); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Export Selected"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Delete Selected"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push(" "); _output.push({tag: ["hr", {"class": "dropdown-divider"}, true]}); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Mark as Active"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push("</ul>"); _output.push("</div>"); _output.push({comp: ["Pagination_Info", {"id": "pagination_info" + ":" + this._cid, "data-id": "pagination_info"}, function(Pagination_Info) {
|
|
const _output = [];
|
|
_output.push(" "); if (this.data.total && this.data.page && this.data.per_page) { /* empty line */
|
|
const start = ((this.data.page - 1) * this.data.per_page) + 1;
|
|
const end = Math.min(this.data.page * this.data.per_page, this.data.total); _output.push(" Showing "); (() => { const result = start ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = end ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.data.total ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); } _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({comp: ["Pagination_Controls", {"id": "pagination_controls" + ":" + this._cid, "data-id": "pagination_controls"}, function(Pagination_Controls) {
|
|
const _output = [];
|
|
_output.push(" "); if (this.data.total_pages && this.data.total_pages > 1) { /* empty line */
|
|
const currentPage = this.data.page || 1;
|
|
const totalPages = this.data.total_pages;
|
|
const maxVisible = 7; // Maximum page numbers to show
|
|
/* empty line */
|
|
// Calculate page range to display
|
|
let startPage, endPage;
|
|
/* empty line */
|
|
if (totalPages <= maxVisible) {
|
|
// Show all pages if total is less than max
|
|
startPage = 1;
|
|
endPage = totalPages;
|
|
} else {
|
|
// Calculate range with current page near center
|
|
const maxPagesBeforeCurrentPage = Math.floor(maxVisible / 2);
|
|
const maxPagesAfterCurrentPage = Math.ceil(maxVisible / 2) - 1;
|
|
/* empty line */
|
|
if (currentPage <= maxPagesBeforeCurrentPage) {
|
|
// Near the start
|
|
startPage = 1;
|
|
endPage = maxVisible;
|
|
} else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
|
|
// Near the end
|
|
startPage = totalPages - maxVisible + 1;
|
|
endPage = totalPages;
|
|
} else {
|
|
// In the middle
|
|
startPage = currentPage - maxPagesBeforeCurrentPage;
|
|
endPage = currentPage + maxPagesAfterCurrentPage;
|
|
}
|
|
}
|
|
/* empty line */
|
|
// Generate page numbers array
|
|
const pages = [];
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
pages.push(i);
|
|
}
|
|
/* empty line */
|
|
const showStartEllipsis = startPage > 1;
|
|
const showEndEllipsis = endPage < totalPages; _output.push({tag: ["li", {"class": "page-item" + (currentPage === 1 ? 'disabled' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (currentPage - 1), "tabindex": (currentPage === 1 ? '-1' : '0')}, false]}); _output.push(" "); _output.push(" Previous "); _output.push("</a>"); _output.push(" "); _output.push("</li>"); if (showStartEllipsis) { _output.push({tag: ["li", {"class": "page-item"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": "1"}, false]}); _output.push("1"); _output.push("</a>"); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {"class": "page-item disabled"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "page-link"}, false]}); _output.push("..."); _output.push("</span>"); _output.push(" "); _output.push("</li>"); } for (let pageNum of pages) { console.log("Loop check", pageNum, currentPage); _output.push({tag: ["li", {"class": "page-item" + (pageNum === currentPage ? 'active' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (pageNum)}, false]}); _output.push(" "); (() => { const result = pageNum ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</a>"); _output.push("</li>"); } if (showEndEllipsis) { _output.push({tag: ["li", {"class": "page-item disabled"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "page-link"}, false]}); _output.push("..."); _output.push("</span>"); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {"class": "page-item"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (totalPages)}, false]}); (() => { const result = totalPages ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>"); _output.push(" "); _output.push("</li>"); } _output.push({tag: ["li", {"class": "page-item" + (currentPage === totalPages ? 'disabled' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (currentPage + 1)}, false]}); _output.push(" "); _output.push(" Next "); _output.push("</a>"); _output.push(" "); _output.push("</li>"); }
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_DataGrid_Abstract);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cafa46b601e1b05d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_delete.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_Delete = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_Delete',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-danger", "title": "Delete"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_Delete);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_39f39e3b268dbe32.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_edit.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_Edit = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_Edit',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "btn btn-secondary", "title": "Edit"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_Edit);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_40cbd9b14342dbca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_view.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_View = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_View',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "btn btn-primary", "title": "View"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_View);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c4cd6b6689b37222.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/activity_feed.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Activity_Feed = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Activity_Feed',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "list-group list-group-flush"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center py-4"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2 text-muted small"}, false]}); _output.push("Loading activity..."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
} else if (this.data.activities && this.data.activities.length === 0) {
|
|
_output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "activity", "data-title": "No activity yet", "data-message": "Activity will appear here"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" "); for (let activity of this.data.activities || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "list-group-item d-flex gap-3 py-3"}, false]});
|
|
_output.push(" "); if (activity.avatar) {
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": activity.avatar, "data-size": "sm"}]});
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "rounded-circle bg-primary text-white d-flex align-items-center justify-content-center", "style": "width: 32px; height: 32px; flex-shrink: 0;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (activity.icon || 'activity')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {}, false]}); (() => { const result = activity.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); (() => { const result = activity.action ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = activity.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
if (activity.description) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-1"}, false]}); (() => { const result = activity.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (activity.metadata) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" "); for (let key in activity.metadata) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-light text-dark me-1"}, false]});
|
|
_output.push(" "); (() => { const result = key ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(": "); (() => { const result = activity.metadata[key] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Activity_Feed);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_16e12ed0cd36683b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/actor_reference.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Actor_Reference = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Actor_Reference',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted d-block mt-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Actor_Reference);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_94c8ee6c8ba68a1d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/advanced_search_panel.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Advanced_Search_Panel = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Advanced_Search_Panel',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); _output.push("Advanced Search"); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["form", {"id": "search_form" + ":" + this._cid, "data-id": "search_form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "row g-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Input_With_Validation", {"data-label": "Keywords", "data-placeholder": "Search keywords...", "data-name": "keywords", "id": "keywords" + ":" + this._cid, "data-id": "keywords"}]});
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Searchable_Select", {"data-label": "Category", "data-placeholder": "Select category", "id": "category" + ":" + this._cid, "data-id": "category"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Multi_Select", {"data-label": "Tags", "data-placeholder": "Select tags", "id": "tags" + ":" + this._cid, "data-id": "tags"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"data-label": "From Date", "id": "from_date" + ":" + this._cid, "data-id": "from_date"}]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"data-label": "To Date", "id": "to_date" + ":" + this._cid, "data-id": "to_date"}]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); _output.push("Sort By"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "sort_by" + ":" + this._cid, "data-id": "sort_by"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "relevance"}, false]}); _output.push("Relevance"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "date"}, false]}); _output.push("Date"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "title"}, false]}); _output.push("Title"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-check"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "exact_match" + ":" + this._cid, "data-id": "exact_match"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-check-label"}, false]});
|
|
_output.push(" "); _output.push(" Exact match only "); _output.push("</label>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</form>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-footer d-flex justify-content-between"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "reset_btn" + ":" + this._cid, "data-id": "reset_btn"}, function(Button_Secondary) { let _output = []; _output.push("Reset"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "search_btn" + ":" + this._cid, "data-id": "search_btn"}, function(Button_Primary) { let _output = []; _output.push("Search"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Advanced_Search_Panel);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9785d1ab0167c4c2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/alert_banner.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Alert_Banner = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Alert_Banner',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "alert alert-info alert-dismissible fade show", "role": "alert"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "data-bs-dismiss": "alert", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Alert_Banner);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_23f6ef44135b0ff4.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/avatar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Avatar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Avatar',
|
|
tag: 'img',
|
|
defaultAttributes: {"class": "rounded-circle", "alt": "User avatar"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Avatar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9b93da3b449e709a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/blockquote.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Blockquote = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Blockquote',
|
|
tag: 'blockquote',
|
|
defaultAttributes: {"class": "blockquote"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Blockquote);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8962f68b97d8e8f3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/breadcrumbs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumbs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumbs',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "breadcrumb"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["ol", {"class": "breadcrumb mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ol>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumbs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_afe144bdfa61d3cd.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/bulk_action_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Bulk_Action_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Bulk_Action_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "alert alert-primary d-flex justify-content-between align-items-center mb-3", "role": "alert"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {"class": "count"}, false]}); _output.push("0"); _output.push("</strong>"); _output.push(" items selected "); _output.push("</div>");
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-2"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Bulk_Action_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e544f4c81faee9c9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/bulk_selection.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Bulk_Selection = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Bulk_Selection',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "form-check"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "checkbox" + ":" + this._cid, "data-id": "checkbox", "aria-label": "Select all"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Bulk_Selection);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2f4eef67eee9d66a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "btn-group", "role": "group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b239d09fd9e8122f.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_primary.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Primary = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Primary',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-primary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Primary);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3ad6fdf2a551145b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_secondary.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Secondary = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Secondary',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-secondary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Secondary);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bcfe3c72ddaa89e1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_90dcdfb9bcaea588.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/calendar_event.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Calendar_Event = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Calendar_Event',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-2", "style": "cursor: pointer;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body p-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-start gap-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-" + (this.args.color || 'primary') + "rounded", "style": "width: 4px; height: 100%; min-height: 40px;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold small"}, false]}); (() => { const result = this.args.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-clock me-1"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.time ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.location) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-geo-alt me-1"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.location ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Calendar_Event);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_21cc4349a5469d96.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/calendar_grid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Calendar_Grid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Calendar_Grid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "prev_btn" + ":" + this._cid, "data-id": "prev_btn"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-chevron-left"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "today_btn" + ":" + this._cid, "data-id": "today_btn"}, false]}); _output.push("Today"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "next_btn" + ":" + this._cid, "data-id": "next_btn"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-chevron-right"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["h5", {"class": "mb-0", "id": "month_title" + ":" + this._cid, "data-id": "month_title"}, false]}); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-view": "month"}, false]}); _output.push("Month"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-view": "week"}, false]}); _output.push("Week"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-bordered mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {"class": "table-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Sun"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Mon"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Tue"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Wed"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Thu"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Fri"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Sat"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {"id": "calendar_body" + ":" + this._cid, "data-id": "calendar_body"}, false]});
|
|
_output.push(" "); _output.push("<!-- Generated via JavaScript -->");
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Calendar_Grid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c7f2613cd27ca298.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_footer.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Footer = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Footer',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-footer bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Footer);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ebb90bbbba9ffc1b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Header',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-header bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_046c6fa8cf01a4ee.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_title.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Title = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Title',
|
|
tag: 'h5',
|
|
defaultAttributes: {"class": "mb-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Title);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fd9575173d3ff436.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bb17642e22644b05.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/chart_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Chart_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Chart_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "chart-placeholder bg-light rounded d-flex align-items-center justify-content-center"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center text-muted p-5"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-graph-up fs-1 d-block mb-2"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["p", {"class": "mb-0"}, false]}); _output.push("Chart Component"); _output.push("</p>");
|
|
_output.push(" ");_output.push({tag: ["small", {}, false]}); _output.push("Placeholder for future chart integration"); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Chart_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c5c07318a6a9c3fb.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/checkbox.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Checkbox = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Checkbox',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "checkbox", "class": "form-check-input"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Checkbox);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_91cd4a0023337040.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/code_block.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Code_Block = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Code_Block',
|
|
tag: 'pre',
|
|
defaultAttributes: {"class": "p-3 bg-dark text-light rounded"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["code", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</code>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Code_Block);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_915ef00c65975793.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/column_visibility_toggle.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Column_Visibility_Toggle = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Column_Visibility_Toggle',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary btn-sm dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-columns"}, false]}); _output.push("</i>"); _output.push(" Columns "); _output.push("</button>");
|
|
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamically populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Column_Visibility_Toggle);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b3e6a83d01905036.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/comment_thread.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Comment_Thread = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Comment_Thread',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); _output.push("Comments (");_output.push({tag: ["span", {"id": "comment_count" + ":" + this._cid, "data-id": "comment_count"}, false]}); (() => { const result = (this.data.comments || []).length ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>"); _output.push(")"); _output.push("</h5>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "comments" + ":" + this._cid, "data-id": "comments"}, false]});
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center py-4"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
} else if (this.data.comments && this.data.comments.length === 0) {
|
|
_output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "chat-left-text", "data-title": "No comments yet", "data-message": "Be the first to comment"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" "); for (let comment of this.data.comments || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3 mb-4", "data-comment-id": (comment.id)}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": comment.avatar, "data-name": comment.user_name, "data-size": "sm"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-light rounded p-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start mb-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {}, false]}); (() => { const result = comment.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = comment.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {}, false]}); (() => { const result = comment.text ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 me-3 reply-btn"}, false]}); _output.push("Reply"); _output.push("</button>");
|
|
_output.push(" "); if (comment.can_edit) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 me-3 edit-btn"}, false]}); _output.push("Edit"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (comment.can_delete) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 text-danger delete-btn"}, false]}); _output.push("Delete"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
if (comment.replies && comment.replies.length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "ms-4 mt-3"}, false]});
|
|
_output.push(" "); for (let reply of comment.replies) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3 mb-3", "data-comment-id": (reply.id)}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": reply.avatar, "data-name": reply.user_name, "data-size": "xs"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-light rounded p-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start mb-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {"class": "small"}, false]}); (() => { const result = reply.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = reply.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "small"}, false]}); (() => { const result = reply.text ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push("<!-- New comment form -->");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-4 pt-4 border-top", "id": "new_comment_form" + ":" + this._cid, "data-id": "new_comment_form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": this.args.current_user_avatar, "data-name": this.args.current_user_name, "data-size": "sm"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control mb-2", "rows": "3", "placeholder": "Write a comment...", "id": "comment_input" + ":" + this._cid, "data-id": "comment_input"}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "submit_btn" + ":" + this._cid, "data-id": "submit_btn"}, function(Button_Primary) { let _output = []; _output.push("Post Comment"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Comment_Thread);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8e90648b1e516e10.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contact_actions.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contact_Actions = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contact_Actions',
|
|
tag: 'td',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contact_Actions);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7f748fe97d884387.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contact_row.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contact_Row = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contact_Row',
|
|
tag: 'tr',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contact_Row);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_522acc1e0535a8e0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contacts_data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_Data_Table',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-body p-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Company"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Role"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Created"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("#CT001"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("Jane Smith"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("jane@acme.com"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 123-4567"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Acme Corporation"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CEO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 15, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT002"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Bob Johnson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("bob@techsolutions.io"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 234-5678"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Tech Solutions Inc"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CTO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 18, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT003"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sarah Wilson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("sarah@globalent.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 345-6789"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Global Enterprises"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Project Manager"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Pending"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 02, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT004"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Michael Brown"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("mbrown@innovation.co"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 456-7890"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("StartUp Innovations"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Developer"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 10, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT005"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Emily Davis"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("emily@wilson.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 567-8901"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Wilson & Associates"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Marketing Director"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Suspended"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 15, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT006"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("David Martinez"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("david@dmppro.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 678-9012"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Digital Marketing Pro"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sales Manager"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 01, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT007"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jennifer Anderson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("jennifer@andersonind.net"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 789-0123"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Anderson Industries"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CFO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 05, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT008"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Robert Thompson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("robert@creativestudios.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 890-1234"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Creative Studios LLC"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Art Director"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Pending"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 12, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT009"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Lisa Garcia"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("lisa@garciaconsult.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 901-2345"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Garcia Consulting"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Consultant"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 18, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT010"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Christopher White"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("chris@whitepartners.org"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 012-3456"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("White & Partners"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Partner"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 22, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contacts_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_11caea8e6e7fc2d3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contacts_list_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_List_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_List_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contacts_List_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2b0dad9b2a4c6834.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/date_picker.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Date_Picker = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Date_Picker',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-calendar"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "date", "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Date_Picker);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_865ebd1e323b6278.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/dropdown_menu.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Dropdown_Menu = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Dropdown_Menu',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "toggle" + ":" + this._cid, "data-id": "toggle"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { const result = this.args.label || 'Menu' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu", "aria-labelledby": "toggle", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Dropdown_Menu);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c4180645ca8fee3a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/empty_state.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Empty_State = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Empty_State',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "text-center py-5"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mb-3 text-muted", "style": "font-size: 3rem;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": this.args.icon || 'inbox'}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["h5", {"class": "text-muted"}, false]}); (() => { const result = this.args.title || 'No items found' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["p", {"class": "text-muted"}, false]}); (() => { const result = this.args.message || 'Get started by creating a new item.' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</p>");
|
|
_output.push(" "); if (this.args.action_label) {
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {}, function(Button_Primary) { let _output = []; (() => { const result = this.args.action_label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Empty_State);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_92f90b187b0143cf.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/export_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Export_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Export_Button',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-" + (this.args.variant || 'primary') + "dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-download"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.label || 'Export' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "csv"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-csv me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as CSV "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "excel"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-xlsx me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as Excel "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "pdf"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-pdf me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as PDF "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "json"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-json me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as JSON "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Export_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9a5639b57b894f70.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/file_upload.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_File_Upload = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'File_Upload',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border rounded p-4 text-center", "id": "drop_zone" + ":" + this._cid, "data-id": "drop_zone", "style": "cursor: pointer; transition: all 0.2s;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "file", "class": "d-none", "id": "file_input" + ":" + this._cid, "data-id": "file_input"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "placeholder" + ":" + this._cid, "data-id": "placeholder"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-cloud-upload fs-1 text-muted"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-primary"}, false]}); _output.push("Click to upload"); _output.push("</span>"); _output.push(" or drag and drop "); _output.push("</div>");
|
|
|
|
_output.push(" "); if (this.args.accept) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-1"}, false]}); (() => { const result = this.args.accept ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.max_size) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]}); _output.push("Max size: "); (() => { const result = this.args.max_size ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "file_info" + ":" + this._cid, "data-id": "file_info", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-file-earmark fs-1 text-success"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2", "id": "file_name" + ":" + this._cid, "data-id": "file_name"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small", "id": "file_size" + ":" + this._cid, "data-id": "file_size"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "remove_btn" + ":" + this._cid, "data-id": "remove_btn", "class": "mt-2"}, function(Button_Secondary) { let _output = []; _output.push("Remove"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "progress" + ":" + this._cid, "data-id": "progress", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Progress_Bar", {"id": "progress_bar" + ":" + this._cid, "data-id": "progress_bar"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-2"}, false]}); _output.push("Uploading..."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_File_Upload);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e8b264b6e5dbbf91.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/filter_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Filter_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Filter_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "row g-3 align-items-end"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Search"); _output.push("</label>");
|
|
_output.push(" "); _output.push({comp: ["Input_With_Icon", {"data-icon": "search", "data-placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Status"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "status" + ":" + this._cid, "data-id": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); _output.push("All"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Date Range"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "date_range" + ":" + this._cid, "data-id": "date_range"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); _output.push("All Time"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "today"}, false]}); _output.push("Today"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "week"}, false]}); _output.push("This Week"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "month"}, false]}); _output.push("This Month"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "custom"}, false]}); _output.push("Custom Range"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto", "id": "custom_dates" + ":" + this._cid, "data-id": "custom_dates", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"id": "start_date" + ":" + this._cid, "data-id": "start_date"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto", "id": "custom_dates_end" + ":" + this._cid, "data-id": "custom_dates_end", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"id": "end_date" + ":" + this._cid, "data-id": "end_date"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto ms-auto"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "clear_btn" + ":" + this._cid, "data-id": "clear_btn"}, function(Button_Secondary) { let _output = []; _output.push("Clear Filters"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "apply_btn" + ":" + this._cid, "data-id": "apply_btn", "class": "ms-2"}, function(Button_Primary) { let _output = []; _output.push("Apply"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "mt-3", "id": "active_filters" + ":" + this._cid, "data-id": "active_filters", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted me-2"}, false]}); _output.push("Active filters:"); _output.push("</small>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-inline-block", "id": "filter_tags" + ":" + this._cid, "data-id": "filter_tags"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Filter_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_86bdf5e6b735bb21.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_actions_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Actions_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Actions_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.cancel_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.cancel_url), "class": "btn btn-secondary"}, false]}); (() => { const result = this.args.cancel_text || 'Cancel' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "type": "submit"}, false]}); (() => { const result = this.args.submit_text || 'Save' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</button>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Actions_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c125b86d10e97419.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_field_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Form Section' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" "); if (this.args.description) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = this.args.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1e85106de52ce305.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_group_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Group_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Group_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"for": (this.args.id)}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.type === 'select') {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "[object Object]", "required": "true"}, false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</select>");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "[object Object]"}, false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</select>");
|
|
}
|
|
_output.push(" "); } else if (this.args.type === 'textarea') {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control", "id": "[object Object]", "rows": (this.args.rows || 4), "placeholder": (this.args.placeholder || ''), "required": "true"}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control", "id": "[object Object]", "rows": (this.args.rows || 4), "placeholder": (this.args.placeholder || '')}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); }
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-control", "id": "[object Object]", "type": (this.args.type || 'text'), "placeholder": (this.args.placeholder || ''), "required": "true"}, true]}); _output.push("</input>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-control", "id": "[object Object]", "type": (this.args.type || 'text'), "placeholder": (this.args.placeholder || '')}, true]}); _output.push("</input>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Group_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_72937efe895dac3c.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_row_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Row_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Row_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Row_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9f9f86aba7786134.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_validation_message.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Validation_Message = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Validation_Message',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "invalid-feedback"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Validation_Message);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2246bd22f8e9add5.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/gantt_chart.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Gantt_Chart = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Gantt_Chart',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Project Timeline' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-bordered mb-0", "style": "table-layout: fixed;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {"class": "table-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 200px;"}, false]}); _output.push("Task"); _output.push("</th>");
|
|
_output.push(" "); for (let month of this.data.months || []) {
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center small"}, false]}); (() => { const result = month ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</th>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"colspan": "100", "class": "text-center py-5"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push("</tr>");
|
|
} else {
|
|
_output.push(" "); for (let task of this.data.tasks || []) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"class": "align-middle"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold"}, false]}); (() => { const result = task.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); if (task.assignee) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = task.assignee ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</td>");
|
|
for (let i = 0; i < (this.data.months || []).length; i++) {
|
|
_output.push(" ");_output.push({tag: ["td", {"class": "p-1 align-middle"}, false]});
|
|
_output.push(" "); if (task.start_month <= i && task.end_month >= i) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-" + (task.color || 'primary') + "rounded p-2 text-white small text-center"}, false]});
|
|
_output.push(" "); (() => { const result = task.start_month === i ? task.name : '' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Gantt_Chart);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bd1cce1a76e13af1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-secondary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_31b59dfa6b448fb1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_with_label.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_With_Label = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_With_Label',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-inline-flex align-items-center gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": this.args.icon}]});
|
|
_output.push(" ");_output.push({tag: ["span", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_With_Label);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0dec1f395fabb9f3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_with_text.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_With_Text = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_With_Text',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex align-items-center py-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-circle-fill me-2 text-primary", "style": "font-size: 0.5rem;"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "flex-grow-1"}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_With_Text);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cbefc50830c7e1b7.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon',
|
|
tag: 'svg',
|
|
defaultAttributes: {"class": "icon icon-xs", "fill": "currentColor", "viewBox": "0 0 24 24", "xmlns": "http://www.w3.org/2000/svg"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f277ab5240123d0d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/info_box.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Info_Box = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Info_Box',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "p-3 mb-3 bg-light border-start border-primary border-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Info_Box);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c6771957d17edc03.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/inline_edit_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Inline_Edit_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Inline_Edit_Field',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex align-items-center gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "display_mode" + ":" + this._cid, "data-id": "display_mode", "style": "cursor: pointer;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "value_display" + ":" + this._cid, "data-id": "value_display"}, false]}); (() => { const result = this.args.value || this.args.placeholder || 'Click to edit' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil text-muted ms-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "edit_mode" + ":" + this._cid, "data-id": "edit_mode", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group input-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "text", "class": "form-control", "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-success", "type": "button", "id": "save_btn" + ":" + this._cid, "data-id": "save_btn", "title": "Save"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-lg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "type": "button", "id": "cancel_btn" + ":" + this._cid, "data-id": "cancel_btn", "title": "Cancel"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-x-lg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Inline_Edit_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_27017433acf49ce1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input_with_icon.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input_With_Icon = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input_With_Icon',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "input-group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.icon_position !== 'end') {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (this.args.icon || 'search')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["input", {"type": (this.args.type || 'text'), "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.icon_position === 'end') {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (this.args.icon || 'search')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input_With_Icon);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8f20f47d36d9f4f1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input_with_validation.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input_With_Validation = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input_With_Validation',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label", "id": "label" + ":" + this._cid, "data-id": "label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); if (this.args.required) {_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>"); }
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["input", {"type": (this.args.type || 'text'), "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "invalid-feedback", "id": "error" + ":" + this._cid, "data-id": "error"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "valid-feedback", "id": "success" + ":" + this._cid, "data-id": "success"}, false]}); _output.push("</div>");
|
|
_output.push(" "); if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input_With_Validation);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f2c3b3f07b2cfc23.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "text", "class": "form-control"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3cd257bb9dd3ef15.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/kanban_board.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Kanban_Board = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Kanban_Board',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex gap-3", "style": "overflow-x: auto;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "w-100 text-center py-5"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" "); for (let column of this.data.columns || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card", "style": "min-width: 300px; max-width: 300px;", "data-column-id": (column.id)}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h6", {"class": "mb-0"}, false]}); (() => { const result = column.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h6>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); (() => { const result = column.cards.length ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-2", "style": "min-height: 400px; max-height: 600px; overflow-y: auto;", "data-column-cards": (column.id)}, false]});
|
|
_output.push(" "); for (let card of column.cards) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card mb-2", "draggable": "true", "data-card-id": (card.id)}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body p-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold mb-2"}, false]}); (() => { const result = card.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); if (card.description) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mb-2"}, false]}); (() => { const result = card.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (card.tags && card.tags.length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mb-2"}, false]});
|
|
_output.push(" "); for (let tag of card.tags) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-light text-dark me-1"}, false]}); (() => { const result = tag ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); if (card.assignee) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center gap-2"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-name": card.assignee, "data-size": "xs"}]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = card.assignee ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Kanban_Board);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_66091e157d531d0d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/link.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Link = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Link',
|
|
tag: 'a',
|
|
defaultAttributes: {"href": "#"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Link);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5cb3cbf116fa5289.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/list.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_List = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'List',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "list-group list-group-flush"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_List);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ee1dd5e5562b7d50.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/loading_skeleton.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Loading_Skeleton = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Loading_Skeleton',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "placeholder-glow"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-12"}, false]}); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-10"}, false]}); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-8"}, false]}); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Loading_Skeleton);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a0cf37c460ea7ee3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/metric_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Metric_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Metric_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card h-100"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-body p-4"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Metric_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5300a706b2d27d65.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/mobile_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Mobile_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Mobile_Header',
|
|
tag: 'header',
|
|
defaultAttributes: {"class": "navbar navbar-light bg-light d-lg-none"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "container-fluid"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "navbar-toggler", "type": "button", "data-bs-toggle": "offcanvas", "data-bs-target": "#mobileSidebar", "aria-controls": "mobileSidebar"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "navbar-toggler-icon"}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["span", {"class": "navbar-brand mb-0 h1"}, false]}); _output.push("PSM"); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center gap-2"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Mobile_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8e635c235d2a1b12.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/modal_dialog.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Modal_Dialog = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Modal_Dialog',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "modal fade", "tabindex": "-1", "aria-hidden": "true"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-dialog"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-content"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "modal-title", "id": "title" + ":" + this._cid, "data-id": "title"}, false]}); (() => { const result = this.args.title || 'Modal' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "data-bs-dismiss": "modal", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-body", "id": "body" + ":" + this._cid, "data-id": "body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"data-bs-dismiss": "modal"}, function(Button_Secondary) { let _output = []; _output.push("Close"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "confirm" + ":" + this._cid, "data-id": "confirm"}, function(Button_Primary) { let _output = []; _output.push("Confirm"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Modal_Dialog);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7095e51c2533c441.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/multi_select.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Multi_Select = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Multi_Select',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle w-100 text-start", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "button" + ":" + this._cid, "data-id": "button"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "selected_text" + ":" + this._cid, "data-id": "selected_text"}, false]}); (() => { const result = this.args.placeholder || 'Select options' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu w-100", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "search", "class": "form-control form-control-sm", "placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "options" + ":" + this._cid, "data-id": "options", "style": "max-height: 250px; overflow-y: auto;"}, false]});
|
|
_output.push(" "); _output.push("<!-- Options populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2 d-flex justify-content-between"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-link btn-sm p-0", "id": "clear_all" + ":" + this._cid, "data-id": "clear_all"}, false]}); _output.push("Clear All"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-link btn-sm p-0", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, false]}); _output.push("Select All"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Multi_Select);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b3fc253174c86570.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/notification_badge.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Notification_Badge = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Notification_Badge',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "position-relative"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger", "id": "count" + ":" + this._cid, "data-id": "count", "style": ((this.args.count > 0 ? '' : 'display: none;'))}, false]});
|
|
|
|
|
|
_output.push(" "); (() => { const result = this.args.count || 0 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Notification_Badge);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5f169cc80d559d94.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/notification_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Notification_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Notification_Dropdown',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link position-relative", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": "bell"}]});
|
|
_output.push(" "); if (this.args.unread_count > 0) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.unread_count ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu dropdown-menu-end", "style": "width: 320px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "dropdown-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "fw-bold"}, false]}); _output.push("Notifications"); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["a", {"href": "#", "class": "small"}, false]}); _output.push("Mark all read"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "overflow-auto", "style": "max-height: 400px;"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Notification_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fca9bd701278cdf2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/overdue_indicator.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Overdue_Indicator = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Overdue_Indicator',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge bg-warning text-dark d-block mt-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Overdue_Indicator);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_98f2e35a4e8f98a6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header_left.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header_Left = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header_Left',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header_Left);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3f3348e80138bd83.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header_right.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header_Right = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header_Right',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header_Right);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0a3eab3f332207ff.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex justify-content-between align-items-center mb-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2b286f1f39207482.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_section.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Section = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Section',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Section);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d6cf7c9e16e8f541.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_subtitle.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Subtitle = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Subtitle',
|
|
tag: 'p',
|
|
defaultAttributes: {"class": "text-muted mb-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Subtitle);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0ab20aacac832674.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_title.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Title = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Title',
|
|
tag: 'h1',
|
|
defaultAttributes: {"class": "h2 mb-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Title);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fcfe2eadb09b8b45.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_31fd149cfb317d39.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/pagination_controls.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pagination_Controls = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pagination_Controls',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "Table pagination"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination pagination-sm mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pagination_Controls);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e6ee289a952c7453.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/pagination_info.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pagination_Info = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pagination_Info',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pagination_Info);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_75460b9999183e3a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/popover.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Popover = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Popover',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-secondary", "data-bs-toggle": "popover"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { const result = this.args.label || 'Info' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Popover);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c31885d0846c31e6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/progress_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Progress_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Progress_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "progress"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "progress-bar", "role": "progressbar", "style": "width:" + (this.args.value || 0) + "%", "aria-valuenow": (this.args.value || 0), "aria-valuemin": "0", "aria-valuemax": "100", "id": "bar" + ":" + this._cid, "data-id": "bar"}, false]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Progress_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_090d679f00c495b6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/radio_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Radio_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Radio_Button',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "radio", "class": "form-check-input"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Radio_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b0b4f93e436d5119.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/record_count_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Record_Count_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Record_Count_Display',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Record_Count_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c55ba0e3e36e44d5.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/rich_text_editor.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rich_Text_Editor = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rich_Text_Editor',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border rounded"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border-bottom bg-light p-2", "id": "toolbar" + ":" + this._cid, "data-id": "toolbar"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "bold", "title": "Bold"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-bold"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "italic", "title": "Italic"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-italic"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "underline", "title": "Underline"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-underline"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "insertUnorderedList", "title": "Bullet List"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-list-ul"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "insertOrderedList", "title": "Numbered List"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-list-ol"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyLeft", "title": "Align Left"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-left"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyCenter", "title": "Align Center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-center"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyRight", "title": "Align Right"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-right"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "createLink", "title": "Insert Link"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-link"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "unlink", "title": "Remove Link"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-link-45deg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"contenteditable": "true", "class": "p-3", "style": "min-height: 200px; max-height: 400px; overflow-y: auto;", "id": "editor" + ":" + this._cid, "data-id": "editor"}, false]});
|
|
|
|
|
|
|
|
|
|
(() => { const result = this.args.value || '' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rich_Text_Editor);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_15b2ff9a7d6c41ca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/row_action_menu.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Row_Action_Menu = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Row_Action_Menu',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-sm btn-link text-muted dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push(" ⋮ "); _output.push("</button>");
|
|
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Row_Action_Menu);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f1b2503da86c7b29.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/Sample_Datagrid_Component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sample_Datagrid_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sample_Datagrid_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-header bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Data Table' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.args.showing || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.args.total || 100 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); (() => { const result = this.args.entity_name || 'items' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</small>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</th>");
|
|
}
|
|
_output.push(" ");
|
|
|
|
if (this.args.columns && this.args.columns.length > 0) {
|
|
_output.push(" "); for (let column of this.args.columns) {
|
|
_output.push(" ");_output.push({tag: ["th", {"style": ((column.width ? 'width: '+column.width : ''))}, false]});
|
|
_output.push(" "); (() => { const result = column.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</th>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Company"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Created"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
|
|
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");
|
|
if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");
|
|
for (let i = 0; i < (this.args.placeholder_rows || 10); i++) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "disabled": "true"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let j = 0; j < (this.args.columns ? this.args.columns.length : 8); j++) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "placeholder-glow"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-" + (Math.floor(Math.random() * 8) + 4)}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); } else if (this.data.rows && this.data.rows.length > 0) {
|
|
_output.push(" ");
|
|
for (let row of this.data.rows) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": row.id + ":" + this._cid, "data-id": row.id}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
|
|
if (this.args.columns) {
|
|
_output.push(" "); for (let column of this.args.columns) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" "); if (column.type === 'badge') {
|
|
_output.push(" ");
|
|
_output.push({tag: ["span", {"class": "badge bg-" + (row[column.field + '_color'] || 'secondary')}, false]});
|
|
_output.push(" "); (() => { const result = row[column.field] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
} else if (column.type === 'actions') {
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" "); if (this.args.view_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.view_url.replace('{id}', row.id)), "class": "btn btn-primary", "title": "View"}, false]});
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</a>");
|
|
}
|
|
_output.push(" "); if (this.args.edit_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.edit_url.replace('{id}', row.id)), "class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</a>");
|
|
}
|
|
_output.push(" "); if (this.args.allow_delete) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "id": "delete_button" + ":" + this._cid, "data-id": "delete_button", "title": "Delete"}, false]});
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" ");
|
|
(() => { const result = row[column.field] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</td>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["td", {}, false]}); (() => { const result = row.id ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.company ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.email ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.phone ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-" + (row.status_color || 'success')}, false]});
|
|
_output.push(" "); (() => { const result = row.status ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); (() => { const result = row.created ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Delete"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"colspan": ((this.args.selectable ? 1 : 0) + (this.args.columns ? this.args.columns.length : 8)), "class": "text-center text-muted py-5"}, false]});
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-inbox fs-1 d-block mb-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" No "); (() => { const result = this.args.entity_name || 'items' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" found "); _output.push("</td>");
|
|
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
|
|
if (this.args.pagination !== false && Object.keys(this.data).length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-footer bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.data.pagination?.from || 1 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = this.data.pagination?.to || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push(" of "); (() => { const result = this.data.pagination?.total || 100 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); _output.push("</small>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["nav", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination pagination-sm mb-0"}, false]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["li", {"class": "page-item" + (this.data.pagination?.current_page === 1 ? 'disabled' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "tabindex": "-1", "id": "prev_page" + ":" + this._cid, "data-id": "prev_page"}, false]}); _output.push("Previous"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
|
|
|
|
if (this.data.pagination?.pages) {
|
|
_output.push(" "); for (let page of this.data.pagination.pages) {
|
|
_output.push(" "); if (page === '...') {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item disabled"}, false]});_output.push({tag: ["a", {"class": "page-link", "href": "#"}, false]}); _output.push("..."); _output.push("</a>"); _output.push("</li>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item" + (page === this.data.pagination.current_page ? 'active' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (page)}, false]}); (() => { const result = page ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
for (let i = 1; i <= 5; i++) {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item" + (i === 1 ? 'active' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (i)}, false]}); (() => { const result = i ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
|
|
_output.push({tag: ["li", {"class": "page-item" + (this.data.pagination?.current_page === this.data.pagination?.total_pages ? 'disabled' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "id": "next_page" + ":" + this._cid, "data-id": "next_page"}, false]}); _output.push("Next"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push("</ul>");
|
|
_output.push("</nav>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sample_Datagrid_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9a27aa4290bb1e22.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "input-group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": "search"}]});
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "search", "class": "form-control", "placeholder": (this.args.placeholder || 'Search...'), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_82fa1779b5d52f06.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-secondary"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-search"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_90ce087c10b29f3c.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Input',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "search", "class": "form-control", "placeholder": "Search contacts...", "style": "width: 250px;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_87133ebd4afe5e36.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/searchable_select.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Searchable_Select = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Searchable_Select',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle w-100 text-start", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "button" + ":" + this._cid, "data-id": "button"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "selected_text" + ":" + this._cid, "data-id": "selected_text"}, false]}); (() => { const result = this.args.placeholder || 'Select an option' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu w-100", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "search", "class": "form-control form-control-sm", "placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "options" + ":" + this._cid, "data-id": "options", "style": "max-height: 250px; overflow-y: auto;"}, false]});
|
|
_output.push(" "); _output.push("<!-- Options populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Searchable_Select);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_aacf254b7210322b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/select_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Select_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Select_Dropdown',
|
|
tag: 'select',
|
|
defaultAttributes: {"class": "form-select"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Select_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_146e3e3c9db514f9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/sidebar_nav.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sidebar_Nav = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sidebar_Nav',
|
|
tag: 'nav',
|
|
defaultAttributes: {"class": "d-flex flex-column p-3 bg-light", "style": "width: 250px; min-height: 100vh;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["a", {"href": "/", "class": "d-flex align-items-center mb-3 text-decoration-none"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "fs-4 fw-bold"}, false]}); _output.push("PSM"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</a>");
|
|
_output.push({tag: ["hr", {}, true]}); _output.push("</hr>");
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "nav nav-pills flex-column mb-auto", "id": "nav_items" + ":" + this._cid, "data-id": "nav_items"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sidebar_Nav);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_dc81d680341fe1d9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/simple_table_test.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Simple_Table_Test = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Simple_Table_Test',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Test"); _output.push("</td>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</table>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Simple_Table_Test);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_875974d23c25e5e2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/sortable_column_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sortable_Column_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sortable_Column_Header',
|
|
tag: 'th',
|
|
defaultAttributes: {"class": "user-select-none", "style": "cursor: pointer;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center justify-content-between"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "ms-2", "id": "sort_icon" + ":" + this._cid, "data-id": "sort_icon"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "text-muted"}, false]}); _output.push("⇅"); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sortable_Column_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5724e547fb5ecdca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/spinner.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Spinner = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Spinner',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "spinner-border", "role": "status"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Spinner);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d7e6ffd2a74afdea.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/stat_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Stat_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Stat_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card text-center border-0 shadow-sm"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Stat_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5c147c4272fcbdfc.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/status_badge.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Status_Badge = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Status_Badge',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Status_Badge);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8d3bc06fac256488.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tab_content.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tab_Content = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tab_Content',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "tab-content mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tab_Content);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f657f12a0aa25bb7.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_body.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Body = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Body',
|
|
tag: 'tbody',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Body);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f586647b2517ead3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_headers.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Headers = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Headers',
|
|
tag: 'thead',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</tr>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Headers);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_18d1bbdb5a50465a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_pagination.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Pagination = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Pagination',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex justify-content-between align-items-center mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small", "id": "info" + ":" + this._cid, "data-id": "info"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.args.start || 1 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = this.args.end || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.args.total || 0 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); _output.push("</div>");
|
|
|
|
_output.push(" ");_output.push({tag: ["nav", {"aria-label": "Table pagination"}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination mb-0", "id": "pagination" + ":" + this._cid, "data-id": "pagination"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
_output.push("</nav>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Pagination);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_383242ee22658bf0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table',
|
|
tag: 'table',
|
|
defaultAttributes: {"class": "table table-hover"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ed2ddbf29c859aa9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tabs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tabs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tabs',
|
|
tag: 'ul',
|
|
defaultAttributes: {"class": "nav nav-tabs"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tabs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4150fd75011321be.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tag_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tag_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tag_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex flex-wrap gap-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tag_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a5dbed84a331830f.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tag.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tag = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tag',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge rounded-pill bg-secondary me-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tag);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_58a09a623e844c61.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/text_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Text_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Text_Display',
|
|
tag: 'span',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Text_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4ca4caa4aa2ac28a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/textarea.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Textarea = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Textarea',
|
|
tag: 'textarea',
|
|
defaultAttributes: {"class": "form-control", "rows": "4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Textarea);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cfb5cfb28a80dd74.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/three_column_layout.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Three_Column_Layout = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Three_Column_Layout',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Three_Column_Layout);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_aa4c1ba17a301e31.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/time_picker.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Time_Picker = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Time_Picker',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-clock"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "time", "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Time_Picker);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2031023f9f1c01f1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/timeline.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Timeline = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Timeline',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex flex-column gap-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Timeline);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_12433da901e62b43.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/timestamp_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Timestamp_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Timestamp_Display',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted d-block"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Timestamp_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_98934efba78289b0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tooltip.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tooltip = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tooltip',
|
|
tag: 'span',
|
|
defaultAttributes: {"data-bs-toggle": "tooltip", "data-bs-placement": "top"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tooltip);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_517d4f18a4791725.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/top_nav.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Top_Nav = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Top_Nav',
|
|
tag: 'nav',
|
|
defaultAttributes: {"class": "navbar navbar-expand-lg navbar-light bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "container-fluid"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "navbar-brand", "href": "/"}, false]}); _output.push("PSM"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "navbar-toggler", "type": "button", "data-bs-toggle": "collapse", "data-bs-target": "#navbarNav", "aria-controls": "navbarNav", "aria-expanded": "false", "aria-label": "Toggle navigation"}, false]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "navbar-toggler-icon"}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "collapse navbar-collapse", "id": "navbarNav"}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "navbar-nav ms-auto", "id": "nav_items" + ":" + this._cid, "data-id": "nav_items"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Top_Nav);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_16475a3ae7842075.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/trend_indicator.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Trend_Indicator = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Trend_Indicator',
|
|
tag: 'span',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Trend_Indicator);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0e49800ae2b20a04.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/two_column_layout.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Two_Column_Layout = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Two_Column_Layout',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Two_Column_Layout);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_09b2f3fdf425ee42.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/user_avatar_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_User_Avatar_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'User_Avatar_Dropdown',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link dropdown-toggle p-0 border-0", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "toggle" + ":" + this._cid, "data-id": "toggle"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": this.args.avatar_src, "data-name": this.args.user_name, "data-size": "sm"}]});
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_User_Avatar_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b75b5b5352e01ff2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/users_data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Users_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Users_Data_Table',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-body p-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": "select-all"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</th>");
|
|
_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Role"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Department"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Last Login"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Joined"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U001"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("JD"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" John Doe "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("john.doe@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Admin"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Engineering"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("2 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 15, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U002"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("JS"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Jane Smith "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("jane.smith@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Marketing"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 day ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 20, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U003"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("MB"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Mike Brown "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("mike.brown@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sales"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Inactive"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("5 days ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 10, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Activate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-circle"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U004"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("SW"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Sarah Wilson "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("sarah.wilson@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("HR"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("3 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Apr 05, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U005"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("TJ"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Tom Johnson "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("tom.j@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Support"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Suspended"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("2 weeks ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("May 12, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Reactivate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-arrow-clockwise"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U006"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("ED"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Emily Davis "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("emily.d@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Admin"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("IT"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Just now"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jun 01, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U007"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("CG"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Chris Garcia "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("chris.g@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Finance"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("6 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jul 15, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U008"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("AM"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Ashley Martinez "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("ashley.m@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Operations"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("12 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Aug 20, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U009"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("KL"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Kevin Lee "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("kevin.lee@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Design"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 day ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sep 10, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U010"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("RW"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Rachel White "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("rachel.w@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Legal"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Inactive"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 week ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Oct 05, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Activate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-circle"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Users_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4e0b9dea1b172d56.js === */
|
|
/* Compiled from: rsx/theme/components/modal/rsx_modal.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Modal = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Modal',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal fade rsx-modal", "tabindex": "-1", "id": "modal" + ":" + this._cid, "data-id": "modal"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-dialog", "id": "dialog" + ":" + this._cid, "data-id": "dialog"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-content"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-header", "id": "header" + ":" + this._cid, "data-id": "header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "modal-title", "id": "title" + ":" + this._cid, "data-id": "title"}, false]}); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn", "data-bs-dismiss": "modal", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-body", "id": "body" + ":" + this._cid, "data-id": "body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-body-content", "id": "body_content" + ":" + this._cid, "data-id": "body_content"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamic content inserted here -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamic buttons inserted here -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-backdrop fade", "id": "backdrop" + ":" + this._cid, "data-id": "backdrop"}, false]}); _output.push("</div>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Modal);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7217e9c37c215bd8.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/breadcrumb.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumb = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumb',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "breadcrumb"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["ol", {"class": "breadcrumb bg-transparent p-0 mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ol>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumb);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0437ab9d2970dd17.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/breadcrumb_item.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumb_Item = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumb_Item',
|
|
tag: 'li',
|
|
defaultAttributes: {"class": "breadcrumb-item"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.active) {
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); } else if (this.args.href) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.href)}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</a>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumb_Item);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_796750a84323e25c.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/client_label.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Label = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Label',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["i", {"class": "bi bi-building"}, false]}); _output.push("</i>");
|
|
_output.push(" "); if (this.data.loading) {
|
|
_output.push(" "); (() => { const result = this.args.placeholder || '------' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else if (this.data.client) {
|
|
_output.push(" "); (() => { const result = this.data.client.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" cadfdsa ");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); _output.push("Unknown Client"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Client_Label);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_84a4678f9228ae19.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/client_label_link.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Label_Link = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Label_Link',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["i", {"class": "bi bi-building"}, false]}); _output.push("</i>");
|
|
_output.push(" "); if (this.data.loading) {
|
|
_output.push(" "); (() => { const result = this.args.placeholder || '------' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else if (this.data.client) {
|
|
_output.push(" "); (() => { const result = this.data.client.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); _output.push("Unknown Client"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Client_Label_Link);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1f6b5c0a2361546e.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/text_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Text_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Text_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.type === 'textarea') {
|
|
_output.push(" ");_output.push({rawtag: ["textarea", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "class": "form-control", "rows": (this.args.rows || 3), "placeholder": (this.args.placeholder || '')}, ((this.args.disabled)) ? {"disabled": "true"} : {}), "undefined"]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else if (this.args.prefix || this.args.suffix) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" "); if (this.args.prefix) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]}); (() => { const result = this.args.prefix ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "type": (this.args.type || 'text'), "class": "form-control", "value": (this.data.value), "placeholder": (this.args.placeholder || '')}, ((this.args.min !== undefined)) ? {"min": (this.args.min)} : {}), ((this.args.max !== undefined)) ? {"max": (this.args.max)} : {}), ((this.args.maxlength)) ? {"maxlength": (this.args.maxlength)} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.suffix) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]}); (() => { const result = this.args.suffix ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "type": (this.args.type || 'text'), "class": "form-control", "value": (this.data.value), "placeholder": (this.args.placeholder || '')}, ((this.args.min !== undefined)) ? {"min": (this.args.min)} : {}), ((this.args.max !== undefined)) ? {"max": (this.args.max)} : {}), ((this.args.maxlength)) ? {"maxlength": (this.args.maxlength)} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Text_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_59c189b4fa652b8e.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.options) {
|
|
_output.push(" "); for (let opt of this.args.options) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3a30a5c5dfa4f0b9.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/ajax_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Ajax_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Ajax_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Please wait...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Ajax_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d3f44e3bcb81a874.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/checkbox_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Checkbox_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Checkbox_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-check"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "class": "form-check-input", "type": "checkbox"}, ((this.data.checked)) ? {"checked": "true"} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"id": "label" + ":" + this._cid, "data-id": "label", "class": "form-check-label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Checkbox_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_77d25c093236508a.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/wysiwyg_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Wysiwyg_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Wysiwyg_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "editor" + ":" + this._cid, "data-id": "editor", "style": "min-height: 200px; background: white;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "hidden", "id": "hidden_input" + ":" + this._cid, "data-id": "hidden_input"}, true]}); _output.push("</input>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Wysiwyg_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_23e1143d0e1cd60c.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/country_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Country_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Country_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Ajax_Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Please wait...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Country_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_717fc745d391ec0b.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/state_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_State_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'State_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Ajax_Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled || !this.data.country_code)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Select State...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_State_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1bc3e8b1a237bb35.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/profile_photo_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Profile_Photo_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Profile_Photo_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "position-relative"}, false]});
|
|
_output.push(" "); if (this.data.thumbnail_url) {
|
|
_output.push(" ");_output.push({tag: ["img", {"id": "photo" + ":" + this._cid, "data-id": "photo", "src": (this.data.thumbnail_url), "class": "rounded-circle me-3", "alt": "Profile Photo", "width": (this.args.width || 96), "height": (this.args.height || 96), "style": "opacity: 1;"}, true]}); _output.push("</img>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "photo" + ":" + this._cid, "data-id": "photo", "class": "user-profile-icon me-3", "style": "width:" + (this.args.width || 96) + "px; height:" + (this.args.height || 96) + "px; display: flex; align-items: center; justify-content: center;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-person-circle", "style": "font-size:" + (Math.round((this.args.width || 96) * 0.75)) + "px;"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "spinner" + ":" + this._cid, "data-id": "spinner", "class": "position-absolute top-50 start-50 translate-middle d-none"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "spinner-border text-primary", "role": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Uploading..."); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "file", "id": "file_input" + ":" + this._cid, "data-id": "file_input", "class": "d-none", "accept": (this.args.accept || 'image/jpeg,image/png,image/gif')}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "id": "upload_btn" + ":" + this._cid, "data-id": "upload_btn", "class": "btn btn-sm btn-primary me-2"}, false]}); _output.push("Upload New Photo"); _output.push("</button>");
|
|
_output.push(" "); if (this.args.show_remove && this.data.attachment_key) {
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "id": "remove_btn" + ":" + this._cid, "data-id": "remove_btn", "class": "btn btn-sm btn-danger"}, false]}); _output.push("Remove"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text mt-2"}, false]}); _output.push("JPG, PNG or GIF. Max size "); (() => { const result = this.args.max_size || 2 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("MB."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Profile_Photo_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7e9b52d659877f0d.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_tabs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Tabs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Tabs',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("<!-- Tab Navigation -->");
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "nav nav-tabs", "role": "tablist", "id": "nav" + ":" + this._cid, "data-id": "nav"}, false]});
|
|
_output.push(" "); _output.push("<!-- Tab headers will be rendered by Rsx_Tab components -->");
|
|
_output.push(" "); _output.push("</ul>");
|
|
|
|
_output.push("<!-- Tab Content Container -->");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "tab-content mt-4", "id": "content" + ":" + this._cid, "data-id": "content"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Tabs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_948e2845fa2cff99.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_tab.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Tab = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Tab',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "tab-pane fade", "role": "tabpanel"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Tab);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_dbf52270a0259e5e.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Form',
|
|
tag: 'form',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"id": "loader" + ":" + this._cid, "data-id": "loader", "class": "text-center py-5"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "spinner-border text-primary mb-3", "role": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["p", {"class": "text-muted"}, false]}); _output.push("Loading form..."); _output.push("</p>");
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"id": "form_content" + ":" + this._cid, "data-id": "form_content", "style": "display: none;"}, false]});
|
|
_output.push(" "); if (window.rsxapp.debug) {
|
|
_output.push(" ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"id": "error" + ":" + this._cid, "data-id": "error"}, false]}); _output.push("</div>");
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_24af8013a9dcda8c.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_field_abstract.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field_Abstract = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field_Abstract',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field_Abstract);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_10786dec1aed77bb.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "form-group mb-3"},
|
|
extends: 'Form_Field_Abstract',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label", "id": "form_label" + ":" + this._cid, "data-id": "form_label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(result); } })();
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": (this.has_error() ? 'is-invalid' : '')}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
if (this.has_error()) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "invalid-feedback d-block"}, false]});
|
|
_output.push(" "); (() => { const result = this.get_error() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "form-text text-muted d-block mt-1"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</small>");
|
|
}
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_df8486e42e28be4f.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_hidden_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Hidden_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Hidden_Field',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "hidden", "class": "Widget"},
|
|
extends: 'Form_Field_Abstract',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Hidden_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5e1e2e4a50922d32.js === */
|
|
/* Compiled from: rsx/theme/components/forms/pin_verification_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pin_Verification_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pin_Verification_Form',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
extends: 'Rsx_Form',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "pin-verification-form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "pin-inputs d-flex justify-content-center gap-2 mb-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_0" + ":" + this._cid, "data-id": "digit_0", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "0"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_1" + ":" + this._cid, "data-id": "digit_1", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "1"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_2" + ":" + this._cid, "data-id": "digit_2", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "2"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_3" + ":" + this._cid, "data-id": "digit_3", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "3"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_4" + ":" + this._cid, "data-id": "digit_4", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "4"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_5" + ":" + this._cid, "data-id": "digit_5", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "5"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"id": "error_container" + ":" + this._cid, "data-id": "error_container", "class": "alert alert-danger", "style": "display: none;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "text-center text-muted small"}, false]});
|
|
_output.push(" "); _output.push(" Enter the 6-digit PIN code "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pin_Verification_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Dev_Bundle_f2d087f4.js === */
|
|
// JavaScript Manifest - Generated by BundleCompiler
|
|
// Registers all classes in this bundle for runtime introspection
|
|
Manifest._define([
|
|
[Manifest, "Manifest", null],
|
|
[Rsx_Behaviors, "Rsx_Behaviors", null],
|
|
[Rsx_Cache, "Rsx_Cache", null],
|
|
[Rsx_Init, "Rsx_Init", null],
|
|
[Rsx_Js_Model, "Rsx_Js_Model", null],
|
|
[Rsx_View_Transitions, "Rsx_View_Transitions", null],
|
|
[ReadWriteLock, "ReadWriteLock", null],
|
|
[Form_Utils, "Form_Utils", null],
|
|
[Debugger, "Debugger", null],
|
|
[Rsx_Jq_Helpers, "Rsx_Jq_Helpers", null],
|
|
[Rsx, "Rsx", null],
|
|
[Ajax, "Ajax", null],
|
|
[Component, "Component", _Base_Jqhtml_Component],
|
|
[Jqhtml_Integration, "Jqhtml_Integration", null],
|
|
[Test_Modal_Form, "Test_Modal_Form", Component],
|
|
[Dev_Modals, "Dev_Modals", null],
|
|
[Dev_Attachments, "Dev_Attachments", null],
|
|
[Dev_Index, "Dev_Index", null],
|
|
[DataGrid_Abstract, "DataGrid_Abstract", Component],
|
|
[Activity_Feed, "Activity_Feed", Component],
|
|
[Actor_Reference, "Actor_Reference", Component],
|
|
[Advanced_Search_Panel, "Advanced_Search_Panel", Component],
|
|
[Alert_Banner, "Alert_Banner", Component],
|
|
[Avatar, "Avatar", Component],
|
|
[Blockquote, "Blockquote", Component],
|
|
[Breadcrumbs, "Breadcrumbs", Component],
|
|
[Bulk_Action_Bar, "Bulk_Action_Bar", Component],
|
|
[Bulk_Selection, "Bulk_Selection", Component],
|
|
[Button_Group, "Button_Group", Component],
|
|
[Button_Primary, "Button_Primary", Component],
|
|
[Button_Secondary, "Button_Secondary", Component],
|
|
[Button, "Button", Component],
|
|
[Calendar_Event, "Calendar_Event", Component],
|
|
[Calendar_Grid, "Calendar_Grid", Component],
|
|
[Card, "Card", Component],
|
|
[Chart_Component, "Chart_Component", Component],
|
|
[Checkbox, "Checkbox", Component],
|
|
[Code_Block, "Code_Block", Component],
|
|
[Column_Visibility_Toggle, "Column_Visibility_Toggle", Component],
|
|
[Comment_Thread, "Comment_Thread", Component],
|
|
[Date_Picker, "Date_Picker", Component],
|
|
[Dropdown_Menu, "Dropdown_Menu", Component],
|
|
[Empty_State, "Empty_State", Component],
|
|
[Export_Button, "Export_Button", Component],
|
|
[File_Upload, "File_Upload", Component],
|
|
[Filter_Bar, "Filter_Bar", Component],
|
|
[Form_Actions_Component, "Form_Actions_Component", Component],
|
|
[Form_Field_Group, "Form_Field_Group", Component],
|
|
[Form_Group_Component, "Form_Group_Component", Component],
|
|
[Form_Row_Component, "Form_Row_Component", Component],
|
|
[Form_Validation_Message, "Form_Validation_Message", Component],
|
|
[Gantt_Chart, "Gantt_Chart", Component],
|
|
[Icon_Button, "Icon_Button", Component],
|
|
[Icon_With_Label, "Icon_With_Label", Component],
|
|
[Icon_With_Text, "Icon_With_Text", Component],
|
|
[Icon, "Icon", Component],
|
|
[Info_Box, "Info_Box", Component],
|
|
[Inline_Edit_Field, "Inline_Edit_Field", Component],
|
|
[Input_With_Icon, "Input_With_Icon", Component],
|
|
[Input_With_Validation, "Input_With_Validation", Component],
|
|
[Input, "Input", Component],
|
|
[Kanban_Board, "Kanban_Board", Component],
|
|
[Link, "Link", Component],
|
|
[List, "List", Component],
|
|
[Loading_Skeleton, "Loading_Skeleton", Component],
|
|
[Metric_Card, "Metric_Card", Component],
|
|
[Mobile_Header, "Mobile_Header", Component],
|
|
[Modal_Dialog, "Modal_Dialog", Component],
|
|
[Multi_Select, "Multi_Select", Component],
|
|
[Notification_Badge, "Notification_Badge", Component],
|
|
[Notification_Dropdown, "Notification_Dropdown", Component],
|
|
[Overdue_Indicator, "Overdue_Indicator", Component],
|
|
[Page_Header, "Page_Header", Component],
|
|
[Page_Section, "Page_Section", Component],
|
|
[Page, "Page", Component],
|
|
[Popover, "Popover", Component],
|
|
[Progress_Bar, "Progress_Bar", Component],
|
|
[Radio_Button, "Radio_Button", Component],
|
|
[Rich_Text_Editor, "Rich_Text_Editor", Component],
|
|
[Row_Action_Menu, "Row_Action_Menu", Component],
|
|
[Sample_Datagrid_Component, "Sample_Datagrid_Component", Component],
|
|
[Search_Bar, "Search_Bar", Component],
|
|
[Searchable_Select, "Searchable_Select", Component],
|
|
[Select_Dropdown, "Select_Dropdown", Component],
|
|
[Sidebar_Nav, "Sidebar_Nav", Component],
|
|
[Sortable_Column_Header, "Sortable_Column_Header", Component],
|
|
[Spinner, "Spinner", Component],
|
|
[Stat_Card, "Stat_Card", Component],
|
|
[Status_Badge, "Status_Badge", Component],
|
|
[Tab_Content, "Tab_Content", Component],
|
|
[Table_Pagination, "Table_Pagination", Component],
|
|
[Table, "Table", Component],
|
|
[Tabs, "Tabs", Component],
|
|
[Tag_Group, "Tag_Group", Component],
|
|
[Tag, "Tag", Component],
|
|
[Text_Display, "Text_Display", Component],
|
|
[Textarea, "Textarea", Component],
|
|
[Three_Column_Layout, "Three_Column_Layout", Component],
|
|
[Time_Picker, "Time_Picker", Component],
|
|
[Timeline, "Timeline", Component],
|
|
[Timestamp_Display, "Timestamp_Display", Component],
|
|
[Tooltip, "Tooltip", Component],
|
|
[Top_Nav, "Top_Nav", Component],
|
|
[Trend_Indicator, "Trend_Indicator", Component],
|
|
[Two_Column_Layout, "Two_Column_Layout", Component],
|
|
[User_Avatar_Dropdown, "User_Avatar_Dropdown", Component],
|
|
[Modal_Abstract, "Modal_Abstract", null],
|
|
[Rsx_Modal, "Rsx_Modal", Component],
|
|
[Modal, "Modal", null],
|
|
[Breadcrumb_Item, "Breadcrumb_Item", Component],
|
|
[Client_Label_Link, "Client_Label_Link", Component],
|
|
[Client_Label, "Client_Label", Component],
|
|
[Form_Input_Abstract, "Form_Input_Abstract", Component],
|
|
[Text_Input, "Text_Input", Form_Input_Abstract],
|
|
[Checkbox_Input, "Checkbox_Input", Form_Input_Abstract],
|
|
[Wysiwyg_Input, "Wysiwyg_Input", Form_Input_Abstract],
|
|
[Select_Input, "Select_Input", Form_Input_Abstract],
|
|
[Ajax_Select_Input, "Ajax_Select_Input", Select_Input],
|
|
[Currency_Input, "Currency_Input", Text_Input],
|
|
[Phone_Text_Input, "Phone_Text_Input", Text_Input],
|
|
[State_Select_Input, "State_Select_Input", Ajax_Select_Input],
|
|
[Country_Select_Input, "Country_Select_Input", Ajax_Select_Input],
|
|
[Profile_Photo_Input, "Profile_Photo_Input", Form_Input_Abstract],
|
|
[Rsx_Tabs, "Rsx_Tabs", Component],
|
|
[Rsx_Tab, "Rsx_Tab", Component],
|
|
[Rsx_Form, "Rsx_Form", Component],
|
|
[Pin_Verification_Form, "Pin_Verification_Form", Rsx_Form],
|
|
[Form_Field_Abstract, "Form_Field_Abstract", Component],
|
|
[Form_Field, "Form_Field", Form_Field_Abstract],
|
|
[Form_Hidden_Field, "Form_Hidden_Field", Form_Field_Abstract]
|
|
]);
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Dev_Bundle_636dc9a3.js === */
|
|
// RSX Route Definitions - Generated by BundleCompiler
|
|
// Provides route patterns for type-safe URL generation
|
|
Rsx._define_routes({
|
|
"Dev_Index_Controller": {
|
|
"index": "/dev"
|
|
},
|
|
"Dev_Modals_Controller": {
|
|
"index": "/dev/modals"
|
|
},
|
|
"Dev_Attachments_Controller": {
|
|
"index": "/dev/attachments"
|
|
}
|
|
});
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Dev_Bundle_e83e43d3.js === */
|
|
$(document).ready(async function() {
|
|
try {
|
|
console_debug('RSX_INIT', 'Document ready, starting Rsx._rsx_core_boot');
|
|
await Rsx._rsx_core_boot();
|
|
console_debug('RSX_INIT', 'Initialization complete');
|
|
} catch (error) {
|
|
console.error('[RSX_INIT] Initialization failed:', error);
|
|
console.error('[RSX_INIT] Stack:', error.stack);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfY29uZmlnX0Rldl9CdW5kbGUuanMiLCJzdG9yYWdlL3JzeC10bXAvbnBtX2ltcG9ydF9kZWNsYXJhdGlvbnNfOTVhNmY2MDJjOTgwMzc2MTFiNjQwYjBiNTM0MjgzMGIuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvZGVjb3JhdG9yLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL2Jyb3dzZXIuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvZGF0ZXRpbWUuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvZXJyb3IuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvaGFzaC5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9NdXRleC5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9hc3luYy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9mdW5jdGlvbnMuanMiLCJyc3gvdGhlbWUvcXVpbGwvcXVpbGxfY2RuLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL01hbmlmZXN0LmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9CZWhhdmlvcnMuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0NhY2hlLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9Jbml0LmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9Kc19Nb2RlbC5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfVmlld19UcmFuc2l0aW9ucy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9SZWFkV3JpdGVMb2NrLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL0Zvcm1fVXRpbHMuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvRGVidWdnZXIuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0pxX0hlbHBlcnMuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4LmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL0FqYXguanMiLCJhcHAvUlNwYWRlL0ludGVncmF0aW9ucy9KcWh0bWwvSnFodG1sX0NvbXBvbmVudC5qcyIsImFwcC9SU3BhZGUvSW50ZWdyYXRpb25zL0pxaHRtbC9KcWh0bWxfSW50ZWdyYXRpb24uanMiLCJyc3gvYXBwL2Rldi9tb2RhbHMvdGVzdF9tb2RhbF9mb3JtLmpzIiwicnN4L2FwcC9kZXYvbW9kYWxzL2Rldl9tb2RhbHMuanMiLCJyc3gvYXBwL2Rldi9hdHRhY2htZW50cy9kZXZfYXR0YWNobWVudHMuanMiLCJyc3gvYXBwL2Rldi9kZXZfaW5kZXguanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9kYXRhZ3JpZC9kYXRhZ3JpZF9hYnN0cmFjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FjdGl2aXR5X0ZlZWQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9BY3Rvcl9SZWZlcmVuY2UuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9BZHZhbmNlZF9TZWFyY2hfUGFuZWwuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9BbGVydF9CYW5uZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9BdmF0YXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9CbG9ja3F1b3RlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQnJlYWRjcnVtYnMuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9CdWxrX0FjdGlvbl9CYXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9CdWxrX1NlbGVjdGlvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2J1dHRvbl9ncm91cC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2J1dHRvbl9wcmltYXJ5LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uX3NlY29uZGFyeS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NhbGVuZGFyX0V2ZW50LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ2FsZW5kYXJfR3JpZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NhcmQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9DaGFydF9Db21wb25lbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9DaGVja2JveC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NvZGVfQmxvY2suanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Db2x1bW5fVmlzaWJpbGl0eV9Ub2dnbGUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Db21tZW50X1RocmVhZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0RhdGVfUGlja2VyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRHJvcGRvd25fTWVudS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0VtcHR5X1N0YXRlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRXhwb3J0X0J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0ZpbGVfVXBsb2FkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRmlsdGVyX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2Zvcm1fYWN0aW9uc19jb21wb25lbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Gb3JtX0ZpZWxkX0dyb3VwLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvZm9ybV9ncm91cF9jb21wb25lbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9mb3JtX3Jvd19jb21wb25lbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Gb3JtX1ZhbGlkYXRpb25fTWVzc2FnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0dhbnR0X0NoYXJ0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvaWNvbl9idXR0b24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JY29uX1dpdGhfTGFiZWwuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JY29uX1dpdGhfVGV4dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2ljb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbmZvX0JveC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0lubGluZV9FZGl0X0ZpZWxkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvSW5wdXRfV2l0aF9JY29uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvSW5wdXRfV2l0aF9WYWxpZGF0aW9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvSW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9LYW5iYW5fQm9hcmQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9saW5rLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvTGlzdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0xvYWRpbmdfU2tlbGV0b24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9NZXRyaWNfQ2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL01vYmlsZV9IZWFkZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Nb2RhbF9EaWFsb2cuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9NdWx0aV9TZWxlY3QuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ob3RpZmljYXRpb25fQmFkZ2UuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ob3RpZmljYXRpb25fRHJvcGRvd24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9PdmVyZHVlX0luZGljYXRvci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1BhZ2VfSGVhZGVyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvcGFnZV9zZWN0aW9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvcGFnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1BvcG92ZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Qcm9ncmVzc19CYXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9SYWRpb19CdXR0b24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9SaWNoX1RleHRfRWRpdG9yLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvUm93X0FjdGlvbl9NZW51LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2FtcGxlX0RhdGFncmlkX0NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NlYXJjaF9CYXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9TZWFyY2hhYmxlX1NlbGVjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NlbGVjdF9Ecm9wZG93bi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NpZGViYXJfTmF2LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU29ydGFibGVfQ29sdW1uX0hlYWRlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NwaW5uZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9TdGF0X0NhcmQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9TdGF0dXNfQmFkZ2UuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UYWJfQ29udGVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYmxlX1BhZ2luYXRpb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UYWJsZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYnMuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UYWdfR3JvdXAuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UYWcuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC90ZXh0X2Rpc3BsYXkuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UZXh0YXJlYS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RocmVlX0NvbHVtbl9MYXlvdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UaW1lX1BpY2tlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RpbWVsaW5lLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGltZXN0YW1wX0Rpc3BsYXkuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ub29sdGlwLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVG9wX05hdi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RyZW5kX0luZGljYXRvci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1R3b19Db2x1bW5fTGF5b3V0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVXNlcl9BdmF0YXJfRHJvcGRvd24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9tb2RhbC9tb2RhbF9hYnN0cmFjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL21vZGFsL3JzeF9tb2RhbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL21vZGFsL01vZGFsLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvcGFnZV9lbGVtZW50cy9icmVhZGNydW1iX2l0ZW0uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9wYWdlX2VsZW1lbnRzL2NsaWVudF9sYWJlbF9saW5rLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvcGFnZV9lbGVtZW50cy9jbGllbnRfbGFiZWwuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvZm9ybV9pbnB1dF9hYnN0cmFjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy90ZXh0X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL2NoZWNrYm94X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL3d5c2l3eWdfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvc2VsZWN0X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL2FqYXhfc2VsZWN0X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL2N1cnJlbmN5X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL3Bob25lX3RleHRfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvc3RhdGVfc2VsZWN0X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL2NvdW50cnlfc2VsZWN0X2lucHV0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL3Byb2ZpbGVfcGhvdG9faW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9yc3hfdGFicy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF90YWIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9yc3hfZm9ybS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3Bpbl92ZXJpZmljYXRpb25fZm9ybS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL2Zvcm1fZmllbGRfYWJzdHJhY3QuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9mb3JtX2ZpZWxkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvZm9ybV9oaWRkZW5fZmllbGQuanMiLCJ0ZXN0X21vZGFsX2Zvcm0uanFodG1sIiwiZGF0YWdyaWRfYWJzdHJhY3QuanFodG1sIiwiYWN0aW9uX2J1dHRvbl9kZWxldGUuanFodG1sIiwiYWN0aW9uX2J1dHRvbl9lZGl0LmpxaHRtbCIsImFjdGlvbl9idXR0b25fdmlldy5qcWh0bWwiLCJhY3Rpdml0eV9mZWVkLmpxaHRtbCIsImFjdG9yX3JlZmVyZW5jZS5qcWh0bWwiLCJhZHZhbmNlZF9zZWFyY2hfcGFuZWwuanFodG1sIiwiYWxlcnRfYmFubmVyLmpxaHRtbCIsImF2YXRhci5qcWh0bWwiLCJibG9ja3F1b3RlLmpxaHRtbCIsImJyZWFkY3J1bWJzLmpxaHRtbCIsImJ1bGtfYWN0aW9uX2Jhci5qcWh0bWwiLCJidWxrX3NlbGVjdGlvbi5qcWh0bWwiLCJidXR0b25fZ3JvdXAuanFodG1sIiwiYnV0dG9uX3ByaW1hcnkuanFodG1sIiwiYnV0dG9uX3NlY29uZGFyeS5qcWh0bWwiLCJidXR0b24uanFodG1sIiwiY2FsZW5kYXJfZXZlbnQuanFodG1sIiwiY2FsZW5kYXJfZ3JpZC5qcWh0bWwiLCJjYXJkX2Zvb3Rlci5qcWh0bWwiLCJjYXJkX2hlYWRlci5qcWh0bWwiLCJjYXJkX3RpdGxlLmpxaHRtbCIsImNhcmQuanFodG1sIiwiY2hhcnRfY29tcG9uZW50LmpxaHRtbCIsImNoZWNrYm94LmpxaHRtbCIsImNvZGVfYmxvY2suanFodG1sIiwiY29sdW1uX3Zpc2liaWxpdHlfdG9nZ2xlLmpxaHRtbCIsImNvbW1lbnRfdGhyZWFkLmpxaHRtbCIsImNvbnRhY3RfYWN0aW9ucy5qcWh0bWwiLCJjb250YWN0X3Jvdy5qcWh0bWwiLCJjb250YWN0c19kYXRhX3RhYmxlLmpxaHRtbCIsImNvbnRhY3RzX2xpc3RfY2FyZC5qcWh0bWwiLCJkYXRlX3BpY2tlci5qcWh0bWwiLCJkcm9wZG93bl9tZW51LmpxaHRtbCIsImVtcHR5X3N0YXRlLmpxaHRtbCIsImV4cG9ydF9idXR0b24uanFodG1sIiwiZmlsZV91cGxvYWQuanFodG1sIiwiZmlsdGVyX2Jhci5qcWh0bWwiLCJmb3JtX2FjdGlvbnNfY29tcG9uZW50LmpxaHRtbCIsImZvcm1fZmllbGRfZ3JvdXAuanFodG1sIiwiZm9ybV9ncm91cF9jb21wb25lbnQuanFodG1sIiwiZm9ybV9yb3dfY29tcG9uZW50LmpxaHRtbCIsImZvcm1fdmFsaWRhdGlvbl9tZXNzYWdlLmpxaHRtbCIsImdhbnR0X2NoYXJ0LmpxaHRtbCIsImljb25fYnV0dG9uLmpxaHRtbCIsImljb25fd2l0aF9sYWJlbC5qcWh0bWwiLCJpY29uX3dpdGhfdGV4dC5qcWh0bWwiLCJpY29uLmpxaHRtbCIsImluZm9fYm94LmpxaHRtbCIsImlubGluZV9lZGl0X2ZpZWxkLmpxaHRtbCIsImlucHV0X3dpdGhfaWNvbi5qcWh0bWwiLCJpbnB1dF93aXRoX3ZhbGlkYXRpb24uanFodG1sIiwiaW5wdXQuanFodG1sIiwia2FuYmFuX2JvYXJkLmpxaHRtbCIsImxpbmsuanFodG1sIiwibGlzdC5qcWh0bWwiLCJsb2FkaW5nX3NrZWxldG9uLmpxaHRtbCIsIm1ldHJpY19jYXJkLmpxaHRtbCIsIm1vYmlsZV9oZWFkZXIuanFodG1sIiwibW9kYWxfZGlhbG9nLmpxaHRtbCIsIm11bHRpX3NlbGVjdC5qcWh0bWwiLCJub3RpZmljYXRpb25fYmFkZ2UuanFodG1sIiwibm90aWZpY2F0aW9uX2Ryb3Bkb3duLmpxaHRtbCIsIm92ZXJkdWVfaW5kaWNhdG9yLmpxaHRtbCIsInBhZ2VfaGVhZGVyX2xlZnQuanFodG1sIiwicGFnZV9oZWFkZXJfcmlnaHQuanFodG1sIiwicGFnZV9oZWFkZXIuanFodG1sIiwicGFnZV9zZWN0aW9uLmpxaHRtbCIsInBhZ2Vfc3VidGl0bGUuanFodG1sIiwicGFnZV90aXRsZS5qcWh0bWwiLCJwYWdlLmpxaHRtbCIsInBhZ2luYXRpb25fY29udHJvbHMuanFodG1sIiwicGFnaW5hdGlvbl9pbmZvLmpxaHRtbCIsInBvcG92ZXIuanFodG1sIiwicHJvZ3Jlc3NfYmFyLmpxaHRtbCIsInJhZGlvX2J1dHRvbi5qcWh0bWwiLCJyZWNvcmRfY291bnRfZGlzcGxheS5qcWh0bWwiLCJyaWNoX3RleHRfZWRpdG9yLmpxaHRtbCIsInJvd19hY3Rpb25fbWVudS5qcWh0bWwiLCJTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LmpxaHRtbCIsInNlYXJjaF9iYXIuanFodG1sIiwic2VhcmNoX2J1dHRvbi5qcWh0bWwiLCJzZWFyY2hfaW5wdXQuanFodG1sIiwic2VhcmNoYWJsZV9zZWxlY3QuanFodG1sIiwic2VsZWN0X2Ryb3Bkb3duLmpxaHRtbCIsInNpZGViYXJfbmF2LmpxaHRtbCIsInNpbXBsZV90YWJsZV90ZXN0LmpxaHRtbCIsInNvcnRhYmxlX2NvbHVtbl9oZWFkZXIuanFodG1sIiwic3Bpbm5lci5qcWh0bWwiLCJzdGF0X2NhcmQuanFodG1sIiwic3RhdHVzX2JhZGdlLmpxaHRtbCIsInRhYl9jb250ZW50LmpxaHRtbCIsInRhYmxlX2JvZHkuanFodG1sIiwidGFibGVfaGVhZGVycy5qcWh0bWwiLCJ0YWJsZV9wYWdpbmF0aW9uLmpxaHRtbCIsInRhYmxlLmpxaHRtbCIsInRhYnMuanFodG1sIiwidGFnX2dyb3VwLmpxaHRtbCIsInRhZy5qcWh0bWwiLCJ0ZXh0X2Rpc3BsYXkuanFodG1sIiwidGV4dGFyZWEuanFodG1sIiwidGhyZWVfY29sdW1uX2xheW91dC5qcWh0bWwiLCJ0aW1lX3BpY2tlci5qcWh0bWwiLCJ0aW1lbGluZS5qcWh0bWwiLCJ0aW1lc3RhbXBfZGlzcGxheS5qcWh0bWwiLCJ0b29sdGlwLmpxaHRtbCIsInRvcF9uYXYuanFodG1sIiwidHJlbmRfaW5kaWNhdG9yLmpxaHRtbCIsInR3b19jb2x1bW5fbGF5b3V0LmpxaHRtbCIsInVzZXJfYXZhdGFyX2Ryb3Bkb3duLmpxaHRtbCIsInVzZXJzX2RhdGFfdGFibGUuanFodG1sIiwicnN4X21vZGFsLmpxaHRtbCIsImJyZWFkY3J1bWIuanFodG1sIiwiYnJlYWRjcnVtYl9pdGVtLmpxaHRtbCIsImNsaWVudF9sYWJlbC5qcWh0bWwiLCJjbGllbnRfbGFiZWxfbGluay5qcWh0bWwiLCJ0ZXh0X2lucHV0LmpxaHRtbCIsInNlbGVjdF9pbnB1dC5qcWh0bWwiLCJhamF4X3NlbGVjdF9pbnB1dC5qcWh0bWwiLCJjaGVja2JveF9pbnB1dC5qcWh0bWwiLCJ3eXNpd3lnX2lucHV0LmpxaHRtbCIsImNvdW50cnlfc2VsZWN0X2lucHV0LmpxaHRtbCIsInN0YXRlX3NlbGVjdF9pbnB1dC5qcWh0bWwiLCJwcm9maWxlX3Bob3RvX2lucHV0LmpxaHRtbCIsInJzeF90YWJzLmpxaHRtbCIsInJzeF90YWIuanFodG1sIiwicnN4X2Zvcm0uanFodG1sIiwiZm9ybV9maWVsZF9hYnN0cmFjdC5qcWh0bWwiLCJmb3JtX2ZpZWxkLmpxaHRtbCIsImZvcm1faGlkZGVuX2ZpZWxkLmpxaHRtbCIsInBpbl92ZXJpZmljYXRpb25fZm9ybS5qcWh0bWwiLCJzdG9yYWdlL3JzeC10bXAvYnVuZGxlX0Rldl9CdW5kbGVfZjJkMDg3ZjQuanMiLCJzdG9yYWdlL3JzeC10bXAvYnVuZGxlX0Rldl9CdW5kbGVfNjM2ZGM5YTMuanMiLCJzdG9yYWdlL3JzeC10bXAvYnVuZGxlX0Rldl9CdW5kbGVfZTgzZTQzZDMuanMiXSwibmFtZXMiOlsiZGVjb3JhdG9yIiwidmFsdWUiLCJpc19tb2JpbGUiLCJ0ZXN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiJCIsIndpbmRvdyIsIndpZHRoIiwiaXNfZGVza3RvcCIsImdldF9vcyIsInVzZXJfYWdlbnQiLCJwbGF0Zm9ybSIsIm1hY29zX3BsYXRmb3JtcyIsIndpbmRvd3NfcGxhdGZvcm1zIiwiaW9zX3BsYXRmb3JtcyIsIm9zIiwiaXNfbW9iaWxlX2RldmljZSIsImluZGV4T2YiLCJpc19jcmF3bGVyIiwiYm90X3BhdHRlcm4iLCJzY3JvbGxfaW50b192aWV3X2lmX25lZWRlZCIsInRhcmdldCIsIiR0YXJnZXQiLCIkcGFyZW50IiwicGFyZW50IiwidGFyZ2V0X3RvcCIsInBvc2l0aW9uIiwidG9wIiwic2Nyb2xsVG9wIiwidGFyZ2V0X2hlaWdodCIsIm91dGVySGVpZ2h0IiwicGFyZW50X2hlaWdodCIsImhlaWdodCIsInNjcm9sbF9wb3NpdGlvbiIsIkRlYnVnZ2VyIiwiY29uc29sZV9kZWJ1ZyIsIm5ld19zY3JvbGxfcG9zaXRpb24iLCJNYXRoIiwibWF4IiwibWluIiwic2Nyb2xsSGVpZ2h0Iiwic2Nyb2xsX3BhZ2VfaW50b192aWV3X2lmX25lZWRlZCIsIm9mZnNldCIsIndpbmRvd19oZWlnaHQiLCJ3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uIiwiYW5pbWF0ZSIsIndhaXRfZm9yX2ltYWdlcyIsImNhbGxiYWNrIiwiJGltYWdlcyIsInRvdGFsX2ltYWdlcyIsImxlbmd0aCIsImltYWdlc19sb2FkZWQiLCJlYWNoIiwiaW1nIiwiSW1hZ2UiLCJvbmxvYWQiLCJvbmVycm9yIiwic3JjIiwiJG5ic3AiLCJlc2NhcGVfanFfc2VsZWN0b3IiLCJpZCIsInJlcGxhY2UiLCJ1bml4X3RpbWUiLCJyb3VuZCIsIkRhdGUiLCJnZXRUaW1lIiwieW1kaGlzX3RvX3VuaXgiLCJzdHJfZGF0ZSIsImRhdGUiLCJlcnJvciIsInN0ciIsImVycm9yX2NvZGUiLCJ1bmRlZiIsInN0YXR1cyIsInNob3VsZG50X2hhcHBlbiIsIm1lc3NhZ2UiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJFcnJvciIsInN0YWNrIiwic3RhY2tMaW5lcyIsInNwbGl0IiwiY2FsbGVySW5mbyIsImNhbGxlckxpbmUiLCJtYXRjaCIsImVycm9yTWVzc2FnZSIsImNvbnNvbGUiLCJyZXBlYXQiLCJmYXRhbEVycm9yIiwibmFtZSIsImhhc2giLCJ0aGVfdmFyIiwiY2FsY19zaGExIiwiaWdub3JlZF9rZXlzIiwianNvbl9zdHJpbmdpZnlfbm9jaXJjIiwiY2FjaGUiLCJKU09OIiwic3RyaW5naWZ5Iiwia2V5IiwidiIsIl9jYWNoZV9rZXkiLCJfaGFzaF9rZXkiLCJwdXNoIiwiZmxhdF92YXIiLCJfZmxhdHRlbiIsInByZWZpeCIsImRlcHRoIiwiaXNfb2JqZWN0IiwiQWJzdHJhY3QiLCJrIiwiaGFzT3duUHJvcGVydHkiLCJpc19hcnJheSIsImkiLCJmb3JlYWNoIiwiaXNfZnVuY3Rpb24iLCJpc19udW1lcmljIiwiU3RyaW5nIiwic29ydGVyIiwic29ydCIsImEiLCJiIiwianNvbiIsImhhc2hlZCIsInNoYTEiLCJkZWVwX2VxdWFsIiwibXV0ZXgiLCJnbG9iYWxfaWQiLCJpbnN0YW5jZV9tdXRleGVzIiwiX2luc3RhbmNlX3N0b3JhZ2UiLCJXZWFrTWFwIiwiZ2xvYmFsX211dGV4ZXMiLCJfZ2xvYmFsX3N0b3JhZ2UiLCJNYXAiLCJnZXRfaW5zdGFuY2VfbXV0ZXgiLCJpbnN0YW5jZSIsIm1ldGhvZF9uYW1lIiwiaW5zdGFuY2VfbG9ja3MiLCJnZXQiLCJzZXQiLCJsb2NrX3N0YXRlIiwiYWN0aXZlIiwicXVldWUiLCJnZXRfZ2xvYmFsX211dGV4Iiwic2NoZWR1bGVfbmV4dCIsImZuIiwicmVzb2x2ZSIsInJlamVjdCIsInNoaWZ0IiwiUHJvbWlzZSIsInRoZW4iLCJmaW5hbGx5IiwiYWNxdWlyZV9sb2NrIiwiZGVzY3JpcHRvciIsIm9yaWdpbmFsX21ldGhvZCIsIl9sZW4iLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiYXBwbHkiLCJfbGVuMiIsIl9rZXkyIiwic2xlZXAiLCJtaWxsaXNlY29uZHMiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJzZXRUaW1lb3V0IiwiZGVib3VuY2UiLCJjYWxsYmFja19vcl9kZWxheSIsImRlbGF5IiwiaW1tZWRpYXRlIiwiZGVjb3JhdG9yX2RlbGF5IiwiZGVjb3JhdG9yX2ltbWVkaWF0ZSIsImNvbnRleHQiLCJraW5kIiwiZGVib3VuY2VfaW1wbCIsInJ1bm5pbmciLCJxdWV1ZWQiLCJsYXN0X2VuZF90aW1lIiwidGltZXIiLCJuZXh0X2FyZ3MiLCJuZXh0X2NvbnRleHQiLCJyZXNvbHZlX3F1ZXVlIiwicmVqZWN0X3F1ZXVlIiwicnVuX2Z1bmN0aW9uIiwidGhlc2VfcmVzb2x2ZXMiLCJ0aGVzZV9yZWplY3RzIiwicmVzdWx0IiwiZXJyIiwibm93IiwiY2xlYXJUaW1lb3V0IiwiZmlyc3RfY2FsbCIsInNpbmNlIiwiSW5maW5pdHkiLCJ3YWl0Iiwicndsb2NrIiwiY2IiLCJSZWFkV3JpdGVMb2NrIiwiYWNxdWlyZSIsInJ3bG9ja19yZWFkIiwiYWNxdWlyZV9yZWFkIiwicndsb2NrX2ZvcmNlX3VubG9jayIsImZvcmNlX3VubG9jayIsInJ3bG9ja19wZW5kaW5nIiwicGVuZGluZyIsIm9iaiIsInJlc3VsdHMiLCJpc0FycmF5IiwiZm9yRWFjaCIsImluZGV4IiwicHJvbWlzZXMiLCJmaWx0ZXIiLCJhbGwiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJpc19zdHJpbmciLCJzIiwiaXNfaW50ZWdlciIsIk51bWJlciIsImlzSW50ZWdlciIsImlzX3Byb21pc2UiLCJmdW5jdGlvbl90b19jaGVjayIsInRvU3RyaW5nIiwiY2FsbCIsImlzX2VtYWlsIiwiZW1haWwiLCJyZWdleCIsImlzc2V0IiwiZW1wdHkiLCJvYmplY3QiLCJmbG9hdCIsInZhbCIsInBhcnNlZCIsImludCIsInBhcnNlSW50IiwidmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSIsImh0bWwiLCJfIiwiZXNjYXBlIiwibmwyYnIiLCJodG1sYnIiLCJ1cmxlbmNvZGUiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ1cmxkZWNvZGUiLCJkZWNvZGVVUklDb21wb25lbnQiLCJqc29uX2VuY29kZSIsImpzb25fZGVjb2RlIiwicGFyc2UiLCJjaGFubmVsIiwidmFsdWVzIiwicmVwbGFjZV9hbGwiLCJzdHJpbmciLCJzZWFyY2giLCJqb2luIiwidWN3b3JkcyIsImlucHV0IiwibWFwIiwid29yZCIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJjb3VudCIsIm8iLCJjIiwiY2xvbmUiLCJGdW5jdGlvbiIsInByb3RvdHlwZSIsIl9fY2xvbmUiLCJ0aGF0IiwidGVtcCIsImNsb25lZCIsImNvbnN0cnVjdG9yIiwiT2JqZWN0IiwiYXNzaWduIiwiY29hbGVzY2UiLCJmcm9tIiwicmV0dXJuX3ZhbCIsImFyZyIsImNzdl90b19hcnJheV90cmltIiwic3RyX2NzdiIsInBhcnRzIiwicmV0IiwicGFydCIsInRyaW0iLCJxdWlsbF9yZWFkeSIsIlF1aWxsIiwiTWFuaWZlc3QiLCJfZGVmaW5lIiwiaXRlbXMiLCJfY2xhc3NlcyIsIml0ZW0iLCJjbGFzc19vYmplY3QiLCJjbGFzc19uYW1lIiwiY2xhc3NfZXh0ZW5kcyIsImRlY29yYXRvcnMiLCJjbGFzcyIsImV4dGVuZHMiLCJfbmFtZSIsIl9leHRlbmRzIiwiX2RlY29yYXRvcnMiLCJfYnVpbGRfc3ViY2xhc3NfaW5kZXgiLCJfc3ViY2xhc3NfaW5kZXgiLCJjbGFzc2RhdGEiLCJjdXJyZW50X2NsYXNzX25hbWUiLCJjdXJyZW50X2NsYXNzZGF0YSIsImV4dGVuZHNfbmFtZSIsImluY2x1ZGVzIiwiZ2V0X2V4dGVuZGluZyIsImJhc2VfY2xhc3MiLCJiYXNlX2NsYXNzX29iamVjdCIsImdldF9jbGFzc19ieV9uYW1lIiwiY2xhc3NlcyIsImpzX2lzX3N1YmNsYXNzX29mIiwibG9jYWxlQ29tcGFyZSIsInN1YmNsYXNzIiwic3VwZXJjbGFzcyIsInN1YmNsYXNzX29iamVjdCIsInN1cGVyY2xhc3Nfb2JqZWN0IiwiY3VycmVudF9jbGFzcyIsImdldF9hbGxfY2xhc3NlcyIsImJ1aWxkX2tleSIsInJzeGFwcCIsImdldF9kZWNvcmF0b3JzIiwiY2xhc3NfaW5mbyIsIl90cmFuc2Zvcm1fZGVjb3JhdG9ycyIsImdldF9hbGxfZGVjb3JhdG9ycyIsImNvbXBhY3RfZGVjb3JhdG9ycyIsImhhc19kZWNvcmF0b3IiLCJkZWNvcmF0b3JfbmFtZSIsInNvbWUiLCJkIiwianNfZ2V0X3N1YmNsYXNzZXNfb2YiLCJiYXNlX2NsYXNzX25hbWUiLCJzdWJjbGFzc19uYW1lcyIsInN1YmNsYXNzX29iamVjdHMiLCJzdWJjbGFzc19uYW1lIiwibmFtZV9hIiwibmFtZV9iIiwiUnN4X0JlaGF2aW9ycyIsIl9vbl9mcmFtZXdvcmtfY29yZV9pbml0IiwiX2luaXRfaWdub3JlX2ludmFsaWRfYW5jaG9yX2xpbmtzIiwiX3RyaW1fY29waWVkX3RleHQiLCJkb2N1bWVudCIsIm9uIiwiZSIsIiRsaW5rIiwiaHJlZiIsImF0dHIiLCJpc0RlZmF1bHRQcmV2ZW50ZWQiLCJkYXRhIiwicHJldmVudERlZmF1bHQiLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJzdGFydHNXaXRoIiwidGFyZ2V0SWQiLCJzdWJzdHJpbmciLCJ0YXJnZXRFeGlzdHMiLCJnZXRFbGVtZW50QnlJZCIsInF1ZXJ5U2VsZWN0b3IiLCJhZGRFdmVudExpc3RlbmVyIiwiZXZlbnQiLCJzaGlmdEtleSIsInNlbGVjdGlvbiIsImdldFNlbGVjdGlvbiIsInNlbGVjdGVkX3RleHQiLCJjb250YWluZXIiLCJnZXRSYW5nZUF0IiwiY29tbW9uQW5jZXN0b3JDb250YWluZXIiLCJub2RlVHlwZSIsInBhcmVudE5vZGUiLCJjbG9zZXN0IiwidHJpbW1lZF90ZXh0IiwiY2xpcGJvYXJkRGF0YSIsInNldERhdGEiLCJsb2ciLCJSc3hfQ2FjaGUiLCJvbl9jb3JlX2RlZmluZSIsIkNvcmVfQ2FjaGUiLCJfY2FjaGVzIiwiZ2xvYmFsIiwiX2NhY2hlc19zZXQiLCJnZXRfaW5zdGFuY2UiLCJNYWluIiwiZGVidWciLCJrZXlfZW5jb2RlZCIsIl9lbmNvZGVrZXkiLCJnZXRfZ2xvYmFsIiwiZ2V0X3Nlc3Npb24iLCJfc3VwcG9ydHNTdG9yYWdlIiwicnMiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzZXRfc2Vzc2lvbiIsIl90cnlhZ2FpbiIsInJlbW92ZUl0ZW0iLCJzZXRJdGVtIiwiX2lzT3V0T2ZTcGFjZSIsImNsZWFyIiwiX3Jlc2V0IiwiX19zdXBwb3J0c1N0b3JhZ2UiLCJleCIsIlJzeF9Jbml0IiwiUnN4IiwiaXNfcHJvZCIsIl9fZW52aXJvbm1lbnRfY2hlY2tzIiwic2NyaXB0cyIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwic2NyaXB0IiwiZGVmZXIiLCJyZWFzb24iLCJfcnN4X2NvcmVfYm9vdF9zdG9wIiwiUnN4X0pzX01vZGVsIiwiX19NT0RFTCIsIm1vZGVsRGF0YSIsImZldGNoIiwiQ3VycmVudENsYXNzIiwibW9kZWxOYW1lIiwicmVzcG9uc2UiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YVR5cGUiLCJfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSIsImdldE1vZGVsTmFtZSIsInJlZnJlc2giLCJmcmVzaCIsInRvT2JqZWN0IiwidG9KU09OIiwiTW9kZWxDbGFzcyIsIlJzeF9WaWV3X1RyYW5zaXRpb25zIiwic3RhcnRWaWV3VHJhbnNpdGlvbiIsIl9pbmplY3RfdHJhbnNpdGlvbl9jc3MiLCJzdHlsZSIsImNyZWF0ZUVsZW1lbnQiLCJ0ZXh0Q29udGVudCIsImhlYWQiLCJhcHBlbmRDaGlsZCIsIl81MGFlNjA5ZV9hc3NlcnRDbGFzc0JyYW5kIiwiXzUwYWU2MDllX2dldF9sb2NrIiwid3JpdGVyX3EiLCJfNTBhZTYwOWVfc2NoZWR1bGUiLCJ3cml0ZXJfYWN0aXZlIiwicmVhZGVyX3EiLCJyZWFkZXJzIiwiX2xvY2tzIiwiZGVsZXRlIiwiXzUwYWU2MDllX1JlYWRXcml0ZUxvY2siLCJiYXRjaCIsInNwbGljZSIsIkZvcm1fVXRpbHMiLCJfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lIiwicGFyYW1zIiwiYWpheF9zdWJtaXQiLCJvcHRpb25zIiwiJGVsZW1lbnQiLCJpcyIsImNvbnRyb2xsZXIiLCJhY3Rpb24iLCJBamF4IiwiYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24iLCJhcHBseV9mb3JtX2Vycm9ycyIsInBhcmVudF9zZWxlY3RvciIsImVycm9ycyIsInJlc2V0X2Zvcm1fZXJyb3JzIiwibm9ybWFsaXplZCIsIl9ub3JtYWxpemVfZXJyb3JzIiwiYW5pbWF0aW9ucyIsInR5cGUiLCJfYXBwbHlfZ2VuZXJhbF9lcnJvcnMiLCJkZWR1cGxpY2F0ZWQiLCJfZGVkdXBsaWNhdGVfZXJyb3JzIiwiX2FwcGx5X2ZpZWxkX2Vycm9ycyIsIm1hdGNoZWRfY291bnQiLCJrZXlzIiwidW5tYXRjaGVkIiwidW5tYXRjaGVkX2RlZHVwbGljYXRlZCIsInVubWF0Y2hlZF9jb3VudCIsInN1bW1hcnlfbXNnIiwic3VtbWFyeV9hbmltYXRpb25zIiwiX2FwcGx5X2NvbWJpbmVkX2Vycm9yIiwiJGVycm9yX2NvbnRhaW5lciIsImZpbmQiLCJmaXJzdCIsImNvbnRhaW5lcl90b3AiLCJmaXhlZF9oZWFkZXJfaGVpZ2h0IiwiX2dldF9maXhlZF9oZWFkZXJfaGVpZ2h0IiwidGFyZ2V0X3Njcm9sbCIsInJlc2V0IiwiZm9ybV9zZWxlY3RvciIsIiRmb3JtIiwidHJpZ2dlciIsInNlcmlhbGl6ZSIsInNlcmlhbGl6ZUFycmF5IiwiZm9ybV9kYXRhIiwib25fc3VjY2VzcyIsImRldGFpbHMiLCJvbl9lcnJvciIsInJlbW92ZSIsInJlbW92ZUNsYXNzIiwiZXZlcnkiLCJ1bndyYXBwZWQiLCJmaWVsZCIsIlNldCIsInNlZW4iLCJoYXMiLCJhZGQiLCJmaWVsZF9lcnJvcnMiLCJmaWVsZF9uYW1lIiwiZXJyb3JfbWVzc2FnZSIsIiRpbnB1dCIsIiRlcnJvciIsImFkZENsYXNzIiwiYXBwZW5kVG8iLCJoaWRlIiwiZmFkZUluIiwicHJvbWlzZSIsInVubWF0Y2hlZF9lcnJvcnMiLCIkYWxlcnQiLCJ0ZXh0IiwiJGxpc3QiLCJlcnJvcl9tc2ciLCJwcmVwZW5kVG8iLCJtZXNzYWdlcyIsIm1zZyIsImVycm9yX2xpc3QiLCJ0b3RhbF9oZWlnaHQiLCIkZWwiLCJjc3MiLCJvdXRlcldpZHRoIiwidmlld3BvcnRfd2lkdGgiLCJsb2dfYnJvd3Nlcl9lcnJvcnMiLCJfaGFuZGxlX2Jyb3dzZXJfZXJyb3IiLCJmaWxlbmFtZSIsImxpbmVubyIsImNvbG5vIiwib25fcmVmcmVzaCIsImVuYWJsZWQiLCJjb25maWciLCJmaWx0ZXJfbW9kZSIsInNwZWNpZmljIiwic3BlY2lmaWNfY2hhbm5lbCIsImNoYW5uZWxzIiwid2hpdGVsaXN0IiwiZmlsdGVyX2NoYW5uZWxzIiwiYmxhY2tsaXN0IiwidGltZXN0YW1wIiwidG9JU09TdHJpbmciLCJpbmNsdWRlX2xvY2F0aW9uIiwiaW5jbHVkZV9iYWNrdHJhY2UiLCJsb2NhdGlvbiIsImJhY2t0cmFjZSIsImxpbmUiLCJvdXRwdXRzIiwiYnJvd3NlciIsImluY2x1ZGVfYmVuY2htYXJrIiwiX2dldF90aW1lX3ByZWZpeCIsImNoYW5uZWxQcmVmaXgiLCJjb25zb2xlTWV0aG9kIiwibGFyYXZlbF9sb2ciLCJfYmF0Y2hfY29uc29sZV9tZXNzYWdlIiwibG9nX2Vycm9yIiwiZXJyb3JEYXRhIiwiX2Vycm9yX2NvdW50IiwiTUFYX0VSUk9SU19QRVJfUEFHRSIsIl9lcnJvcl9iYXRjaF9jb3VudCIsIk1BWF9FUlJPUl9CQVRDSEVTIiwiX2Vycm9yX2JhdGNoIiwiX2Vycm9yX3RpbWVyIiwiX2ZsdXNoX2Vycm9yX2JhdGNoIiwiREVCT1VOQ0VfTVMiLCJfY29uc29sZV9iYXRjaCIsIl9jb25zb2xlX3RpbWVyIiwiX2ZsdXNoX2NvbnNvbGVfYmF0Y2giLCJSb3V0ZSIsIl9zdGFydF90aW1lIiwiZWxhcHNlZCIsInRvRml4ZWQiLCJfMjdlMGU5ODZfZGVmaW5lUHJvcGVydHkiLCJSc3hfSnFfSGVscGVycyIsImV4aXN0cyIsImlzX3Zpc2libGUiLCJzY3JvbGxfdXBfdG8iLCJzcGVlZCIsImlzX2luX2RvbSIsImVfdG9wIiwic190b3AiLCJleHByIiwiZm9jdXMiLCJlbGVtIiwiYWN0aXZlRWxlbWVudCIsIl9jbGlja19uYXRpdmUiLCJjbGljayIsImhhbmRsZXIiLCJvcmlnaW5hbF9wcmV2ZW50RGVmYXVsdCIsImJpbmQiLCJ3YXJuIiwiY2xpY2tfYWxsb3dfZGVmYXVsdCIsIl9hbmNlc3RvciIsIkhUTUxvYmoiLCJwYXJlbnRFbGVtZW50IiwiZG9jdW1lbnRFbGVtZW50IiwiaXNfaW5fdmlld3BvcnQiLCJzY3JvbGx0b3AiLCJ0b3Bfb2ZfZWxlbWVudCIsImJvdHRvbV9vZl9lbGVtZW50IiwiYm90dG9tX29mX3NjcmVlbiIsImlubmVySGVpZ2h0IiwidG9wX29mX3NjcmVlbiIsInRhZ25hbWUiLCJwcm9wIiwidG9Mb3dlckNhc2UiLCJpc19leHRlcm5hbCIsImhvc3QiLCJsaW5rIiwiaG9zdG5hbWUiLCJjaGVja1ZhbGlkaXR5IiwicmVwb3J0VmFsaWRpdHkiLCJyZXF1ZXN0U3VibWl0IiwiY2xvc2VzdF9zaWJsaW5nIiwic2VsZWN0b3IiLCIkY3VycmVudCIsIiRmb3VuZCIsIm5hdGl2ZV9hamF4Iiwic2V0dGluZ3MiLCJyZXF1ZXN0X3VybCIsImlzX3JlbGF0aXZlIiwiaXNfc2FtZV9kb21haW4iLCJvcmlnaW4iLCJpc19sb2NhbF9yZXF1ZXN0IiwiX19sb2NhbF9pbnRlZ3JhdGlvbiIsImlzX2ZpbGVfdXBsb2FkIiwiZW5kc1dpdGgiLCJjb250cm9sbGVyX25hbWUiLCJhY3Rpb25fbmFtZSIsInVybF9tYXRjaCIsIl9pbml0X2V2ZW50cyIsIl9ldmVudF9oYW5kbGVycyIsIl90cmlnZ2VyZWRfZXZlbnRzIiwidHJpZ2dlcl9yZWZyZXNoIiwiQ29yZV9Mb2ciLCJpc19kZXYiLCJ1aWQiLCJfdWlkIiwiX2RlZmluZV9yb3V0ZXMiLCJyb3V0ZXMiLCJfcm91dGVzIiwicGFyYW1zX29iaiIsInBhdHRlcm4iLCJfZ2VuZXJhdGVfdXJsX2Zyb21fcGF0dGVybiIsInJlcXVpcmVkX3BhcmFtcyIsIm1hdGNoZXMiLCJtaXNzaW5nIiwicmVxdWlyZWQiLCJ1c2VkX3BhcmFtcyIsInBhcmFtX25hbWUiLCJlbmNvZGVkX3ZhbHVlIiwicXVlcnlfcGFyYW1zIiwicXVlcnlfc3RyaW5nIiwiZW50cmllcyIsIl9yZWYiLCJfcnN4X2NhbGxfYWxsX2NsYXNzZXMiLCJhbGxfY2xhc3NlcyIsImNsYXNzZXNfd2l0aF9tZXRob2QiLCJwcm9taXNlX3BpbGUiLCJyZXR1cm5fdmFsdWUiLCJfX3N0b3BwZWQiLCJfcnN4X2NvcmVfYm9vdCIsIl9fYm9vdGVkIiwicGhhc2VzIiwicGhhc2UiLCJfcGFyc2VfaGFzaCIsImhhc2hfc3RyaW5nIiwicGFpcnMiLCJwYWlyIiwiX3NlcmlhbGl6ZV9oYXNoIiwiZ2V0X2FsbF9wYWdlX3N0YXRlIiwiZ2V0X3BhZ2Vfc3RhdGUiLCJfc3RhdGUka2V5Iiwic3RhdGUiLCJzZXRfcGFnZV9zdGF0ZSIsIm5ld19oYXNoIiwicGF0aG5hbWUiLCJoaXN0b3J5IiwicmVwbGFjZVN0YXRlIiwic2V0X2FsbF9wYWdlX3N0YXRlIiwibmV3X3N0YXRlIiwicmVuZGVyX2Vycm9yIiwiJGNvbnRhaW5lciIsImZpbGUiLCJfZXNjYXBlX2h0bWwiLCJkaXYiLCJpbm5lckhUTUwiLCJfZTgyMTFmNWJfZGVmaW5lUHJvcGVydHkiLCJfcGVuZGluZ19jYWxscyIsIl9mbHVzaF90aW1lb3V0IiwiX2NhbGxfY291bnRlciIsIk1BWF9CQVRDSF9TSVpFIiwiX3RyYWNrZWRfcHJvbWlzZXMiLCJXZWFrU2V0IiwiTW9kYWwiLCJwYXRoIiwiYWpheF9kaXNhYmxlX2JhdGNoaW5nIiwiX2NhbGxfZGlyZWN0IiwiX2NhbGxfYmF0Y2giLCJjYWxsX2tleSIsIl9nZW5lcmF0ZV9jYWxsX2tleSIsImV4aXN0aW5nX2NhbGwiLCJpc19jb21wbGV0ZSIsImlzX2Vycm9yIiwiY2FsbGJhY2tzIiwiY2FsbF9pZCIsInBlbmRpbmdfY2FsbCIsInBlbmRpbmdfY291bnQiLCJfZmx1c2hfcGVuZGluZ19jYWxscyIsInN1Y2Nlc3MiLCJfc3VjY2VzcyIsInByb2Nlc3NlZF92YWx1ZSIsIl9hamF4X3JldHVybl92YWx1ZSIsImVycm9yX3R5cGUiLCJmYXRhbF9lcnJvcl9kYXRhIiwiZmF0YWxfZXJyb3IiLCJlbmRwb2ludCIsImF1dGhfZXJyb3IiLCJ1bmF1dGhfZXJyb3IiLCJmb3JtX2Vycm9yIiwiZ2VuZXJpY19lcnJvciIsInhociIsIl9leHRyYWN0X2Vycm9yX21lc3NhZ2UiLCJuZXR3b3JrX2Vycm9yIiwic3RhdHVzVGV4dCIsImNhbGxzX3RvX3NlbmQiLCJjYWxsX21hcCIsImJhdGNoX2NhbGxzIiwicmVzcG9uc2Vfa2V5IiwiY2FsbF9yZXNwb25zZSIsImVycm9yX2RldGFpbHMiLCJfcmVmMiIsInhocl9lcnJvciIsIl9yZWYzIiwic29ydGVkX3BhcmFtcyIsInJlc3BvbnNlSlNPTiIsInJlc3BvbnNlVGV4dCIsIkpxaHRtbF9Db21wb25lbnQiLCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50IiwiSnFodG1sX0ludGVncmF0aW9uIiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZSIsImpxaHRtbF9jb21wb25lbnRzIiwiY29tcG9uZW50IiwianFodG1sIiwicmVnaXN0ZXJfY29tcG9uZW50IiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQiLCIkc2NvcGUiLCJpc190b3BfbGV2ZWwiLCJjb21wb25lbnRzX25lZWRpbmdfaW5pdCIsImNvbnRhaW5zIiwiY2xhc3NMaXN0IiwiY29tcG9uZW50X25hbWUiLCJjb21wb25lbnRfYXJncyIsImFyZ3Nfc3RyaW5nIiwicmVtb3ZlQXR0ciIsInJlbW92ZURhdGEiLCJjb21wb25lbnRfYXJnc19maWx0ZXJlZCIsIl9pbm5lcl9odG1sIiwiY29tcG9uZW50X3Byb21pc2UiLCJuZXN0ZWRfcHJvbWlzZXMiLCJnZXRfY29tcG9uZW50X25hbWVzIiwiaGFzX2NvbXBvbmVudCIsIlRlc3RfTW9kYWxfRm9ybSIsIm9uX2NyZWF0ZSIsIm9uX3JlYWR5IiwidmFscyIsIiRpZCIsInJvbGUiLCJEZXZfTW9kYWxzIiwib25fYXBwX3JlYWR5IiwiaW5pdCIsImFsZXJ0Iiwic2hvd19yZXN1bHQiLCJjb25maXJtIiwicHJvbXB0IiwiJHJpY2hfY29udGVudCIsImFwcGVuZCIsInZhbGlkIiwic2hvdyIsInRpdGxlIiwiYm9keSIsImJ1dHRvbnMiLCJsYWJlbCIsImRlZmF1bHQiLCIkY29udGVudCIsIm1heF93aWR0aCIsInVuY2xvc2FibGUiLCJjbG9zZSIsInByb21pc2UxIiwicHJvbWlzZTIiLCJwcm9taXNlMyIsImVycm9yX29iaiIsInRhbGxfY29udGVudCIsImZvcm0iLCJvbl9zdWJtaXQiLCJzdWJtaXRfbGFiZWwiLCJwaW4iLCJjb3JyZWN0X3BpbiIsInZlcmlmaWVkIiwiaXNfb3BlbiIsImN1cnJlbnRfbW9kYWwiLCJnZXRfY3VycmVudCIsImZvcm1hdHRlZCIsInNlY3Rpb24iLCIkcmVzdWx0IiwiJHRleHQiLCJmYWRlT3V0IiwiRGV2X0F0dGFjaG1lbnRzIiwiZmlsZXMiLCJ1cGxvYWRfaW1hZ2UiLCJGb3JtRGF0YSIsInByb2Nlc3NEYXRhIiwiY29udGVudFR5cGUiLCJhdHRhY2htZW50IiwiZXh0ZW5zaW9uIiwiZmlsZV9leHRlbnNpb24iLCJfeGhyJHJlc3BvbnNlSlNPTiIsIkRldl9JbmRleCIsInRvb2x0aXAiLCJEYXRhR3JpZF9BYnN0cmFjdCIsInJvd3MiLCJsb2FkaW5nIiwiaXNfZW1wdHkiLCJsb2FkZWQiLCJ0b3RhbF9wYWdlcyIsIl90aGF0JGFyZ3MkcGVyX3BhZ2UiLCJfdGhhdCRhcmdzJHNvcnQiLCJfdGhhdCRhcmdzJG9yZGVyIiwiZGF0YV9zb3VyY2UiLCJkZWZhdWx0X3BhZ2UiLCJkZWZhdWx0X3Blcl9wYWdlIiwicGVyX3BhZ2UiLCJkZWZhdWx0X3NvcnQiLCJkZWZhdWx0X29yZGVyIiwib3JkZXIiLCJkZWZhdWx0X2ZpbHRlciIsImhhc2hfcGFnZSIsIl9jaWQiLCJoYXNoX3NvcnQiLCJoYXNoX29yZGVyIiwiaGFzaF9maWx0ZXIiLCJwYWdlIiwicmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcyIsInJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycyIsIiRmaWx0ZXIiLCJtZWFzdXJlX2FuZF9zZXRfZml4ZWRfaGVpZ2h0IiwibG9hZF9wYWdlIiwidXBkYXRlX2hlYWRlciIsIl9sYXN0X2hlYWRlcl9zdGF0ZSIsImN1cnJlbnQiLCJyZW5kZXIiLCJ1cGRhdGVfcGFnaW5hdGlvbiIsIl9sYXN0X3BhZ2luYXRpb25fc3RhdGUiLCJ0b3RhbCIsInJlY29yZHMiLCJzY3JvbGxfdG9fdG9wX2lmX25lZWRlZCIsIiRyb3ciLCIkY29sIiwiJGNoaWxkcmVuIiwiY2hpbGRyZW4iLCIkdGgiLCJzb3J0YnkiLCIkZXhpc3RpbmdfbGluayIsImNvbnRlbnRzIiwiZW5kIiwiYXJyb3ciLCJzb3J0X2J5IiwiaGFzQ2xhc3MiLCIkY2xlYXJfYnRuIiwiY2xlYXJfZmlsdGVyIiwiY29sdW1uIiwiZmlsdGVyX3ZhbHVlIiwiZmlsdGVyX2NoYW5nZWQiLCIkZGF0YWdyaWQiLCJkYXRhZ3JpZFRvcCIsInNjcm9sbFRvIiwiYmVoYXZpb3IiLCIkdGJvZHkiLCIkbWVhc3VyZW1lbnRfcm93Iiwicm93X2hlaWdodCIsIm1pbl9oZWlnaHQiLCJ0Ym9keV9taW5faGVpZ2h0IiwiQWN0aXZpdHlfRmVlZCIsIm9uX2xvYWQiLCJhY3Rpdml0aWVzIiwiYXV0b19yZWZyZXNoIiwic3RhcnRfYXV0b19yZWZyZXNoIiwiaW50ZXJ2YWwiLCJyZWZyZXNoX2ludGVydmFsIiwicmVmcmVzaF90aW1lciIsInNldEludGVydmFsIiwicmVsb2FkX2RhdGEiLCJzdG9wX2F1dG9fcmVmcmVzaCIsImNsZWFySW50ZXJ2YWwiLCJBY3Rvcl9SZWZlcmVuY2UiLCJBZHZhbmNlZF9TZWFyY2hfUGFuZWwiLCJjYXRlZ29yaWVzIiwic2V0X29wdGlvbnMiLCJ0YWdzIiwicGVyZm9ybV9zZWFyY2giLCJvbl9jbG9zZSIsImNyaXRlcmlhIiwia2V5d29yZHMiLCJnZXRfdmFsdWUiLCJjYXRlZ29yeSIsImZyb21fZGF0ZSIsInRvX2RhdGUiLCJleGFjdF9tYXRjaCIsIm9uX3NlYXJjaCIsInNldF92YWx1ZSIsIm9uX3Jlc2V0IiwiQWxlcnRfQmFubmVyIiwiZGlzbWlzc2libGUiLCJBdmF0YXIiLCJzaXplIiwic2l6ZV9tYXAiLCJzaG93X2luaXRpYWxzIiwiaW5pdGlhbHMiLCIkZGl2IiwicmVwbGFjZVdpdGgiLCJCbG9ja3F1b3RlIiwiQnJlYWRjcnVtYnMiLCJCdWxrX0FjdGlvbl9CYXIiLCIkdGFibGUiLCJzZXRfY291bnQiLCJCdWxrX1NlbGVjdGlvbiIsIiRjaGVja2JveCIsImNoZWNrZWQiLCJvbl9jaGFuZ2UiLCJCdXR0b25fR3JvdXAiLCJCdXR0b25fUHJpbWFyeSIsIkJ1dHRvbl9TZWNvbmRhcnkiLCJCdXR0b24iLCJDYWxlbmRhcl9FdmVudCIsIm9uX2NsaWNrIiwiQ2FsZW5kYXJfR3JpZCIsImN1cnJlbnRfZGF0ZSIsInJlbmRlcl9jYWxlbmRhciIsInNldE1vbnRoIiwiZ2V0TW9udGgiLCJ5ZWFyIiwiZ2V0RnVsbFllYXIiLCJtb250aCIsIm1vbnRoX25hbWVzIiwiZmlyc3RfZGF5IiwiZ2V0RGF5IiwiZGF5c19pbl9tb250aCIsImdldERhdGUiLCJkYXkiLCIkdHIiLCJqIiwiJHRkIiwiJGRheV9udW0iLCJ0b2RheSIsImV2ZW50cyIsImdldF9ldmVudHNfZm9yX2RhdGUiLCIkZXZlbnQiLCJvbl9ldmVudF9jbGljayIsInBhZFN0YXJ0Iiwib25fZGF0ZV9jbGljayIsImRhdGVfc3RyIiwiQ2FyZCIsIkNoYXJ0X0NvbXBvbmVudCIsIkNoZWNrYm94IiwiZGlzYWJsZWQiLCJDb2RlX0Jsb2NrIiwiQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIiwiY29sdW1ucyIsImJ1aWxkX21lbnUiLCIkbWVudSIsIiRsaSIsIiRsYWJlbCIsInZpc2libGUiLCJ0b2dnbGVfY29sdW1uIiwib25fdG9nZ2xlIiwidGFibGUiLCJzZXRfY29sdW1ucyIsIkNvbW1lbnRfVGhyZWFkIiwiY29tbWVudHMiLCJzdWJtaXRfY29tbWVudCIsIiRjb21tZW50IiwiY29tbWVudF9pZCIsInNob3dfcmVwbHlfZm9ybSIsImVkaXRfY29tbWVudCIsImRlbGV0ZV9jb21tZW50Iiwib25fZWRpdCIsIm9uX2RlbGV0ZSIsIkRhdGVfUGlja2VyIiwicmVhZG9ubHkiLCJEcm9wZG93bl9NZW51IiwiJGNoaWxkIiwiRW1wdHlfU3RhdGUiLCJFeHBvcnRfQnV0dG9uIiwiZm9ybWF0IiwiY3VycmVudFRhcmdldCIsImV4cG9ydF9kYXRhIiwib25fZXhwb3J0IiwiYXV0b19leHBvcnQiLCJleHBvcnRfdXJsIiwiZXhwb3J0X2NzdiIsImV4cG9ydF9qc29uIiwiaGVhZGVycyIsImNzdiIsInJvdyIsImhlYWRlciIsImJsb2IiLCJCbG9iIiwiVVJMIiwiY3JlYXRlT2JqZWN0VVJMIiwiJGEiLCJyZXZva2VPYmplY3RVUkwiLCJGaWxlX1VwbG9hZCIsIiRkcm9wX3pvbmUiLCJhY2NlcHQiLCJtdWx0aXBsZSIsImhhbmRsZV9maWxlcyIsInN0b3BQcm9wYWdhdGlvbiIsIm9yaWdpbmFsRXZlbnQiLCJkYXRhVHJhbnNmZXIiLCJtYXhfc2l6ZV9ieXRlcyIsImZvcm1hdF9zaXplIiwic2VsZWN0ZWRfZmlsZSIsInVwbG9hZF91cmwiLCJ1cGxvYWQiLCJvbl9zZWxlY3QiLCJvbl91cGxvYWQiLCJvbl9jbGVhciIsImdldF9maWxlIiwiYnl0ZXMiLCJGaWx0ZXJfQmFyIiwiYWN0aXZlX2ZpbHRlcnMiLCJzdGF0dXNfb3B0aW9ucyIsIiRzdGF0dXMiLCJvcHQiLCJzZWFyY2hfdGltZW91dCIsImFkZF9maWx0ZXIiLCJhcHBseV9maWx0ZXJzIiwiY2xlYXJfZmlsdGVycyIsInVwZGF0ZV9maWx0ZXJfZGlzcGxheSIsImRhdGVfcmFuZ2UiLCJzdGFydF9kYXRlIiwiZW5kX2RhdGUiLCJvbl9hcHBseSIsIiR0YWdzIiwiJHRhZyIsIiRyZW1vdmUiLCJnZXRfZmlsdGVycyIsIkZvcm1fQWN0aW9uc19Db21wb25lbnQiLCJvbl9jbGlja19oZWxsbyIsIkZvcm1fRmllbGRfR3JvdXAiLCJjb2xsYXBzaWJsZSIsIm1ha2VfY29sbGFwc2libGUiLCIkaGVhZGVyIiwiJGJvZHkiLCJjb2xsYXBzZV9pZCIsInJhbmRvbSIsInN1YnN0ciIsIiR0b2dnbGUiLCJGb3JtX0dyb3VwX0NvbXBvbmVudCIsImNvbF9jbGFzcyIsIkZvcm1fUm93X0NvbXBvbmVudCIsIkZvcm1fVmFsaWRhdGlvbl9NZXNzYWdlIiwiR2FudHRfQ2hhcnQiLCJ0YXNrcyIsIm1vbnRocyIsImdlbmVyYXRlX21vbnRocyIsIkljb25fQnV0dG9uIiwiSWNvbl9XaXRoX0xhYmVsIiwiSWNvbl9XaXRoX1RleHQiLCJJY29uIiwiSW5mb19Cb3giLCJjb2xvciIsIklubGluZV9FZGl0X0ZpZWxkIiwiY3VycmVudF92YWx1ZSIsImVudGVyX2VkaXRfbW9kZSIsInNhdmUiLCJjYW5jZWwiLCJzZWxlY3QiLCJleGl0X2VkaXRfbW9kZSIsIm5ld192YWx1ZSIsIm9uX3NhdmUiLCJzaG93X3NhdmluZyIsInVwZGF0ZV9kaXNwbGF5IiwiY2F0Y2giLCJkaXNwbGF5IiwicGxhY2Vob2xkZXIiLCJJbnB1dF9XaXRoX0ljb24iLCJvbl9pbnB1dCIsIklucHV0X1dpdGhfVmFsaWRhdGlvbiIsInZhbGlkYXRlIiwic2V0X3ZhbGlkIiwic2V0X2Vycm9yIiwiJHN1Y2Nlc3MiLCJjbGVhcl92YWxpZGF0aW9uIiwiSW5wdXQiLCJLYW5iYW5fQm9hcmQiLCJzZXR1cF9kcmFnX2FuZF9kcm9wIiwiZHJhZ2dlZF9jYXJkIiwiJGNhcmQiLCIkY29sdW1uIiwib25fbW92ZSIsImNhcmRfaWQiLCJjb2x1bW5faWQiLCJMaW5rIiwiTGlzdCIsIkxvYWRpbmdfU2tlbGV0b24iLCJsaW5lcyIsIiRzcGFuIiwiTWV0cmljX0NhcmQiLCJNb2JpbGVfSGVhZGVyIiwiTW9kYWxfRGlhbG9nIiwibW9kYWwiLCJib290c3RyYXAiLCJNdWx0aV9TZWxlY3QiLCJzZWxlY3RlZF92YWx1ZXMiLCJhbGxfb3B0aW9ucyIsInJlbmRlcl9vcHRpb25zIiwiJHNlYXJjaCIsImZpbHRlcl9vcHRpb25zIiwiY2xlYXJfYWxsIiwic2VsZWN0X2FsbCIsIm9wdGlvbiIsInRvZ2dsZV9vcHRpb24iLCJxdWVyeSIsImZpbHRlcmVkIiwiZWwiLCJOb3RpZmljYXRpb25fQmFkZ2UiLCIkY291bnQiLCJOb3RpZmljYXRpb25fRHJvcGRvd24iLCJPdmVyZHVlX0luZGljYXRvciIsIlBhZ2VfSGVhZGVyIiwiUGFnZV9TZWN0aW9uIiwiUGFnZSIsIlBvcG92ZXIiLCJjb250ZW50IiwiUHJvZ3Jlc3NfQmFyIiwiJGJhciIsInNob3dfdmFsdWUiLCJSYWRpb19CdXR0b24iLCJSaWNoX1RleHRfRWRpdG9yIiwiJGVkaXRvciIsImNvbW1hbmQiLCJleGVjQ29tbWFuZCIsInBsYWluX3RleHRfcGFzdGUiLCJnZXREYXRhIiwiZ2V0X3RleHQiLCJSb3dfQWN0aW9uX01lbnUiLCJ3cmFwIiwiU2FtcGxlX0RhdGFncmlkX0NvbXBvbmVudCIsImFwaV91cmwiLCJnZW5lcmF0ZV9zYW1wbGVfZGF0YSIsInNlbGVjdGFibGUiLCJ1cGRhdGVfc2VsZWN0aW9uX2NvdW50IiwiYWxsb3dfZGVsZXRlIiwiJGJ1dHRvbiIsImNvbmZpcm1fZGVsZXRlIiwicGFnaW5hdGlvbiIsImdvX3RvX3BhZ2UiLCJjdXJyZW50X3BhZ2UiLCJzZWxlY3RlZCIsImdldF9zZWxlY3RlZF9pZHMiLCJpZHMiLCJjaGVja2JveCIsImNsZWFyX3NlbGVjdGlvbiIsImRlbGV0ZV9yb3ciLCJzdGF0dXNlcyIsImZpcnN0X25hbWVzIiwibGFzdF9uYW1lcyIsImNvbXBhbmllcyIsInNob3dpbmciLCJmaXJzdF9uYW1lIiwiZmxvb3IiLCJsYXN0X25hbWUiLCJjb21wYW55IiwicGhvbmUiLCJzdGF0dXNfY29sb3IiLCJjcmVhdGVkIiwicmFuZG9tX2RhdGUiLCJjZWlsIiwidG8iLCJwYWdlcyIsIlNlYXJjaF9CYXIiLCJTZWFyY2hhYmxlX1NlbGVjdCIsInNlbGVjdGVkX3ZhbHVlIiwic2VsZWN0ZWRfb3B0aW9uIiwiJGl0ZW0iLCJzZWxlY3Rfb3B0aW9uIiwiZHJvcGRvd24iLCJEcm9wZG93biIsImdldEluc3RhbmNlIiwiU2VsZWN0X0Ryb3Bkb3duIiwiU2lkZWJhcl9OYXYiLCIkbmF2X2l0ZW1zIiwiY3VycmVudF9wYXRoIiwiU29ydGFibGVfQ29sdW1uX0hlYWRlciIsInRvZ2dsZV9zb3J0Iiwic2V0X3NvcnQiLCJuZXh0Iiwib25fc29ydCIsImRpcmVjdGlvbiIsIiRpY29uIiwiU3Bpbm5lciIsIlN0YXRfQ2FyZCIsIlN0YXR1c19CYWRnZSIsImNvbG9yX21hcCIsImJnX2NsYXNzIiwiVGFiX0NvbnRlbnQiLCJUYWJsZV9QYWdpbmF0aW9uIiwiZ2VuZXJhdGVfcGFnaW5hdGlvbiIsIiRwYWdpbmF0aW9uIiwiJHByZXYiLCJzdGFydCIsIiRuZXh0IiwiVGFibGUiLCJ2YXJpYW50IiwiVGFicyIsIlRhZ19Hcm91cCIsIlRhZyIsIlRleHRfRGlzcGxheSIsIlRleHRhcmVhIiwiVGhyZWVfQ29sdW1uX0xheW91dCIsIlRpbWVfUGlja2VyIiwic3RlcCIsIlRpbWVsaW5lIiwiVGltZXN0YW1wX0Rpc3BsYXkiLCJUb29sdGlwIiwicGxhY2VtZW50IiwiVG9wX05hdiIsIiRuYXYiLCJUcmVuZF9JbmRpY2F0b3IiLCJpc19wb3NpdGl2ZSIsImlzX25lZ2F0aXZlIiwiVHdvX0NvbHVtbl9MYXlvdXQiLCJVc2VyX0F2YXRhcl9Ecm9wZG93biIsIk1vZGFsX0Fic3RyYWN0IiwiUnN4X01vZGFsIiwiYm9keV9jb250ZW50IiwiY2xvc2FibGUiLCJjbG9zZV9vbl9zdWJtaXQiLCJyZXN1bHRfcHJvbWlzZSIsInJlc29sdmVfZm4iLCJfYnNfbW9kYWwiLCJfcmVzaXplX2hhbmRsZXIiLCJfYXBwbHlfc2l6aW5nIiwiaW50ZXJuYWxfb3B0aW9ucyIsInNraXBfYmFja2Ryb3AiLCJzaG91bGRfYW5pbWF0ZSIsImljb24iLCJfc2V0X2JvZHlfY29udGVudCIsIl9zZXRfYnV0dG9ucyIsIl9mYWRlX2luIiwiX2ZvY3VzX2ZpcnN0X2lucHV0IiwiZXNjYXBlZCIsImpRdWVyeSIsIiRmb290ZXIiLCJidXR0b25fZGVmIiwiaGFkX2NhbGxiYWNrIiwidmlld3BvcnRfaGVpZ2h0Iiwidmlld3BvcnRfbGltaXQiLCJwcmVmZXJyZWRfd2lkdGgiLCJjb250ZW50X2hlaWdodCIsIm1heF9oZWlnaHQiLCJvZmZzZXRIZWlnaHQiLCIkZmlyc3RfaW5wdXQiLCJvZmYiLCJhcHBseV9lcnJvcnMiLCJfaW5pdCIsIl9pbml0aWFsaXplZCIsIl9iYWNrZHJvcCIsIl9nZXRfc2Nyb2xsYmFyX3dpZHRoIiwiJG91dGVyIiwidmlzaWJpbGl0eSIsIm92ZXJmbG93Iiwid2lkdGhfd2l0aF9zY3JvbGxiYXIiLCJvZmZzZXRXaWR0aCIsIiRpbm5lciIsIndpZHRoX3dpdGhvdXRfc2Nyb2xsYmFyIiwiX2xvY2tfYm9keV9zY3JvbGwiLCJfdW5sb2NrX3RpbWVvdXQiLCJfb3JpZ2luYWxfYm9keV9vdmVyZmxvdyIsIl9vcmlnaW5hbF9ib2R5X3BhZGRpbmciLCJoYXNfc2Nyb2xsYmFyIiwic2Nyb2xsYmFyX3dpZHRoIiwiY3VycmVudF9wYWRkaW5nIiwiX3VubG9ja19ib2R5X3Njcm9sbCIsIl9jdXJyZW50IiwiX3F1ZXVlIiwiX3Nob3dfYmFja2Ryb3AiLCJfaGlkZV9iYWNrZHJvcCIsIl9jcmVhdGVfbW9kYWwiLCIkbW9kYWxfZWxlbWVudCIsIm1vZGFsX2luc3RhbmNlIiwiZm9vdGVyIiwiX3Nob3dfbW9kYWwiLCJfcHJvY2Vzc19xdWV1ZSIsImJhY2tkcm9wX3Zpc2libGUiLCJ0aW1lX3NpbmNlX2xhc3RfY2xvc2UiLCJfbGFzdF9jbG9zZV90aW1lc3RhbXAiLCJ0aXRsZV9vcl9ib2R5IiwiYnV0dG9uX2xhYmVsIiwiY29uZmlybV9sYWJlbCIsImNhbmNlbF9sYWJlbCIsImRlZmF1bHRfdmFsdWUiLCJtdWx0aWxpbmUiLCJkZWZhdWx0cyIsImZpbmFsX29wdGlvbnMiLCIkY29tcG9uZW50X2NvbnRhaW5lciIsImNvbXBvbmVudF9pbnN0YW5jZSIsInN1Ym1pdCIsImN1c3RvbSIsImVycm9yX21lc3NhZ2VzIiwicmVvcGVuX3dpdGhfZXJyb3JzIiwiX2QxZjVhM2NiX2RlZmluZVByb3BlcnR5IiwiQnJlYWRjcnVtYl9JdGVtIiwiQ2xpZW50X0xhYmVsX0xpbmsiLCJjbGllbnQiLCJjbGllbnRfaWQiLCJGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyIiwiZ2V0X2NsaWVudCIsIm9uX3JlbmRlciIsIkNsaWVudF9MYWJlbCIsIkZvcm1fSW5wdXRfQWJzdHJhY3QiLCJzZWVkIiwiVGV4dF9JbnB1dCIsInNlZWRlciIsIkNoZWNrYm94X0lucHV0IiwiY2hlY2tlZF92YWx1ZSIsInVuY2hlY2tlZF92YWx1ZSIsImlucHV0X2lkIiwiaXNfY2hlY2tlZCIsInNob3VsZF9jaGVjayIsIld5c2l3eWdfSW5wdXQiLCJxdWlsbCIsIl9pbml0aWFsaXplX3F1aWxsIiwidGhlbWUiLCJtb2R1bGVzIiwidG9vbGJhciIsInJvb3QiLCJzYW1wbGVfY29udGVudCIsIlNlbGVjdF9JbnB1dCIsImRlY29kZWQiLCJhbGxvd0VtcHR5T3B0aW9uIiwiY3JlYXRlIiwibWF4T3B0aW9ucyIsInBsdWdpbnMiLCJvbkluaXRpYWxpemUiLCJjb250cm9sIiwidG9tX3NlbGVjdCIsIlRvbVNlbGVjdCIsInNldFZhbHVlIiwiZ2V0VmFsdWUiLCJyYW5kb21faW5kZXgiLCJyYW5kb21fb3B0IiwicmFuZG9tX3ZhbHVlIiwib25fZGVzdHJveSIsImRlc3Ryb3kiLCJBamF4X1NlbGVjdF9JbnB1dCIsInNlbGVjdF92YWx1ZXMiLCJfcGVuZGluZ192YWx1ZSIsIm9rIiwiQ3VycmVuY3lfSW5wdXQiLCJhbGxvd19kZWNpbWFscyIsInNob3dfc3ltYm9sIiwiY3VycmVuY3lfc3ltYm9sIiwiX2Zvcm1hdF9jdXJyZW5jeSIsImludGVnZXJfcGFydCIsImRlY2ltYWxfcGFydCIsIl9nZXRfbnVtZXJpY192YWx1ZSIsImNsZWFuZWQiLCJkZWNpbWFsX2NvdW50IiwiZmlyc3RfZGVjaW1hbCIsInJhdyIsIm51bWVyaWMiLCJpbnB1dF9lbGVtZW50IiwiY3Vyc29yX3BvcyIsInNlbGVjdGlvblN0YXJ0IiwiY3Vyc29yX2VuZCIsInNlbGVjdGlvbkVuZCIsInZhbHVlX2xlbmd0aCIsImNoYXJfYmVmb3JlIiwibmV3X251bWVyaWMiLCJuZXdfbGVuZ3RoIiwic2V0U2VsZWN0aW9uUmFuZ2UiLCJzeW1ib2xfb2Zmc2V0IiwibmV3X2N1cnNvciIsImluaXRpYWxfdmFsdWUiLCJQaG9uZV9UZXh0X0lucHV0IiwiX2lzX2ludGVybmF0aW9uYWwiLCJfY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlIiwiX2Zvcm1hdF91c19waG9uZSIsImRpZ2l0cyIsInN0cl92YWx1ZSIsImRpZ2l0c190b19mb3JtYXQiLCJfbGFzdF9jdXJzb3JfcG9zaXRpb24iLCJuZXdfZGlnaXRzIiwiU3RhdGVfU2VsZWN0X0lucHV0IiwiY291bnRyeV9jb2RlIiwiUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIiLCJzdGF0ZXMiLCJjb3VudHJ5IiwiX3N0YXRlX2NhY2hlIiwiaXNfbmEiLCJkaXNhYmxlIiwic2V0X2NvdW50cnlfY29kZSIsImN1cnJlbnRfY291bnRyeSIsInJlZHJhdyIsImNhY2hlZF92YWx1ZSIsInZhbHVlX2V4aXN0cyIsImVuYWJsZSIsIkNvdW50cnlfU2VsZWN0X0lucHV0IiwiY291bnRyaWVzIiwiZGVmYXVsdF9jb3VudHJ5IiwiZGVmYXVsdF9jb3VudHJ5X2NvZGUiLCJkZWZhdWx0X2NvdW50cnlfaW5kZXgiLCJmaW5kSW5kZXgiLCJ1bnNoaWZ0IiwiX3VwZGF0ZV9zdGF0ZV9zZWxlY3RvciIsInN0YXRlX2NvbXBvbmVudCIsIlByb2ZpbGVfUGhvdG9fSW5wdXQiLCJhdHRhY2htZW50X2tleSIsInRodW1ibmFpbF91cmwiLCJ1cGxvYWRfcGhvdG8iLCJzaG93X3JlbW92ZSIsInJlbW92ZV9waG90byIsIm1heF9zaXplIiwidXBkYXRlX3Bob3RvIiwiUnN4X1RhYnMiLCJ0YWJzIiwiYWN0aXZlX3RhYl9pZCIsIl9idWlsZF9uYXYiLCJ0YWJfaWQiLCJhY3RpdmF0ZV90YWIiLCJyZWdpc3Rlcl90YWIiLCJ0YWJfY29tcG9uZW50IiwidGFiIiwiaXNfYWN0aXZlIiwidCIsImhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyIsInRhYl9lcnJvcnMiLCJlcnJvcl9jb3VudCIsImNvdW50X2Vycm9ycyIsIiRiYWRnZSIsImZpcnN0X2Vycm9yZWRfdGFiIiwiY2xlYXJfZXJyb3JfYmFkZ2VzIiwiUnN4X1RhYiIsInRhYnNfY29udGFpbmVyIiwiZmllbGRzIiwiZWxlbWVudCIsImZpZWxkX2NvbXBvbmVudCIsIlJzeF9Gb3JtIiwidGFic19lbCIsInNoYWxsb3dGaW5kIiwiJHdpZGdldCIsIndpZGdldF9uYW1lIiwiZ2V0X2Vycm9yIiwiYWpheF91cmwiLCJyZWRpcmVjdCIsIlBpbl9WZXJpZmljYXRpb25fRm9ybSIsInBpbl9sZW5ndGgiLCJmaXJzdF9lbXB0eSIsIl9maW5kX2ZpcnN0X2VtcHR5X2luZGV4IiwiX2ZvY3VzX2lucHV0IiwiX2hhbmRsZV9wYXN0ZSIsInN0YXJ0X2luZGV4IiwicGFzdGUiLCJuZXh0X2luZGV4IiwiRm9ybV9GaWVsZF9BYnN0cmFjdCIsImhhc19lcnJvciIsIndpZGdldF9jb21wb25lbnQiLCJGb3JtX0ZpZWxkIiwiRm9ybV9IaWRkZW5fRmllbGQiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOzs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzFLQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDL0NBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDVEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3BCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNwQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNQQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN6RUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNQQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzFNQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDWkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNWQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDaENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2pDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3hDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNOQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDWEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2hEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2pCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNsQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDM0NBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNqQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN0QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN2QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNWQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3hEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDWEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3ZOQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNUQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2pCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNUQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDVkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDWkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5VUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNsQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3JCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDdEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzVEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN2Q0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDaEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25DQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3BDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3REQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDaENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDNUJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN4Q0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNsQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzNDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRyIsImZpbGUiOiJidW5kbGVfb3V0cHV0X0Rldl9CdW5kbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ3aW5kb3cucnN4YXBwID0gd2luZG93LnJzeGFwcCB8fCB7fTtcbndpbmRvdy5yc3hhcHAubW9kdWxlX3BhdGhzID0ge1wiYm9vdHN0cmFwNV9zcmNcIjpcInJzeFxcL3RoZW1lXFwvdmVuZG9yXFwvYm9vdHN0cmFwNVxcL3Njc3NcIn07XG4iLCIvLyBOUE0gSW1wb3J0IERlY2xhcmF0aW9ucyBmb3IgQXBwIEJ1bmRsZVxuLy8gQXV0by1nZW5lcmF0ZWQgdG8gcHJvdmlkZSBOUE0gbW9kdWxlcyB0byBhcHAgYnVuZGxlIHNjb3BlXG4vLyBDYWNoZSBrZXk6IDk1YTZmNjAyYzk4MDM3NjExYjY0MGIwYjUzNDI4MzBiXG5cbmNvbnN0IGpxaHRtbCA9IHdpbmRvdy5fcnN4X25wbS5qcWh0bWw7XG5pZiAoIWpxaHRtbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1JTWCBGcmFtZXdvcmsgRXJyb3I6IE5QTSBtb2R1bGUgXCJqcWh0bWxcIiBub3QgZm91bmQuXFxuJyArXG4gICAgICAgICdFeHBlY3RlZCB3aW5kb3cuX3JzeF9ucG0uanFodG1sIHRvIGJlIGRlZmluZWQgYnkgdGhlIHZlbmRvciBidW5kbGUuJ1xuICAgICk7XG59XG5cbmNvbnN0IF9CYXNlX0pxaHRtbF9Db21wb25lbnQgPSB3aW5kb3cuX3JzeF9ucG0uX0Jhc2VfSnFodG1sX0NvbXBvbmVudDtcbmlmICghX0Jhc2VfSnFodG1sX0NvbXBvbmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1JTWCBGcmFtZXdvcmsgRXJyb3I6IE5QTSBtb2R1bGUgXCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50XCIgbm90IGZvdW5kLlxcbicgK1xuICAgICAgICAnRXhwZWN0ZWQgd2luZG93Ll9yc3hfbnBtLl9CYXNlX0pxaHRtbF9Db21wb25lbnQgdG8gYmUgZGVmaW5lZCBieSB0aGUgdmVuZG9yIGJ1bmRsZS4nXG4gICAgKTtcbn1cblxuLy8gQ2xlYW4gdXAgTlBNIGNvbnRhaW5lciB0byBwcmV2ZW50IGNvbnNvbGUgYWNjZXNzXG5kZWxldGUgd2luZG93Ll9yc3hfbnBtO1xuIiwiLyoqXG4gKiBEZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBtYXJrcyBhIGZ1bmN0aW9uIGFzIGEgZGVjb3JhdG9yIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIFdoZW4gYSBmdW5jdGlvbiBoYXMgQGRlY29yYXRvciBpbiBpdHMgSlNEb2MgY29tbWVudCwgaXQgd2hpdGVsaXN0cyB0aGF0IGZ1bmN0aW9uXG4gKiB0byBiZSB1c2VkIGFzIGEgZGVjb3JhdG9yIG9uIG90aGVyIG1ldGhvZHMgdGhyb3VnaG91dCB0aGUgY29kZWJhc2UuXG4gKlxuICogVGhlIGZ1bmN0aW9uIGl0c2VsZiBwZXJmb3JtcyBubyBvcGVyYXRpb24gLSBpdCBzaW1wbHkgcmV0dXJucyBpdHMgaW5wdXQgdW5jaGFuZ2VkLlxuICogSXRzIHB1cnBvc2UgaXMgcHVyZWx5IGFzIGEgbWFya2VyIGZvciB0aGUgbWFuaWZlc3QgdmFsaWRhdGlvbiBzeXN0ZW0uXG4gKlxuICogVXNhZ2U6XG4gKiAgIC8vIC8qKlxuICogICAvLyAgKiBNeSBjdXN0b20gZGVjb3JhdG9yIGltcGxlbWVudGF0aW9uXG4gKiAgIC8vICAqIEBkZWNvcmF0b3JcbiAqICAgLy8gICpcXC9cbiAqICAgZnVuY3Rpb24gbXlfY3VzdG9tX2RlY29yYXRvcih0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICogICAgICAgLy8gRGVjb3JhdG9yIGltcGxlbWVudGF0aW9uXG4gKiAgIH1cbiAqXG4gKiBUaGlzIGFsbG93cyBteV9jdXN0b21fZGVjb3JhdG9yIHRvIGJlIHVzZWQgYXMgQG15X2N1c3RvbV9kZWNvcmF0b3Igb24gc3RhdGljIG1ldGhvZHMuXG4gKlxuICogVE9ETzogVGhpcyBpcyBwcm9iYWJseSBubyBsb25nZXIgbmVjZXNzYXJ5PyBtYXliZT9cbiAqL1xuZnVuY3Rpb24gZGVjb3JhdG9yKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuIiwiLypcbiAqIEJyb3dzZXIgYW5kIERPTSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIGJyb3dzZXIgZGV0ZWN0aW9uLCB2aWV3cG9ydCB1dGlsaXRpZXMsIGFuZCBET00gbWFuaXB1bGF0aW9uLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEJST1dTRVIgREVURUNUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB1c2VyIGlzIG9uIGEgbW9iaWxlIGRldmljZSBvciB1c2luZyBtb2JpbGUgdmlld3BvcnRcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG1vYmlsZSBkZXZpY2Ugb3Igdmlld3BvcnQgPCA5OTJweFxuICogQHRvZG8gSW1wcm92ZSB1c2VyIGFnZW50IGRldGVjdGlvbiBmb3IgYWxsIG1vYmlsZSBkZXZpY2VzXG4gKi9cbmZ1bmN0aW9uIGlzX21vYmlsZSgpIHtcbiAgICBpZiAoL0FuZHJvaWR8d2ViT1N8aVBob25lfGlQYWR8aVBvZHxCbGFja0JlcnJ5fElFTW9iaWxlfE9wZXJhIE1pbmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoJCh3aW5kb3cpLndpZHRoKCkgPCA5OTIpIHtcbiAgICAgICAgLy8gOTkycHggPSBib290c3RyYXAgNCBjb2wtbWQtXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB1c2VyIGlzIG9uIGRlc2t0b3AgKG5vdCBtb2JpbGUpXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBub3QgbW9iaWxlIGRldmljZS92aWV3cG9ydFxuICovXG5mdW5jdGlvbiBpc19kZXNrdG9wKCkge1xuICAgIHJldHVybiAhaXNfbW9iaWxlKCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB0aGUgdXNlcidzIG9wZXJhdGluZyBzeXN0ZW1cbiAqIEByZXR1cm5zIHtzdHJpbmd9IE9TIG5hbWU6ICdNYWMgT1MnLCAnaVBob25lJywgJ2lQYWQnLCAnV2luZG93cycsICdBbmRyb2lkLVBob25lJywgJ0FuZHJvaWQtVGFibGV0JywgJ0xpbnV4Jywgb3IgJ1Vua25vd24nXG4gKi9cbmZ1bmN0aW9uIGdldF9vcygpIHtcbiAgICBsZXQgdXNlcl9hZ2VudCA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LFxuICAgICAgICBwbGF0Zm9ybSA9IHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0sXG4gICAgICAgIG1hY29zX3BsYXRmb3JtcyA9IFsnTWFjaW50b3NoJywgJ01hY0ludGVsJywgJ01hY1BQQycsICdNYWM2OEsnXSxcbiAgICAgICAgd2luZG93c19wbGF0Zm9ybXMgPSBbJ1dpbjMyJywgJ1dpbjY0JywgJ1dpbmRvd3MnLCAnV2luQ0UnXSxcbiAgICAgICAgaW9zX3BsYXRmb3JtcyA9IFsnaVBob25lJywgJ2lQYWQnLCAnaVBvZCddLFxuICAgICAgICBvcyA9IG51bGw7XG5cbiAgICBsZXQgaXNfbW9iaWxlX2RldmljZSA9IGlzX21vYmlsZSgpO1xuXG4gICAgaWYgKG1hY29zX3BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEpIHtcbiAgICAgICAgb3MgPSAnTWFjIE9TJztcbiAgICB9IGVsc2UgaWYgKGlvc19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xICYmIGlzX21vYmlsZV9kZXZpY2UpIHtcbiAgICAgICAgb3MgPSAnaVBob25lJztcbiAgICB9IGVsc2UgaWYgKGlvc19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xICYmICFpc19tb2JpbGVfZGV2aWNlKSB7XG4gICAgICAgIG9zID0gJ2lQYWQnO1xuICAgIH0gZWxzZSBpZiAod2luZG93c19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xKSB7XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgIH0gZWxzZSBpZiAoL0FuZHJvaWQvLnRlc3QodXNlcl9hZ2VudCkgJiYgaXNfbW9iaWxlX2RldmljZSkge1xuICAgICAgICBvcyA9ICdBbmRyb2lkLVBob25lJztcbiAgICB9IGVsc2UgaWYgKC9BbmRyb2lkLy50ZXN0KHVzZXJfYWdlbnQpICYmICFpc19tb2JpbGVfZGV2aWNlKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQtVGFibGV0JztcbiAgICB9IGVsc2UgaWYgKCFvcyAmJiAvTGludXgvLnRlc3QocGxhdGZvcm0pKSB7XG4gICAgICAgIG9zID0gJ0xpbnV4JztcbiAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9ICdVbmtub3duJztcbiAgICB9XG5cbiAgICByZXR1cm4gb3M7XG59XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB0aGUgdXNlciBhZ2VudCBpcyBhIHdlYiBjcmF3bGVyL2JvdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdXNlciBhZ2VudCBhcHBlYXJzIHRvIGJlIGEgYm90L2NyYXdsZXJcbiAqL1xuZnVuY3Rpb24gaXNfY3Jhd2xlcigpIHtcbiAgICBsZXQgdXNlcl9hZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgbGV0IGJvdF9wYXR0ZXJuID0gL2JvdHxzcGlkZXJ8Y3Jhd2x8c2x1cnB8YXJjaGl2ZXJ8cGluZ3xzZWFyY2h8ZGlnfHRyYWNrZXJ8bW9uaXRvcnxzbm9vcHl8eWFob298YmFpZHV8bXNufGFza3x0ZW9tYXxheGlvcy9pO1xuXG4gICAgcmV0dXJuIGJvdF9wYXR0ZXJuLnRlc3QodXNlcl9hZ2VudCk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERPTSBTQ1JPTExJTkcgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogU2Nyb2xscyBwYXJlbnQgY29udGFpbmVyIHRvIG1ha2UgdGFyZ2V0IGVsZW1lbnQgdmlzaWJsZSBpZiBuZWVkZWRcbiAqIEBwYXJhbSB7c3RyaW5nfEhUTUxFbGVtZW50fGpRdWVyeX0gdGFyZ2V0IC0gVGFyZ2V0IGVsZW1lbnQgdG8gc2Nyb2xsIGludG8gdmlld1xuICovXG5mdW5jdGlvbiBzY3JvbGxfaW50b192aWV3X2lmX25lZWRlZCh0YXJnZXQpIHtcbiAgICBjb25zdCAkdGFyZ2V0ID0gJCh0YXJnZXQpO1xuXG4gICAgLy8gRmluZCB0aGUgY2xvc2VzdCBwYXJlbnQgd2l0aCBvdmVyZmxvdy15OiBhdXRvXG4gICAgY29uc3QgJHBhcmVudCA9ICR0YXJnZXQucGFyZW50KCk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGFic29sdXRlIHRvcCBwb3NpdGlvbiBvZiB0aGUgdGFyZ2V0XG4gICAgY29uc3QgdGFyZ2V0X3RvcCA9ICR0YXJnZXQucG9zaXRpb24oKS50b3AgKyAkcGFyZW50LnNjcm9sbFRvcCgpO1xuXG4gICAgY29uc3QgdGFyZ2V0X2hlaWdodCA9ICR0YXJnZXQub3V0ZXJIZWlnaHQoKTtcbiAgICBjb25zdCBwYXJlbnRfaGVpZ2h0ID0gJHBhcmVudC5oZWlnaHQoKTtcbiAgICBjb25zdCBzY3JvbGxfcG9zaXRpb24gPSAkcGFyZW50LnNjcm9sbFRvcCgpO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHRhcmdldCBpcyBvdXQgb2Ygdmlld1xuICAgIGlmICh0YXJnZXRfdG9wIDwgc2Nyb2xsX3Bvc2l0aW9uIHx8IHRhcmdldF90b3AgKyB0YXJnZXRfaGVpZ2h0ID4gc2Nyb2xsX3Bvc2l0aW9uICsgcGFyZW50X2hlaWdodCkge1xuICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdVSScsICdTY3JvbGxpbmchJywgdGFyZ2V0X3RvcCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuZXcgc2Nyb2xsIHBvc2l0aW9uIHRvIGNlbnRlciB0aGUgdGFyZ2V0XG4gICAgICAgIGxldCBuZXdfc2Nyb2xsX3Bvc2l0aW9uID0gdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgLyAyIC0gcGFyZW50X2hlaWdodCAvIDI7XG5cbiAgICAgICAgLy8gTGltaXQgdGhlIHNjcm9sbCBwb3NpdGlvbiBiZXR3ZWVuIDAgYW5kIHRoZSBtYXhpbXVtIHNjcm9sbGFibGUgaGVpZ2h0XG4gICAgICAgIG5ld19zY3JvbGxfcG9zaXRpb24gPSBNYXRoLm1heCgwLCBNYXRoLm1pbihuZXdfc2Nyb2xsX3Bvc2l0aW9uLCAkcGFyZW50WzBdLnNjcm9sbEhlaWdodCAtIHBhcmVudF9oZWlnaHQpKTtcblxuICAgICAgICAvLyBTY3JvbGwgdGhlIHBhcmVudCB0byB0aGUgbmV3IHNjcm9sbCBwb3NpdGlvblxuICAgICAgICAkcGFyZW50LnNjcm9sbFRvcChuZXdfc2Nyb2xsX3Bvc2l0aW9uKTtcbiAgICB9XG59XG5cbi8qKlxuICogU2Nyb2xscyBwYWdlIHRvIG1ha2UgdGFyZ2V0IGVsZW1lbnQgdmlzaWJsZSBpZiBuZWVkZWQgKHdpdGggYW5pbWF0aW9uKVxuICogQHBhcmFtIHtzdHJpbmd8SFRNTEVsZW1lbnR8alF1ZXJ5fSB0YXJnZXQgLSBUYXJnZXQgZWxlbWVudCB0byBzY3JvbGwgaW50byB2aWV3XG4gKi9cbmZ1bmN0aW9uIHNjcm9sbF9wYWdlX2ludG9fdmlld19pZl9uZWVkZWQodGFyZ2V0KSB7XG4gICAgY29uc3QgJHRhcmdldCA9ICQodGFyZ2V0KTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgYWJzb2x1dGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50XG4gICAgY29uc3QgdGFyZ2V0X3RvcCA9ICR0YXJnZXQub2Zmc2V0KCkudG9wO1xuXG4gICAgY29uc3QgdGFyZ2V0X2hlaWdodCA9ICR0YXJnZXQub3V0ZXJIZWlnaHQoKTtcbiAgICBjb25zdCB3aW5kb3dfaGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgIGNvbnN0IHdpbmRvd19zY3JvbGxfcG9zaXRpb24gPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdGFyZ2V0IGlzIG91dCBvZiB2aWV3XG4gICAgaWYgKHRhcmdldF90b3AgPCB3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uIHx8IHRhcmdldF90b3AgKyB0YXJnZXRfaGVpZ2h0ID4gd2luZG93X3Njcm9sbF9wb3NpdGlvbiArIHdpbmRvd19oZWlnaHQpIHtcbiAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZygnVUknLCAnU2Nyb2xsaW5nIScsIHRhcmdldF90b3ApO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbmV3IHNjcm9sbCBwb3NpdGlvbiB0byBjZW50ZXIgdGhlIHRhcmdldFxuICAgICAgICBjb25zdCBuZXdfc2Nyb2xsX3Bvc2l0aW9uID0gdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgLyAyIC0gd2luZG93X2hlaWdodCAvIDI7XG5cbiAgICAgICAgLy8gQW5pbWF0ZSB0aGUgc2Nyb2xsIHRvIHRoZSBuZXcgcG9zaXRpb25cbiAgICAgICAgJCgnaHRtbCwgYm9keScpLmFuaW1hdGUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiBuZXdfc2Nyb2xsX3Bvc2l0aW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDEwMDBcbiAgICAgICAgKTsgLy8gZHVyYXRpb24gb2YgdGhlIHNjcm9sbCBhbmltYXRpb24gaW4gbWlsbGlzZWNvbmRzXG4gICAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBET00gVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogV2FpdHMgZm9yIGFsbCBpbWFnZXMgb24gdGhlIHBhZ2UgdG8gbG9hZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gYWxsIGltYWdlcyBhcmUgbG9hZGVkXG4gKi9cbmZ1bmN0aW9uIHdhaXRfZm9yX2ltYWdlcyhjYWxsYmFjaykge1xuICAgIGNvbnN0ICRpbWFnZXMgPSAkKCdpbWcnKTsgLy8gR2V0IGFsbCBpbWcgdGFnc1xuICAgIGNvbnN0IHRvdGFsX2ltYWdlcyA9ICRpbWFnZXMubGVuZ3RoO1xuICAgIGxldCBpbWFnZXNfbG9hZGVkID0gMDtcblxuICAgIGlmICh0b3RhbF9pbWFnZXMgPT09IDApIHtcbiAgICAgICAgY2FsbGJhY2soKTsgLy8gaWYgdGhlcmUgYXJlIG5vIGltYWdlcywgaW1tZWRpYXRlbHkgY2FsbCB0aGUgY2FsbGJhY2tcbiAgICB9XG5cbiAgICAkaW1hZ2VzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGltYWdlc19sb2FkZWQrKztcbiAgICAgICAgICAgIGlmIChpbWFnZXNfbG9hZGVkID09PSB0b3RhbF9pbWFnZXMpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpOyAvLyBjYWxsIHRoZSBjYWxsYmFjayB3aGVuIGFsbCBpbWFnZXMgYXJlIGxvYWRlZFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpbWcub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGltYWdlc19sb2FkZWQrKztcbiAgICAgICAgICAgIGlmIChpbWFnZXNfbG9hZGVkID09PSB0b3RhbF9pbWFnZXMpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpOyAvLyBhbHNvIGNhbGwgdGhlIGNhbGxiYWNrIGlmIGFuIGltYWdlIGZhaWxzIHRvIGxvYWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaW1nLnNyYyA9IHRoaXMuc3JjOyAvLyB0aGlzIHRyaWdnZXJzIHRoZSBsb2FkaW5nXG4gICAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGpRdWVyeSBlbGVtZW50IGNvbnRhaW5pbmcgYSBub24tYnJlYWtpbmcgc3BhY2VcbiAqIEByZXR1cm5zIHtqUXVlcnl9IGpRdWVyeSBzcGFuIGVsZW1lbnQgd2l0aCAmbmJzcDtcbiAqL1xuZnVuY3Rpb24gJG5ic3AoKSB7XG4gICAgcmV0dXJuICQoJzxzcGFuPiZuYnNwOzwvc3Bhbj4nKTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIGpRdWVyeSBzZWxlY3RvclxuICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gRWxlbWVudCBJRCB0byBlc2NhcGVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IGpRdWVyeSBzZWxlY3RvciBzdHJpbmcgd2l0aCBlc2NhcGVkIHNwZWNpYWwgY2hhcmFjdGVyc1xuICogQHdhcm5pbmcgTm90IHNhZmUgZm9yIHNlY3VyaXR5LWNyaXRpY2FsIG9wZXJhdGlvbnNcbiAqL1xuZnVuY3Rpb24gZXNjYXBlX2pxX3NlbGVjdG9yKGlkKSB7XG4gICAgcmV0dXJuICcjJyArIGlkLnJlcGxhY2UoLyg6fFxcLnxcXFt8XFxdfCx8PXxAKS9nLCAnXFxcXCQxJyk7XG59IiwiLypcbiAqIERhdGUgYW5kIHRpbWUgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHRoZSBSU3BhZGUgZnJhbWV3b3JrLlxuICogVGhlc2UgZnVuY3Rpb25zIGhhbmRsZSBkYXRlL3RpbWUgY29udmVyc2lvbnMgYW5kIFVuaXggdGltZXN0YW1wcy5cbiAqL1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEQVRFL1RJTUUgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogR2V0cyB0aGUgY3VycmVudCBVbml4IHRpbWVzdGFtcCAoc2Vjb25kcyBzaW5jZSBlcG9jaClcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEN1cnJlbnQgVW5peCB0aW1lc3RhbXAgaW4gc2Vjb25kc1xuICogQHRvZG8gQ2FsY3VsYXRlIGJhc2VkIG9uIHNlcnZlciB0aW1lIGF0IHBhZ2UgcmVuZGVyXG4gKiBAdG9kbyBNb3ZlIHRvIGEgZGF0ZSBsaWJyYXJ5XG4gKi9cbmZ1bmN0aW9uIHVuaXhfdGltZSgpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgZGF0ZSBzdHJpbmcgdG8gVW5peCB0aW1lc3RhbXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJfZGF0ZSAtIERhdGUgc3RyaW5nIChZLW0tZCBIOmk6cyBmb3JtYXQpXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbml4IHRpbWVzdGFtcCBpbiBzZWNvbmRzXG4gKi9cbmZ1bmN0aW9uIHltZGhpc190b191bml4KHN0cl9kYXRlKSB7XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHN0cl9kYXRlKTtcbiAgICByZXR1cm4gZGF0ZS5nZXRUaW1lKCkgLyAxMDAwO1xufSIsIi8qXG4gKiBFcnJvciBoYW5kbGluZyB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIGVycm9yIGNyZWF0aW9uIGFuZCBkZWJ1Z2dpbmcgdXRpbGl0aWVzLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVSUk9SIEhBTkRMSU5HXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlcnJvciBvYmplY3QgZnJvbSBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBzdHIgLSBFcnJvciBtZXNzYWdlIG9yIGV4aXN0aW5nIGVycm9yIG9iamVjdFxuICogQHBhcmFtIHtudW1iZXJ9IFtlcnJvcl9jb2RlXSAtIE9wdGlvbmFsIGVycm9yIHN0YXR1cyBjb2RlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBFcnJvciBvYmplY3Qgd2l0aCBlcnJvciBhbmQgc3RhdHVzIHByb3BlcnRpZXNcbiAqL1xuZnVuY3Rpb24gZXJyb3Ioc3RyLCBlcnJvcl9jb2RlKSB7XG4gICAgaWYgKHR5cGVvZiBzdHIuZXJyb3IgIT0gdW5kZWYpIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIGVycm9yX2NvZGUgPT0gdW5kZWYpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGVycm9yOiBzdHIsIHN0YXR1czogbnVsbCB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHsgZXJyb3I6IHN0ciwgc3RhdHVzOiBlcnJvcl9jb2RlIH07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIGZhaWx1cmUgaGFuZGxlciBmb3IgSmF2YVNjcmlwdFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGEgc2FuaXR5IGNoZWNrIGZhaWxzIC0gaS5lLiwgd2hlbiB0aGUgY29kZVxuICogZW5jb3VudGVycyBhIGNvbmRpdGlvbiB0aGF0IFwic2hvdWxkbid0IGhhcHBlblwiIGlmIGV2ZXJ5dGhpbmcgaXMgd29ya2luZyBjb3JyZWN0bHkuXG4gKlxuICogVW5saWtlIFBIUCwgd2UgY2FuJ3Qgc3RvcCBKYXZhU2NyaXB0IGV4ZWN1dGlvbiwgYnV0IHdlIGNhbjpcbiAqIDEuIFRocm93IGFuIGVycm9yIHRoYXQgd2lsbCBiZSBjYXVnaHQgYnkgZXJyb3IgaGFuZGxlcnNcbiAqIDIuIExvZyBhIGNsZWFyIGVycm9yIHRvIHRoZSBjb25zb2xlXG4gKiAzLiBQcm92aWRlIHN0YWNrIHRyYWNlIGZvciBkZWJ1Z2dpbmdcbiAqXG4gKiBVc2UgdGhpcyBpbnN0ZWFkIG9mIHNpbGVudGx5IHJldHVybmluZyBvciBjb250aW51aW5nIHdoZW4gZW5jb3VudGVyaW5nIHVuZXhwZWN0ZWQgY29uZGl0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBPcHRpb25hbCBzcGVjaWZpYyBtZXNzYWdlIGFib3V0IHdoYXQgc2hvdWxkbid0IGhhdmUgaGFwcGVuZWRcbiAqIEB0aHJvd3Mge0Vycm9yfSBBbHdheXMgdGhyb3dzIHdpdGggbG9jYXRpb24gYW5kIGNvbnRleHQgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hvdWxkbnRfaGFwcGVuKG1lc3NhZ2UgPSBudWxsKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBjb25zdCBzdGFjayA9IGVycm9yLnN0YWNrIHx8ICcnO1xuICAgIGNvbnN0IHN0YWNrTGluZXMgPSBzdGFjay5zcGxpdCgnXFxuJyk7XG5cbiAgICAvLyBHZXQgdGhlIGNhbGxlciBsb2NhdGlvbiAoc2tpcCB0aGUgRXJyb3IgbGluZSBhbmQgdGhpcyBmdW5jdGlvbilcbiAgICBsZXQgY2FsbGVySW5mbyA9ICd1bmtub3duIGxvY2F0aW9uJztcbiAgICBpZiAoc3RhY2tMaW5lcy5sZW5ndGggPiAyKSB7XG4gICAgICAgIGNvbnN0IGNhbGxlckxpbmUgPSBzdGFja0xpbmVzWzJdIHx8IHN0YWNrTGluZXNbMV0gfHwgJyc7XG4gICAgICAgIC8vIEV4dHJhY3QgZmlsZSBhbmQgbGluZSBudW1iZXIgZnJvbSBzdGFjayB0cmFjZVxuICAgICAgICBjb25zdCBtYXRjaCA9IGNhbGxlckxpbmUubWF0Y2goL2F0XFxzKy4qP1xccytcXCgoLio/KTooXFxkKyk6KFxcZCspXFwpLykgfHwgY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrKC4qPyk6KFxcZCspOihcXGQrKS8pO1xuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGNhbGxlckluZm8gPSBgJHttYXRjaFsxXX06JHttYXRjaFsyXX1gO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGVycm9yTWVzc2FnZSA9IGBGYXRhbDogc2hvdWxkbnRfaGFwcGVuKCkgd2FzIGNhbGxlZCBhdCAke2NhbGxlckluZm99XFxuYDtcbiAgICBlcnJvck1lc3NhZ2UgKz0gJ1RoaXMgaW5kaWNhdGVzIGEgc2FuaXR5IGNoZWNrIGZhaWxlZCAtIHRoZSBjb2RlIGlzIG5vdCBiZWhhdmluZyBhcyBleHBlY3RlZC5cXG4nO1xuXG4gICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlICs9IGBEZXRhaWxzOiAke21lc3NhZ2V9XFxuYDtcbiAgICB9XG5cbiAgICBlcnJvck1lc3NhZ2UgKz0gJ1BsZWFzZSB0aG9yb3VnaGx5IHJldmlldyB0aGUgcmVsYXRlZCBjb2RlIHRvIGRldGVybWluZSB3aHkgdGhpcyBlcnJvciBvY2N1cnJlZC4nO1xuXG4gICAgLy8gTG9nIHRvIGNvbnNvbGUgd2l0aCBmdWxsIHZpc2liaWxpdHlcbiAgICBjb25zb2xlLmVycm9yKCc9Jy5yZXBlYXQoODApKTtcbiAgICBjb25zb2xlLmVycm9yKCdTQU5JVFkgQ0hFQ0sgRkFJTFVSRScpO1xuICAgIGNvbnNvbGUuZXJyb3IoJz0nLnJlcGVhdCg4MCkpO1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICBjb25zb2xlLmVycm9yKCdTdGFjayB0cmFjZTonLCBzdGFjayk7XG4gICAgY29uc29sZS5lcnJvcignPScucmVwZWF0KDgwKSk7XG5cbiAgICAvLyBUaHJvdyBlcnJvciB0byBzdG9wIGV4ZWN1dGlvbiBmbG93XG4gICAgY29uc3QgZmF0YWxFcnJvciA9IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgIGZhdGFsRXJyb3IubmFtZSA9ICdTYW5pdHlDaGVja0ZhaWx1cmUnO1xuICAgIHRocm93IGZhdGFsRXJyb3I7XG59IiwiLypcbiAqIEhhc2hpbmcgYW5kIGNvbXBhcmlzb24gdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHRoZSBSU3BhZGUgZnJhbWV3b3JrLlxuICogVGhlc2UgZnVuY3Rpb25zIGhhbmRsZSBvYmplY3QgaGFzaGluZyBhbmQgZGVlcCBjb21wYXJpc29uLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhBU0hJTkcgQU5EIENPTVBBUklTT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSB1bmlxdWUgaGFzaCBmb3IgYW55IHZhbHVlIChoYW5kbGVzIG9iamVjdHMsIGFycmF5cywgY2lyY3VsYXIgcmVmZXJlbmNlcylcbiAqIEBwYXJhbSB7Kn0gdGhlX3ZhciAtIFZhbHVlIHRvIGhhc2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NhbGNfc2hhMT10cnVlXSAtIElmIHRydWUsIHJldHVybnMgU0hBMSBoYXNoOyBpZiBmYWxzZSwgcmV0dXJucyBKU09OXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtpZ25vcmVkX2tleXM9bnVsbF0gLSBLZXlzIHRvIGlnbm9yZSB3aGVuIGhhc2hpbmcgb2JqZWN0c1xuICogQHJldHVybnMge3N0cmluZ30gU0hBMSBoYXNoIG9yIEpTT04gc3RyaW5nIG9mIHRoZSB2YWx1ZVxuICovXG5mdW5jdGlvbiBoYXNoKHRoZV92YXIsIGNhbGNfc2hhMSA9IHRydWUsIGlnbm9yZWRfa2V5cyA9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIHRoZV92YXIgPT0gdW5kZWYpIHtcbiAgICAgICAgdGhlX3ZhciA9ICdfX3VuZGVmaW5lZF9fJztcbiAgICB9XG5cbiAgICBpZiAoaWdub3JlZF9rZXlzID09PSBudWxsKSB7XG4gICAgICAgIGlnbm9yZWRfa2V5cyA9IFsnJCddO1xuICAgIH1cblxuICAgIC8vIENvbnZlcnRzIHZhbHVlIHRvIGpzb24sIGRpc2NhcmRpbmcgY2lyY3VsYXIgcmVmZXJlbmNlc1xuICAgIGxldCBqc29uX3N0cmluZ2lmeV9ub2NpcmMgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY29uc3QgY2FjaGUgPSBbXTtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCBmdW5jdGlvbiAoa2V5LCB2KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdvYmplY3QnICYmIHR5cGVvZiB0aGVfdmFyLl9jYWNoZV9rZXkgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGVfdmFyLl9oYXNoX2tleSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdiA9PT0gJ29iamVjdCcgJiYgdiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZS5pbmRleE9mKHYpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBEdXBsaWNhdGUgcmVmZXJlbmNlIGZvdW5kLCBkaXNjYXJkIGtleVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhY2hlLnB1c2godik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIFR1cm4gZXZlcnkgcHJvcGVydHkgYW5kIGFsbCBpdHMgY2hpbGRyZW4gaW50byBhIHNpbmdsZSBkZXB0aCBhcnJheSBvZiB2YWx1ZXMgdGhhdCB3ZSBjYW4gdGhlblxuICAgIC8vIHNvcnQgYW5kIGhhc2ggYXMgYSB3aG9sZVxuICAgIGxldCBmbGF0X3ZhciA9IHt9O1xuICAgIGxldCBfZmxhdHRlbiA9IGZ1bmN0aW9uICh0aGVfdmFyLCBwcmVmaXgsIGRlcHRoID0gMCkge1xuICAgICAgICAvLyBJZiBhIGNsYXNzIG9iamVjdCBpcyBwcm92aWRlZCwgY2lyY3VsYXIgcmVmZXJlbmNlcyBjYW4gbWFrZSB0aGUgY2FsbCBzdGFjayByZWN1cnNpdmUuXG4gICAgICAgIC8vIEZvciB0aGUgcHVycG9zZXMgb2YgaG93IHRoZSBoYXNoIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhpcyBzaG91bGQgYmUgc3VmZmljaWVudC5cbiAgICAgICAgaWYgKGRlcHRoID4gMTApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvZXMgbm90IGFjY291bnQgZm9yIGRhdGVzIGkgdGhpbmsuLi5cblxuICAgICAgICBpZiAoaXNfb2JqZWN0KHRoZV92YXIpICYmIHR5cGVvZiB0aGVfdmFyLl9jYWNoZV9rZXkgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy8gVXNlIF9jYWNoZV9rZXkgdG8gaGFzaCBjb21wb25lbnRzXG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0gdGhlX3Zhci5faGFzaF9rZXkoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc19vYmplY3QodGhlX3ZhcikgJiYgdHlwZW9mIEFic3RyYWN0ICE9PSAndW5kZWZpbmVkJyAmJiB0aGVfdmFyIGluc3RhbmNlb2YgQWJzdHJhY3QpIHtcbiAgICAgICAgICAgIC8vIFN0cmluZ2lmeSBhbGwgY2xhc3Mgb2JqZWN0c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IGpzb25fc3RyaW5naWZ5X25vY2lyYyh0aGVfdmFyKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc19vYmplY3QodGhlX3ZhcikpIHtcbiAgICAgICAgICAgIC8vIEl0ZXJhdGUgb3RoZXIgb2JqZWN0c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IHt9O1xuICAgICAgICAgICAgZm9yIChsZXQgayBpbiB0aGVfdmFyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoZV92YXIuaGFzT3duUHJvcGVydHkoaykgJiYgaWdub3JlZF9rZXlzLmluZGV4T2YoaykgPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgX2ZsYXR0ZW4odGhlX3ZhcltrXSwgcHJlZml4ICsgJy4uJyArIGssIGRlcHRoICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGlzX2FycmF5KHRoZV92YXIpKSB7XG4gICAgICAgICAgICAvLyBJdGVyYXRlIGFycmF5c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IFtdO1xuICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgZm9yZWFjaCh0aGVfdmFyLCAodikgPT4ge1xuICAgICAgICAgICAgICAgIF9mbGF0dGVuKHYsIHByZWZpeCArICcuLicgKyBpLCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzX2Z1bmN0aW9uKHRoZV92YXIpKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nXG4gICAgICAgIH0gZWxzZSBpZiAoIWlzX251bWVyaWModGhlX3ZhcikpIHtcbiAgICAgICAgICAgIGZsYXRfdmFyW3ByZWZpeF0gPSBTdHJpbmcodGhlX3Zhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0gdGhlX3ZhcjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBfZmxhdHRlbih0aGVfdmFyLCAnXycpO1xuXG4gICAgbGV0IHNvcnRlciA9IFtdO1xuXG4gICAgZm9yZWFjaChmbGF0X3ZhciwgZnVuY3Rpb24gKHYsIGspIHtcbiAgICAgICAgc29ydGVyLnB1c2goW2ssIHZdKTtcbiAgICB9KTtcblxuICAgIHNvcnRlci5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhWzBdID4gYlswXTtcbiAgICB9KTtcblxuICAgIGxldCBqc29uID0gSlNPTi5zdHJpbmdpZnkoc29ydGVyKTtcblxuICAgIGlmIChjYWxjX3NoYTEpIHtcbiAgICAgICAgbGV0IGhhc2hlZCA9IHNoYTEuc2hhMShqc29uKTtcbiAgICAgICAgcmV0dXJuIGhhc2hlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG59XG5cbi8qKlxuICogRGVlcCBjb21wYXJpc29uIG9mIHR3byB2YWx1ZXMgKGlnbm9yZXMgcHJvcGVydHkgb3JkZXIgYW5kIGZ1bmN0aW9ucylcbiAqIEBwYXJhbSB7Kn0gYSAtIEZpcnN0IHZhbHVlIHRvIGNvbXBhcmVcbiAqIEBwYXJhbSB7Kn0gYiAtIFNlY29uZCB2YWx1ZSB0byBjb21wYXJlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZXMgYXJlIGRlZXBseSBlcXVhbFxuICovXG5mdW5jdGlvbiBkZWVwX2VxdWFsKGEsIGIpIHtcbiAgICByZXR1cm4gaGFzaChhLCBmYWxzZSkgPT0gaGFzaChiLCBmYWxzZSk7XG59IiwiLyoqXG4gKiBNdXRleCBkZWNvcmF0b3IgZm9yIGV4Y2x1c2l2ZSBtZXRob2QgZXhlY3V0aW9uXG4gKlxuICogV2l0aG91dCBhcmd1bWVudHM6IFBlci1pbnN0YW5jZSBsb2NraW5nIChlYWNoIG9iamVjdCBoYXMgaXRzIG93biBsb2NrIHBlciBtZXRob2QpXG4gKiAgIEBtdXRleFxuICogICBhc3luYyBteV9tZXRob2QoKSB7IC4uLiB9XG4gKlxuICogV2l0aCBJRCBhcmd1bWVudDogR2xvYmFsIGxvY2tpbmcgYnkgSUQgKGFsbCBpbnN0YW5jZXMgc2hhcmUgdGhlIGxvY2spXG4gKiAgIEBtdXRleCgnb3BlcmF0aW9uX25hbWUnKVxuICogICBhc3luYyBteV9tZXRob2QoKSB7IC4uLiB9XG4gKlxuICogQGRlY29yYXRvclxuICogQHBhcmFtIHtzdHJpbmd9IFtnbG9iYWxfaWRdIC0gT3B0aW9uYWwgZ2xvYmFsIG11dGV4IElEIGZvciBjcm9zcy1pbnN0YW5jZSBsb2NraW5nXG4gKi9cbmZ1bmN0aW9uIG11dGV4KGdsb2JhbF9pZCkge1xuICAgIC8vIFN0b3JhZ2UgKHVzaW5nIElJRkVzIHRvIGtlZXAgV2Vha01hcC9NYXAgaW4gY2xvc3VyZSBzY29wZSlcbiAgICBjb25zdCBpbnN0YW5jZV9tdXRleGVzID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIW11dGV4Ll9pbnN0YW5jZV9zdG9yYWdlKSB7XG4gICAgICAgICAgICBtdXRleC5faW5zdGFuY2Vfc3RvcmFnZSA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG11dGV4Ll9pbnN0YW5jZV9zdG9yYWdlO1xuICAgIH0pKCk7XG5cbiAgICBjb25zdCBnbG9iYWxfbXV0ZXhlcyA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCFtdXRleC5fZ2xvYmFsX3N0b3JhZ2UpIHtcbiAgICAgICAgICAgIG11dGV4Ll9nbG9iYWxfc3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXV0ZXguX2dsb2JhbF9zdG9yYWdlO1xuICAgIH0pKCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3IgY3JlYXRlIGEgbXV0ZXggZm9yIGEgc3BlY2lmaWMgaW5zdGFuY2UgYW5kIG1ldGhvZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldF9pbnN0YW5jZV9tdXRleChpbnN0YW5jZSwgbWV0aG9kX25hbWUpIHtcbiAgICAgICAgbGV0IGluc3RhbmNlX2xvY2tzID0gaW5zdGFuY2VfbXV0ZXhlcy5nZXQoaW5zdGFuY2UpO1xuICAgICAgICBpZiAoIWluc3RhbmNlX2xvY2tzKSB7XG4gICAgICAgICAgICBpbnN0YW5jZV9sb2NrcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGluc3RhbmNlX211dGV4ZXMuc2V0KGluc3RhbmNlLCBpbnN0YW5jZV9sb2Nrcyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbG9ja19zdGF0ZSA9IGluc3RhbmNlX2xvY2tzLmdldChtZXRob2RfbmFtZSk7XG4gICAgICAgIGlmICghbG9ja19zdGF0ZSkge1xuICAgICAgICAgICAgbG9ja19zdGF0ZSA9IHsgYWN0aXZlOiBmYWxzZSwgcXVldWU6IFtdIH07XG4gICAgICAgICAgICBpbnN0YW5jZV9sb2Nrcy5zZXQobWV0aG9kX25hbWUsIGxvY2tfc3RhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxvY2tfc3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IG9yIGNyZWF0ZSBhIGdsb2JhbCBtdXRleCBieSBJRFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldF9nbG9iYWxfbXV0ZXgoaWQpIHtcbiAgICAgICAgbGV0IGxvY2tfc3RhdGUgPSBnbG9iYWxfbXV0ZXhlcy5nZXQoaWQpO1xuICAgICAgICBpZiAoIWxvY2tfc3RhdGUpIHtcbiAgICAgICAgICAgIGxvY2tfc3RhdGUgPSB7IGFjdGl2ZTogZmFsc2UsIHF1ZXVlOiBbXSB9O1xuICAgICAgICAgICAgZ2xvYmFsX211dGV4ZXMuc2V0KGlkLCBsb2NrX3N0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9ja19zdGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlIHRoZSBuZXh0IHF1ZXVlZCBvcGVyYXRpb24gZm9yIGEgbXV0ZXhcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzY2hlZHVsZV9uZXh0KGxvY2tfc3RhdGUpIHtcbiAgICAgICAgaWYgKGxvY2tfc3RhdGUuYWN0aXZlIHx8IGxvY2tfc3RhdGUucXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGZuLCByZXNvbHZlLCByZWplY3QgfSA9IGxvY2tfc3RhdGUucXVldWUuc2hpZnQoKTtcbiAgICAgICAgbG9ja19zdGF0ZS5hY3RpdmUgPSB0cnVlO1xuXG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICAudGhlbihmbilcbiAgICAgICAgICAgIC50aGVuKHJlc29sdmUsIHJlamVjdClcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2NrX3N0YXRlLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHNjaGVkdWxlX25leHQobG9ja19zdGF0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3F1aXJlIGEgbXV0ZXggbG9jayBhbmQgZXhlY3V0ZSBjYWxsYmFja1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFjcXVpcmVfbG9jayhsb2NrX3N0YXRlLCBmbikge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9ja19zdGF0ZS5xdWV1ZS5wdXNoKHsgZm4sIHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIHNjaGVkdWxlX25leHQobG9ja19zdGF0ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIElmIGNhbGxlZCB3aXRoIGFuIElEIGFyZ3VtZW50OiBAbXV0ZXgoJ2lkJylcbiAgICBpZiAodHlwZW9mIGdsb2JhbF9pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbF9tZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9yaWdpbmFsX21ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQG11dGV4IGNhbiBvbmx5IGJlIGFwcGxpZWQgdG8gbWV0aG9kcyAodHJpZWQgdG8gYXBwbHkgdG8gJHtrZXl9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvY2tfc3RhdGUgPSBnZXRfZ2xvYmFsX211dGV4KGdsb2JhbF9pZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjcXVpcmVfbG9jayhsb2NrX3N0YXRlLCAoKSA9PiBvcmlnaW5hbF9tZXRob2QuYXBwbHkodGhpcywgYXJncykpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSWYgY2FsbGVkIHdpdGhvdXQgYXJndW1lbnRzOiBAbXV0ZXggKHRhcmdldCBpcyB0aGUgZmlyc3QgYXJndW1lbnQpXG4gICAgY29uc3QgdGFyZ2V0ID0gZ2xvYmFsX2lkOyAgLy8gSW4gdGhpcyBjYXNlLCBmaXJzdCBhcmcgaXMgdGFyZ2V0XG4gICAgY29uc3Qga2V5ID0gYXJndW1lbnRzWzFdO1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBhcmd1bWVudHNbMl07XG5cbiAgICBjb25zdCBvcmlnaW5hbF9tZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgaWYgKHR5cGVvZiBvcmlnaW5hbF9tZXRob2QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBAbXV0ZXggY2FuIG9ubHkgYmUgYXBwbGllZCB0byBtZXRob2RzICh0cmllZCB0byBhcHBseSB0byAke2tleX0pYCk7XG4gICAgfVxuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IGZ1bmN0aW9uKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgbG9ja19zdGF0ZSA9IGdldF9pbnN0YW5jZV9tdXRleCh0aGlzLCBrZXkpO1xuICAgICAgICByZXR1cm4gYWNxdWlyZV9sb2NrKGxvY2tfc3RhdGUsICgpID0+IG9yaWdpbmFsX21ldGhvZC5hcHBseSh0aGlzLCBhcmdzKSk7XG4gICAgfTtcblxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xufVxuIiwiLypcbiAqIEFzeW5jIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB0aGUgUlNwYWRlIGZyYW1ld29yay5cbiAqIFRoZXNlIGZ1bmN0aW9ucyBoYW5kbGUgYXN5bmNocm9ub3VzIG9wZXJhdGlvbnMsIGRlbGF5cywgZGVib3VuY2luZywgYW5kIG11dGV4ZXMuXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQVNZTkMgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogUGF1c2VzIGV4ZWN1dGlvbiBmb3Igc3BlY2lmaWVkIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtudW1iZXJ9IFttaWxsaXNlY29uZHM9MF0gLSBEZWxheSBpbiBtaWxsaXNlY29uZHMgKDAgdXNlcyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGRlbGF5XG4gKiBAZXhhbXBsZSBhd2FpdCBzbGVlcCgxMDAwKTsgLy8gV2FpdCAxIHNlY29uZFxuICovXG5mdW5jdGlvbiBzbGVlcChtaWxsaXNlY29uZHMgPSAwKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMgPT0gMCAmJiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShyZXNvbHZlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gd2l0aCBleGNsdXNpdml0eSBhbmQgcHJvbWlzZSBmYW4taW5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uLCB3aGVuIGludm9rZWQsIGltbWVkaWF0ZWx5IHJ1bnMgdGhlIGNhbGxiYWNrIGV4Y2x1c2l2ZWx5LlxuICogRm9yIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMsIGl0IGFwcGxpZXMgYSBkZWxheSBiZWZvcmUgcnVubmluZyB0aGUgY2FsbGJhY2sgZXhjbHVzaXZlbHkgYWdhaW4uXG4gKiBUaGUgZGVsYXkgc3RhcnRzIGFmdGVyIHRoZSBjdXJyZW50IGFzeW5jaHJvbm91cyBvcGVyYXRpb24gcmVzb2x2ZXMuXG4gKlxuICogSWYgJ2RlbGF5JyBpcyBzZXQgdG8gMCwgdGhlIGZ1bmN0aW9uIHdpbGwgb25seSBwcmV2ZW50IGVucXVldWVpbmcgbXVsdGlwbGUgZXhlY3V0aW9ucyBvZiB0aGVcbiAqIHNhbWUgbWV0aG9kIG1vcmUgdGhhbiBvbmNlLCBidXQgd2lsbCBzdGlsbCBydW4gdGhlbSBpbW1lZGlhdGVseSBpbiBhbiBleGNsdXNpdmUgc2VxdWVudGlhbCBtYW5uZXIuXG4gKlxuICogVGhlIG1vc3QgcmVjZW50IGludm9jYXRpb24gb2YgdGhlIGZ1bmN0aW9uIHdpbGwgYmUgdGhlIHBhcmFtZXRlcnMgdGhhdCBnZXQgcGFzc2VkIHRvIHRoZSBmdW5jdGlvblxuICogd2hlbiBpdCBpbnZva2VzLlxuICpcbiAqIFRoZSBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG5leHQgZXhjbHVzaXZlIGV4ZWN1dGlvbiBjb21wbGV0ZXMuXG4gKlxuICogVXNhZ2UgYXMgZnVuY3Rpb246XG4gKiAgIGNvbnN0IGRlYm91bmNlZEZuID0gZGVib3VuY2UobXlGdW5jdGlvbiwgMjUwKTtcbiAqXG4gKiBVc2FnZSBhcyBkZWNvcmF0b3I6XG4gKiAgIEBkZWJvdW5jZSgyNTApXG4gKiAgIG15TWV0aG9kKCkgeyAuLi4gfVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb258bnVtYmVyfSBjYWxsYmFja19vcl9kZWxheSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gT1IgZGVsYXkgd2hlbiB1c2VkIGFzIGRlY29yYXRvclxuICogQHBhcmFtIHtudW1iZXJ9IGRlbGF5IFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIHN1YnNlcXVlbnQgaW52b2NhdGlvbnNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW1tZWRpYXRlIGlmIHRydWUsIHRoZSBmaXJzdCB0aW1lIHRoZSBhY3Rpb24gaXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sgZXhlY3V0ZXMgaW1tZWRpYXRlbHlcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0aGF0IHdoZW4gaW52b2tlZCwgcnVucyB0aGUgY2FsbGJhY2sgaW1tZWRpYXRlbHkgYW5kIGV4Y2x1c2l2ZWx5LFxuICpcbiAqIEBkZWNvcmF0b3JcbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoY2FsbGJhY2tfb3JfZGVsYXksIGRlbGF5LCBpbW1lZGlhdGUgPSBmYWxzZSkge1xuICAgIC8vIERlY29yYXRvciB1c2FnZTogQGRlYm91bmNlKDI1MCkgb3IgQGRlYm91bmNlKDI1MCwgdHJ1ZSlcbiAgICAvLyBGaXJzdCBhcmd1bWVudCBpcyBhIG51bWJlciAodGhlIGRlbGF5KSwgcmV0dXJucyBkZWNvcmF0b3IgZnVuY3Rpb25cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrX29yX2RlbGF5ID09PSAnbnVtYmVyJykge1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JfZGVsYXkgPSBjYWxsYmFja19vcl9kZWxheTtcbiAgICAgICAgY29uc3QgZGVjb3JhdG9yX2ltbWVkaWF0ZSA9IGRlbGF5IHx8IGZhbHNlO1xuXG4gICAgICAgIC8vIFRDMzkgZGVjb3JhdG9yIGZvcm06IHJlY2VpdmVzICh2YWx1ZSwgY29udGV4dClcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY29udGV4dCkge1xuICAgICAgICAgICAgaWYgKGNvbnRleHQua2luZCA9PT0gJ21ldGhvZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVib3VuY2VfaW1wbCh2YWx1ZSwgZGVjb3JhdG9yX2RlbGF5LCBkZWNvcmF0b3JfaW1tZWRpYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGdW5jdGlvbiB1c2FnZTogZGVib3VuY2UoZm4sIDI1MClcbiAgICAvLyBGaXJzdCBhcmd1bWVudCBpcyBhIGZ1bmN0aW9uICh0aGUgY2FsbGJhY2spXG4gICAgY29uc3QgY2FsbGJhY2sgPSBjYWxsYmFja19vcl9kZWxheTtcbiAgICByZXR1cm4gZGVib3VuY2VfaW1wbChjYWxsYmFjaywgZGVsYXksIGltbWVkaWF0ZSk7XG59XG5cbi8qKlxuICogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgZGVib3VuY2UgbG9naWNcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlX2ltcGwoY2FsbGJhY2ssIGRlbGF5LCBpbW1lZGlhdGUgPSBmYWxzZSkge1xuICAgIGxldCBydW5uaW5nID0gZmFsc2U7XG4gICAgbGV0IHF1ZXVlZCA9IGZhbHNlO1xuICAgIGxldCBsYXN0X2VuZF90aW1lID0gMDsgLy8gdGltZXN0YW1wIG9mIGxhc3QgY29tcGxldGVkIHJ1blxuICAgIGxldCB0aW1lciA9IG51bGw7XG5cbiAgICBsZXQgbmV4dF9hcmdzID0gW107XG4gICAgbGV0IG5leHRfY29udGV4dCA9IG51bGw7XG4gICAgbGV0IHJlc29sdmVfcXVldWUgPSBbXTtcbiAgICBsZXQgcmVqZWN0X3F1ZXVlID0gW107XG5cbiAgICBjb25zdCBydW5fZnVuY3Rpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRoZXNlX3Jlc29sdmVzID0gcmVzb2x2ZV9xdWV1ZTtcbiAgICAgICAgY29uc3QgdGhlc2VfcmVqZWN0cyA9IHJlamVjdF9xdWV1ZTtcbiAgICAgICAgY29uc3QgYXJncyA9IG5leHRfYXJncztcbiAgICAgICAgY29uc3QgY29udGV4dCA9IG5leHRfY29udGV4dDtcblxuICAgICAgICByZXNvbHZlX3F1ZXVlID0gW107XG4gICAgICAgIHJlamVjdF9xdWV1ZSA9IFtdO1xuICAgICAgICBuZXh0X2FyZ3MgPSBbXTtcbiAgICAgICAgbmV4dF9jb250ZXh0ID0gbnVsbDtcbiAgICAgICAgcXVldWVkID0gZmFsc2U7XG4gICAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjYWxsYmFjay5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb2x2ZSBvZiB0aGVzZV9yZXNvbHZlcykgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVqZWN0IG9mIHRoZXNlX3JlamVjdHMpIHJlamVjdChlcnIpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgbGFzdF9lbmRfdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBpZiAocXVldWVkKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQocnVuX2Z1bmN0aW9uLCBNYXRoLm1heChkZWxheSwgMCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aW1lciA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIG5leHRfYXJncyA9IGFyZ3M7XG4gICAgICAgIG5leHRfY29udGV4dCA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVfcXVldWUucHVzaChyZXNvbHZlKTtcbiAgICAgICAgICAgIHJlamVjdF9xdWV1ZS5wdXNoKHJlamVjdCk7XG5cbiAgICAgICAgICAgIC8vIE5vdGhpbmcgcnVubmluZyBhbmQgbm90aGluZyBzY2hlZHVsZWRcbiAgICAgICAgICAgIGlmICghcnVubmluZyAmJiAhdGltZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaXJzdF9jYWxsID0gbGFzdF9lbmRfdGltZSA9PT0gMDtcblxuICAgICAgICAgICAgICAgIGlmIChpbW1lZGlhdGUgJiYgZmlyc3RfY2FsbCkge1xuICAgICAgICAgICAgICAgICAgICBydW5fZnVuY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNpbmNlID0gZmlyc3RfY2FsbCA/IEluZmluaXR5IDogRGF0ZS5ub3coKSAtIGxhc3RfZW5kX3RpbWU7XG4gICAgICAgICAgICAgICAgaWYgKHNpbmNlID49IGRlbGF5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bl9mdW5jdGlvbigpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdhaXQgPSBNYXRoLm1heChkZWxheSAtIHNpbmNlLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KHJ1bl9mdW5jdGlvbiwgd2FpdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgd2UncmUgYWxyZWFkeSBydW5uaW5nIG9yIGEgdGltZXIgZXhpc3RzLCBqdXN0IG1hcmsgcXVldWVkLlxuICAgICAgICAgICAgLy8gVGhlIGZpbmFsbHl7fSBvZiBydW5fZnVuY3Rpb24gaGFuZGxlcyBzY2hlZHVsaW5nIGFmdGVyIGZ1bGwgZGVsYXkuXG4gICAgICAgICAgICBxdWV1ZWQgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBSRUFELVdSSVRFIExPQ0sgRlVOQ1RJT05TIC0gRGVsZWdhdGVkIHRvIFJlYWRXcml0ZUxvY2sgY2xhc3Ncbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBBY3F1aXJlIGFuIGV4Y2x1c2l2ZSB3cml0ZSBsb2NrIGJ5IG5hbWUuXG4gKiBPbmx5IG9uZSB3cml0ZXIgcnVucyBhdCBhIHRpbWU7IGJsb2NrcyByZWFkZXJzIHVudGlsIGZpbmlzaGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7KCkgPT4gYW55fFByb21pc2U8YW55Pn0gY2JcbiAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gKi9cbmZ1bmN0aW9uIHJ3bG9jayhuYW1lLCBjYikge1xuICAgIHJldHVybiBSZWFkV3JpdGVMb2NrLmFjcXVpcmUobmFtZSwgY2IpO1xufVxuXG4vKipcbiAqIEFjcXVpcmUgYSBzaGFyZWQgcmVhZCBsb2NrIGJ5IG5hbWUuXG4gKiBNdWx0aXBsZSByZWFkZXJzIHJ1biBpbiBwYXJhbGxlbCwgYnV0IHJlYWRlcnMgYXJlIGJsb2NrZWQgYnkgcXVldWVkL2FjdGl2ZSB3cml0ZXJzLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7KCkgPT4gYW55fFByb21pc2U8YW55Pn0gY2JcbiAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gKi9cbmZ1bmN0aW9uIHJ3bG9ja19yZWFkKG5hbWUsIGNiKSB7XG4gICAgcmV0dXJuIFJlYWRXcml0ZUxvY2suYWNxdWlyZV9yZWFkKG5hbWUsIGNiKTtcbn1cblxuLyoqXG4gKiBGb3JjZWZ1bGx5IGNsZWFyIGFsbCBsb2NrcyBhbmQgcXVldWVzIGZvciBhIGdpdmVuIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICovXG5mdW5jdGlvbiByd2xvY2tfZm9yY2VfdW5sb2NrKG5hbWUpIHtcbiAgICBSZWFkV3JpdGVMb2NrLmZvcmNlX3VubG9jayhuYW1lKTtcbn1cblxuLyoqXG4gKiBJbnNwZWN0IGxvY2sgc3RhdGUgZm9yIGRlYnVnZ2luZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7e3JlYWRlcnM6bnVtYmVyLCB3cml0ZXJfYWN0aXZlOmJvb2xlYW4sIHJlYWRlcl9xOm51bWJlciwgd3JpdGVyX3E6bnVtYmVyfX1cbiAqL1xuZnVuY3Rpb24gcndsb2NrX3BlbmRpbmcobmFtZSkge1xuICAgIHJldHVybiBSZWFkV3JpdGVMb2NrLnBlbmRpbmcobmFtZSk7XG59XG4iLCIvKlxuICogQ29yZSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIHR5cGUgY2hlY2tpbmcsIHR5cGUgY29udmVyc2lvbiwgc3RyaW5nIG1hbmlwdWxhdGlvbixcbiAqIGFuZCBvYmplY3QvYXJyYXkgdXRpbGl0aWVzLiBUaGV5IG1pcnJvciBmdW5jdGlvbmFsaXR5IGZyb20gUEhQIGZ1bmN0aW9ucy5cbiAqXG4gKiBPdGhlciB1dGlsaXR5IGZ1bmN0aW9ucyBhcmUgb3JnYW5pemVkIGluOlxuICogLSBhc3luYy5qczogQXN5bmMgdXRpbGl0aWVzIChzbGVlcCwgZGVib3VuY2UsIG11dGV4KVxuICogLSBicm93c2VyLmpzOiBCcm93c2VyL0RPTSB1dGlsaXRpZXMgKGlzX21vYmlsZSwgc2Nyb2xsIGZ1bmN0aW9ucylcbiAqIC0gZGF0ZXRpbWUuanM6IERhdGUvdGltZSB1dGlsaXRpZXNcbiAqIC0gaGFzaC5qczogSGFzaGluZyBhbmQgY29tcGFyaXNvblxuICogLSBlcnJvci5qczogRXJyb3IgaGFuZGxpbmdcbiAqL1xuXG4vLyBUb2RvOiB0ZXN0IHRoYXQgcHJvZCBidWlsZCBpZGVudGlmaWVzIGFuZCByZW1vdmVzIHVuY2FsbGVkIGZ1bmN0aW9ucyBmcm9tIHRoZSBmaW5hbCBidW5kbGUuXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENPTlNUQU5UUyBBTkQgSEVMUEVSU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vLyBEZWZpbmUgY29tbW9ubHkgdXNlZCBjb25zdGFudHNcbmNvbnN0IHVuZGVmID0gJ3VuZGVmaW5lZCc7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBhcnJheXMgb3Igb2JqZWN0cyB3aXRoIHByb21pc2Ugc3VwcG9ydFxuICpcbiAqIFdvcmtzIHdpdGggYm90aCBzeW5jaHJvbm91cyBhbmQgYXN5bmNocm9ub3VzIGNhbGxiYWNrcy4gSWYgdGhlIGNhbGxiYWNrXG4gKiByZXR1cm5zIHByb21pc2VzLCB0aGV5IGFyZSBleGVjdXRlZCBpbiBwYXJhbGxlbCBhbmQgdGhpcyBmdW5jdGlvbiByZXR1cm5zXG4gKiBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBwYXJhbGxlbCB0YXNrcyBjb21wbGV0ZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqIC0gQ29sbGVjdGlvbiB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggaXRlbSAodmFsdWUsIGtleSkgLSBjYW4gYmUgYXN5bmNcbiAqIEByZXR1cm5zIHtQcm9taXNlfHVuZGVmaW5lZH0gUHJvbWlzZSBpZiBhbnkgY2FsbGJhY2tzIHJldHVybiBwcm9taXNlcywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTeW5jaHJvbm91cyB1c2FnZVxuICogZm9yZWFjaChbMSwyLDNdLCAodmFsKSA9PiBjb25zb2xlLmxvZyh2YWwpKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXN5bmNocm9ub3VzIHVzYWdlIC0gd2FpdHMgZm9yIGFsbCB0byBjb21wbGV0ZVxuICogYXdhaXQgZm9yZWFjaChbMSwyLDNdLCBhc3luYyAodmFsKSA9PiB7XG4gKiAgICAgYXdhaXQgZmV0Y2goJy9hcGkvcHJvY2Vzcy8nICsgdmFsKTtcbiAqIH0pO1xuICovXG5mdW5jdGlvbiBmb3JlYWNoKG9iaiwgY2FsbGJhY2spIHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgIG9iai5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChjYWxsYmFjayh2YWx1ZSwgaW5kZXgpKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGNhbGxiYWNrKG9ialtrZXldLCBrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZpbHRlciBmb3IgcHJvbWlzZXNcbiAgICBjb25zdCBwcm9taXNlcyA9IHJlc3VsdHMuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09ICdmdW5jdGlvbicpO1xuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGFueSBwcm9taXNlcywgcmV0dXJuIFByb21pc2UuYWxsIHRvIHdhaXQgZm9yIGFsbCB0byBjb21wbGV0ZVxuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgLy8gTm8gcHJvbWlzZXMgcmV0dXJuZWQsIHNvIHdlJ3JlIGRvbmVcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRZUEUgQ0hFQ0tJTkcgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgbnVtZXJpY1xuICogQHBhcmFtIHsqfSBuIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIGZpbml0ZSBudW1iZXJcbiAqL1xuZnVuY3Rpb24gaXNfbnVtZXJpYyhuKSB7XG4gICAgcmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhIHN0cmluZ1xuICogQHBhcmFtIHsqfSBzIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiBpc19zdHJpbmcocykge1xuICAgIHJldHVybiB0eXBlb2YgcyA9PSAnc3RyaW5nJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhbiBpbnRlZ2VyXG4gKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqL1xuZnVuY3Rpb24gaXNfaW50ZWdlcihuKSB7XG4gICAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIobik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYSBwcm9taXNlLWxpa2Ugb2JqZWN0XG4gKiBAcGFyYW0geyp9IG9iaiAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaGFzIGEgdGhlbiBtZXRob2RcbiAqL1xuZnVuY3Rpb24gaXNfcHJvbWlzZShvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIG9iaiA9PSAnb2JqZWN0JyAmJiB0eXBlb2Ygb2JqLnRoZW4gPT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhbiBhcnJheVxuICogQHBhcmFtIHsqfSBvYmogLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIGFycmF5XG4gKi9cbmZ1bmN0aW9uIGlzX2FycmF5KG9iaikge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KG9iaik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYW4gb2JqZWN0IChleGNsdWRlcyBudWxsKVxuICogQHBhcmFtIHsqfSBvYmogLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIG9iamVjdCBhbmQgbm90IG51bGxcbiAqL1xuZnVuY3Rpb24gaXNfb2JqZWN0KG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogIT09IG51bGw7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYSBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBmdW5jdGlvbl90b19jaGVjayAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBpc19mdW5jdGlvbihmdW5jdGlvbl90b19jaGVjaykge1xuICAgIHJldHVybiBmdW5jdGlvbl90b19jaGVjayAmJiB7fS50b1N0cmluZy5jYWxsKGZ1bmN0aW9uX3RvX2NoZWNrKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXG4gKiBVc2VzIGEgcHJhY3RpY2FsIFJGQyA1MzIyIGNvbXBsaWFudCByZWdleCB0aGF0IG1hdGNoZXMgOTkuOTklIG9mIHJlYWwtd29ybGQgZW1haWwgYWRkcmVzc2VzXG4gKiBAcGFyYW0ge3N0cmluZ30gZW1haWwgLSBFbWFpbCBhZGRyZXNzIHRvIHZhbGlkYXRlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgZW1haWwgYWRkcmVzc1xuICovXG5mdW5jdGlvbiBpc19lbWFpbChlbWFpbCkge1xuICAgIGlmICghaXNfc3RyaW5nKGVtYWlsKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHJlZ2V4ID0gL15bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKD86XFwuW2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKykqQCg/OlthLXowLTldKD86W2EtejAtOS1dKlthLXowLTldKT9cXC4pK1thLXowLTldKD86W2EtejAtOS1dKlthLXowLTldKT8kL2k7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QoZW1haWwpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGRlZmluZWQgKG5vdCB1bmRlZmluZWQpXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWRcbiAqL1xuZnVuY3Rpb24gaXNzZXQodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9IHVuZGVmO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGVtcHR5IChudWxsLCB1bmRlZmluZWQsIDAsIFwiXCIsIGVtcHR5IGFycmF5L29iamVjdClcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5XG4gKi9cbmZ1bmN0aW9uIGVtcHR5KG9iamVjdCkge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09IHVuZGVmKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob2JqZWN0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9iamVjdCA9PSAnc3RyaW5nJyAmJiBvYmplY3QgPT0gJycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT0gMDtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gIW9iamVjdC5sZW5ndGg7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFIENPTlZFUlNJT04gRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ29udmVydHMgYSB2YWx1ZSB0byBhIGZsb2F0aW5nIHBvaW50IG51bWJlclxuICogUmV0dXJucyAwIGZvciBudWxsLCB1bmRlZmluZWQsIE5hTiwgb3Igbm9uLW51bWVyaWMgdmFsdWVzXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEZsb2F0aW5nIHBvaW50IG51bWJlclxuICovXG5mdW5jdGlvbiBmbG9hdCh2YWwpIHtcbiAgICAvLyBIYW5kbGUgbnVsbCwgdW5kZWZpbmVkLCBlbXB0eSBzdHJpbmdcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gJycpIHtcbiAgICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gcGFyc2UgdGhlIHZhbHVlXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VGbG9hdCh2YWwpO1xuXG4gICAgLy8gQ2hlY2sgZm9yIE5hTiBhbmQgcmV0dXJuIDAgaWYgcGFyc2luZyBmYWlsZWRcbiAgICByZXR1cm4gaXNOYU4ocGFyc2VkKSA/IDAuMCA6IHBhcnNlZDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGFuIGludGVnZXJcbiAqIFJldHVybnMgMCBmb3IgbnVsbCwgdW5kZWZpbmVkLCBOYU4sIG9yIG5vbi1udW1lcmljIHZhbHVlc1xuICogQHBhcmFtIHsqfSB2YWwgLSBWYWx1ZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBJbnRlZ2VyIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGludCh2YWwpIHtcbiAgICAvLyBIYW5kbGUgbnVsbCwgdW5kZWZpbmVkLCBlbXB0eSBzdHJpbmdcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gJycpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHBhcnNlIHRoZSB2YWx1ZVxuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlSW50KHZhbCwgMTApO1xuXG4gICAgLy8gQ2hlY2sgZm9yIE5hTiBhbmQgcmV0dXJuIDAgaWYgcGFyc2luZyBmYWlsZWRcbiAgICByZXR1cm4gaXNOYU4ocGFyc2VkKSA/IDAgOiBwYXJzZWQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSB2YWx1ZSB0byBhIHN0cmluZ1xuICogUmV0dXJucyBlbXB0eSBzdHJpbmcgZm9yIG51bGwgb3IgdW5kZWZpbmVkXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHIodmFsKSB7XG4gICAgLy8gSGFuZGxlIG51bGwgYW5kIHVuZGVmaW5lZCBzcGVjaWFsbHlcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IHRvIHN0cmluZ1xuICAgIHJldHVybiBTdHJpbmcodmFsKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBudW1lcmljIHN0cmluZ3MgdG8gbnVtYmVycywgcmV0dXJucyBhbGwgb3RoZXIgdmFsdWVzIHVuY2hhbmdlZFxuICogVXNlZCB3aGVuIHlvdSBuZWVkIHRvIGVuc3VyZSBudW1lcmljIHR5cGVzIGJ1dCBkb24ndCB3YW50IHRvIGZvcmNlXG4gKiBjb252ZXJzaW9uIG9mIG5vbi1udW1lcmljIHZhbHVlcyAod2hpY2ggd291bGQgYmVjb21lIDApXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHsqfSBOdW1iZXIgaWYgaW5wdXQgd2FzIG51bWVyaWMgc3RyaW5nLCBvdGhlcndpc2UgdW5jaGFuZ2VkXG4gKi9cbmZ1bmN0aW9uIHZhbHVlX3VubGVzc19udW1lcmljX3N0cmluZ190aGVuX251bWVyaWNfdmFsdWUodmFsKSB7XG4gICAgLy8gSWYgaXQncyBhbHJlYWR5IGEgbnVtYmVyLCByZXR1cm4gaXRcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCdzIGEgc3RyaW5nIGFuZCBudW1lcmljLCBjb252ZXJ0IGl0XG4gICAgaWYgKGlzX3N0cmluZyh2YWwpICYmIGlzX251bWVyaWModmFsKSkge1xuICAgICAgICAvLyBVc2UgcGFyc2VGbG9hdCB0byBoYW5kbGUgYm90aCBpbnRlZ2VycyBhbmQgZmxvYXRzXG4gICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbCk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGV2ZXJ5dGhpbmcgZWxzZSB1bmNoYW5nZWQgKG51bGwsIG9iamVjdHMsIG5vbi1udW1lcmljIHN0cmluZ3MsIGV0Yy4pXG4gICAgcmV0dXJuIHZhbDtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gU1RSSU5HIE1BTklQVUxBVElPTiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBFc2NhcGVzIEhUTUwgc3BlY2lhbCBjaGFyYWN0ZXJzICh1c2VzIExvZGFzaCBlc2NhcGUpXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIGVzY2FwZVxuICogQHJldHVybnMge3N0cmluZ30gSFRNTC1lc2NhcGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBodG1sKHN0cikge1xuICAgIHJldHVybiBfLmVzY2FwZShzdHIpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIG5ld2xpbmVzIHRvIEhUTUwgbGluZSBicmVha3NcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHdpdGggbmV3bGluZXMgcmVwbGFjZWQgYnkgPGJyIC8+XG4gKi9cbmZ1bmN0aW9uIG5sMmJyKHN0cikge1xuICAgIGlmICh0eXBlb2Ygc3RyID09PSB1bmRlZiB8fCBzdHIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gKHN0ciArICcnKS5yZXBsYWNlKC8oW14+XFxyXFxuXT8pKFxcclxcbnxcXG5cXHJ8XFxyfFxcbikvZywgJyQxPGJyIC8+JDInKTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIEhUTUwgYW5kIGNvbnZlcnRzIG5ld2xpbmVzIHRvIDxiciAvPlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byBwcm9jZXNzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIVE1MLWVzY2FwZWQgc3RyaW5nIHdpdGggbGluZSBicmVha3NcbiAqL1xuZnVuY3Rpb24gaHRtbGJyKHN0cikge1xuICAgIHJldHVybiBubDJicihodG1sKHN0cikpO1xufVxuXG4vKipcbiAqIFVSTC1lbmNvZGVzIGEgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybnMge3N0cmluZ30gVVJMLWVuY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHVybGVuY29kZShzdHIpIHtcbiAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cik7XG59XG5cbi8qKlxuICogVVJMLWRlY29kZXMgYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVUkwtZGVjb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gdXJsZGVjb2RlKHN0cikge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyKTtcbn1cblxuLyoqXG4gKiBKU09OLWVuY29kZXMgYSB2YWx1ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIFZhbHVlIHRvIGVuY29kZVxuICogQHJldHVybnMge3N0cmluZ30gSlNPTiBzdHJpbmdcbiAqL1xuZnVuY3Rpb24ganNvbl9lbmNvZGUodmFsdWUpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xufVxuXG4vKipcbiAqIEpTT04tZGVjb2RlcyBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIEpTT04gc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybnMgeyp9IERlY29kZWQgdmFsdWVcbiAqL1xuZnVuY3Rpb24ganNvbl9kZWNvZGUoc3RyKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uoc3RyKTtcbn1cblxuLyoqXG4gKiBDb25zb2xlIGRlYnVnIG91dHB1dCB3aXRoIGNoYW5uZWwgZmlsdGVyaW5nXG4gKiBBbGlhcyBmb3IgRGVidWdnZXIuY29uc29sZV9kZWJ1Z1xuICogQHBhcmFtIHtzdHJpbmd9IGNoYW5uZWwgLSBEZWJ1ZyBjaGFubmVsIG5hbWVcbiAqIEBwYXJhbSB7Li4uKn0gdmFsdWVzIC0gVmFsdWVzIHRvIGxvZ1xuICovXG5mdW5jdGlvbiBjb25zb2xlX2RlYnVnKGNoYW5uZWwsIC4uLnZhbHVlcykge1xuICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoY2hhbm5lbCwgLi4udmFsdWVzKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgYSBzdWJzdHJpbmcgaW4gYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgLSBTdHJpbmcgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0ge3N0cmluZ30gc2VhcmNoIC0gU3Vic3RyaW5nIHRvIGZpbmRcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXBsYWNlIC0gUmVwbGFjZW1lbnQgc3Vic3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgd2l0aCBhbGwgb2NjdXJyZW5jZXMgcmVwbGFjZWRcbiAqL1xuZnVuY3Rpb24gcmVwbGFjZV9hbGwoc3RyaW5nLCBzZWFyY2gsIHJlcGxhY2UpIHtcbiAgICBpZiAoIWlzX3N0cmluZyhzdHJpbmcpKSB7XG4gICAgICAgIHN0cmluZyA9IHN0cmluZyArICcnO1xuICAgIH1cbiAgICByZXR1cm4gc3RyaW5nLnNwbGl0KHNlYXJjaCkuam9pbihyZXBsYWNlKTtcbn1cblxuLyoqXG4gKiBDYXBpdGFsaXplcyB0aGUgZmlyc3QgbGV0dGVyIG9mIGVhY2ggd29yZFxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gU3RyaW5nIHRvIGNhcGl0YWxpemVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyB3aXRoIGZpcnN0IGxldHRlciBvZiBlYWNoIHdvcmQgY2FwaXRhbGl6ZWRcbiAqL1xuZnVuY3Rpb24gdWN3b3JkcyhpbnB1dCkge1xuICAgIHJldHVybiBpbnB1dFxuICAgICAgICAuc3BsaXQoJyAnKVxuICAgICAgICAubWFwKCh3b3JkKSA9PiB3b3JkLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgd29yZC5zbGljZSgxKSlcbiAgICAgICAgLmpvaW4oJyAnKTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gT0JKRUNUIEFORCBBUlJBWSBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDb3VudHMgdGhlIG51bWJlciBvZiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdCBvciBlbGVtZW50cyBpbiBhbiBhcnJheVxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IG8gLSBPYmplY3Qgb3IgYXJyYXkgdG8gY291bnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBvd24gcHJvcGVydGllcy9lbGVtZW50c1xuICovXG5mdW5jdGlvbiBjb3VudChvKSB7XG4gICAgbGV0IGMgPSAwO1xuICAgIGZvciAoY29uc3QgayBpbiBvKSB7XG4gICAgICAgIGlmIChvLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICArK2M7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGM7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNoYWxsb3cgY2xvbmUgb2YgYW4gb2JqZWN0LCBhcnJheSwgb3IgZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIC0gVmFsdWUgdG8gY2xvbmVcbiAqIEByZXR1cm5zIHsqfSBDbG9uZWQgdmFsdWVcbiAqL1xuZnVuY3Rpb24gY2xvbmUob2JqKSB7XG4gICAgaWYgKHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGUuX19jbG9uZSA9PSB1bmRlZikge1xuICAgICAgICBGdW5jdGlvbi5wcm90b3R5cGUuX19jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTgzMzU4OC9qYXZhc2NyaXB0LWNsb25lLWEtZnVuY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgbGV0IHRlbXAgPSBmdW5jdGlvbiBjbG9uZWQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoYXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gdGhpcykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcFtrZXldID0gdGhpc1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0ZW1wO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2JqID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG9iai5fX2Nsb25lKCk7XG4gICAgfSBlbHNlIGlmIChvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yID09IEFycmF5KSB7XG4gICAgICAgIHJldHVybiBvYmouc2xpY2UoMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzI4MzYwL2hvdy1kby1pLWNvcnJlY3RseS1jbG9uZS1hLWphdmFzY3JpcHQtb2JqZWN0LzMwMDQyOTQ4IzMwMDQyOTQ4XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBvYmopO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBub24tbnVsbC91bmRlZmluZWQgdmFsdWUgZnJvbSBhcmd1bWVudHNcbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzIC0gVmFsdWVzIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Kn0gRmlyc3Qgbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlLCBvciBudWxsIGlmIG5vbmUgZm91bmRcbiAqL1xuZnVuY3Rpb24gY29hbGVzY2UoKSB7XG4gICAgbGV0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3VtZW50cyk7XG4gICAgbGV0IHJldHVybl92YWwgPSBudWxsO1xuICAgIGFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgIGlmIChyZXR1cm5fdmFsID09PSBudWxsICYmIHR5cGVvZiBhcmcgIT0gdW5kZWYgJiYgYXJnICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm5fdmFsID0gYXJnO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldHVybl92YWw7XG59XG5cbi8qKlxuICogQ29udmVydHMgQ1NWIHN0cmluZyB0byBhcnJheSwgdHJpbW1pbmcgZWFjaCBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyX2NzdiAtIENTViBzdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge0FycmF5PHN0cmluZz59IEFycmF5IG9mIHRyaW1tZWQgdmFsdWVzXG4gKiBAdG9kbyBIYW5kbGUgcXVvdGVkL2VzY2FwZWQgY2hhcmFjdGVyc1xuICovXG5mdW5jdGlvbiBjc3ZfdG9fYXJyYXlfdHJpbShzdHJfY3N2KSB7XG4gICAgY29uc3QgcGFydHMgPSBzdHJfY3N2LnNwbGl0KCcsJyk7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgZm9yZWFjaChwYXJ0cywgKHBhcnQpID0+IHtcbiAgICAgICAgcmV0LnB1c2gocGFydC50cmltKCkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXQ7XG59XG4iLCIvKipcbiAqIFF1aWxsIEVkaXRvciAtIFV0aWxpdHkgRnVuY3Rpb25zXG4gKlxuICogUHJvdmlkZXMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdvcmtpbmcgd2l0aCBRdWlsbCBlZGl0b3IuXG4gKi9cblxuLyoqXG4gKiBFbnN1cmVzIFF1aWxsIGlzIGxvYWRlZCBiZWZvcmUgZXhlY3V0aW5nIGNhbGxiYWNrXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBRdWlsbCBpcyByZWFkeVxuICovXG5mdW5jdGlvbiBxdWlsbF9yZWFkeShjYWxsYmFjaykge1xuICAgIGlmICh0eXBlb2Ygd2luZG93LlF1aWxsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcXVpbGxfcmVhZHkoY2FsbGJhY2spLCA1MCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBNYW5pZmVzdCAtIEphdmFTY3JpcHQgY2xhc3MgcmVnaXN0cnkgYW5kIG1ldGFkYXRhIHN5c3RlbVxuICpcbiAqIFRoaXMgY2xhc3MgbWFpbnRhaW5zIGEgcmVnaXN0cnkgb2YgYWxsIEphdmFTY3JpcHQgY2xhc3NlcyBpbiB0aGUgYnVuZGxlLFxuICogdHJhY2tpbmcgdGhlaXIgbmFtZXMgYW5kIGluaGVyaXRhbmNlIHJlbGF0aW9uc2hpcHMuIEl0IHByb3ZpZGVzIHV0aWxpdGllc1xuICogZm9yIHdvcmtpbmcgd2l0aCBjbGFzcyBoaWVyYXJjaGllcyBhbmQgY2FsbGluZyBpbml0aWFsaXphdGlvbiBtZXRob2RzLlxuICovXG5jbGFzcyBNYW5pZmVzdCB7XG4gICAgLyoqXG4gICAgICogRGVmaW5lIGNsYXNzZXMgaW4gdGhlIG1hbmlmZXN0IChmcmFtZXdvcmsgaW50ZXJuYWwpXG4gICAgICogQHBhcmFtIHtBcnJheX0gaXRlbXMgLSBBcnJheSBvZiBjbGFzcyBkZWZpbml0aW9ucyBbW0NsYXNzLCBcIkNsYXNzTmFtZVwiLCBQYXJlbnRDbGFzcywgZGVjb3JhdG9yc10sIC4uLl1cbiAgICAgKi9cbiAgICBzdGF0aWMgX2RlZmluZShpdGVtcykge1xuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBjbGFzc2VzIG9iamVjdCBpZiBub3QgYWxyZWFkeSBkZWZpbmVkXG4gICAgICAgIGlmICh0eXBlb2YgTWFuaWZlc3QuX2NsYXNzZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBNYW5pZmVzdC5fY2xhc3NlcyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyBlYWNoIGNsYXNzIGRlZmluaXRpb25cbiAgICAgICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgbGV0IGNsYXNzX29iamVjdCA9IGl0ZW1bMF07XG4gICAgICAgICAgICBsZXQgY2xhc3NfbmFtZSA9IGl0ZW1bMV07XG4gICAgICAgICAgICBsZXQgY2xhc3NfZXh0ZW5kcyA9IGl0ZW1bMl0gfHwgbnVsbDtcbiAgICAgICAgICAgIGxldCBkZWNvcmF0b3JzID0gaXRlbVszXSB8fCBudWxsO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgY2xhc3MgaW5mb3JtYXRpb24gKHVzaW5nIG9iamVjdCB0byBhdm9pZCBkdXBsaWNhdGVzKVxuICAgICAgICAgICAgTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV0gPSB7XG4gICAgICAgICAgICAgICAgY2xhc3M6IGNsYXNzX29iamVjdCxcbiAgICAgICAgICAgICAgICBuYW1lOiBjbGFzc19uYW1lLFxuICAgICAgICAgICAgICAgIGV4dGVuZHM6IGNsYXNzX2V4dGVuZHMsXG4gICAgICAgICAgICAgICAgZGVjb3JhdG9yczogZGVjb3JhdG9ycywgIC8vIFN0b3JlIGNvbXBhY3QgZGVjb3JhdG9yIGRhdGFcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIEFkZCBtZXRhZGF0YSB0byB0aGUgY2xhc3Mgb2JqZWN0IGl0c2VsZlxuICAgICAgICAgICAgY2xhc3Nfb2JqZWN0Ll9uYW1lID0gY2xhc3NfbmFtZTtcbiAgICAgICAgICAgIGNsYXNzX29iamVjdC5fZXh0ZW5kcyA9IGNsYXNzX2V4dGVuZHM7XG4gICAgICAgICAgICBjbGFzc19vYmplY3QuX2RlY29yYXRvcnMgPSBkZWNvcmF0b3JzO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBCdWlsZCB0aGUgc3ViY2xhc3MgaW5kZXggYWZ0ZXIgYWxsIGNsYXNzZXMgYXJlIGRlZmluZWRcbiAgICAgICAgTWFuaWZlc3QuX2J1aWxkX3N1YmNsYXNzX2luZGV4KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYW4gaW5kZXggb2Ygc3ViY2xhc3NlcyBmb3IgZWZmaWNpZW50IGxvb2t1cHNcbiAgICAgKiBUaGlzIGNyZWF0ZXMgYSBtYXBwaW5nIHdoZXJlIGVhY2ggY2xhc3MgbmFtZSBwb2ludHMgdG8gYW4gYXJyYXkgb2YgYWxsIGl0cyBzdWJjbGFzc2VzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2J1aWxkX3N1YmNsYXNzX2luZGV4KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBzdWJjbGFzcyBpbmRleFxuICAgICAgICBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXggPSB7fTtcblxuICAgICAgICAvLyBTdGVwIHRocm91Z2ggZWFjaCBjbGFzcyBhbmQgd2FsayB1cCBpdHMgcGFyZW50IGNoYWluXG4gICAgICAgIGZvciAobGV0IGNsYXNzX25hbWUgaW4gTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRfY2xhc3NfbmFtZSA9IGNsYXNzX25hbWU7XG4gICAgICAgICAgICBsZXQgY3VycmVudF9jbGFzc2RhdGEgPSBjbGFzc2RhdGE7XG5cbiAgICAgICAgICAgIC8vIFdhbGsgdXAgdGhlIHBhcmVudCBjaGFpbiB1bnRpbCB3ZSByZWFjaCB0aGUgcm9vdFxuICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnRfY2xhc3NkYXRhKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5kc19uYW1lID0gY3VycmVudF9jbGFzc2RhdGEuZXh0ZW5kcztcblxuICAgICAgICAgICAgICAgIGlmIChleHRlbmRzX25hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgcGFyZW50J3Mgc3ViY2xhc3MgYXJyYXkgaWYgbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGlmICghTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4W2V4dGVuZHNfbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleFtleHRlbmRzX25hbWVdID0gW107XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhpcyBjbGFzcyB0byBpdHMgcGFyZW50J3Mgc3ViY2xhc3MgbGlzdFxuICAgICAgICAgICAgICAgICAgICBpZiAoIU1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleFtleHRlbmRzX25hbWVdLmluY2x1ZGVzKGNsYXNzX25hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXhbZXh0ZW5kc19uYW1lXS5wdXNoKGNsYXNzX25hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTW92ZSB1cCB0byB0aGUgcGFyZW50J3MgbWV0YWRhdGEgKGlmIGl0IGV4aXN0cyBpbiBtYW5pZmVzdClcbiAgICAgICAgICAgICAgICAgICAgaWYgKE1hbmlmZXN0Ll9jbGFzc2VzW2V4dGVuZHNfbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfY2xhc3NkYXRhID0gTWFuaWZlc3QuX2NsYXNzZXNbZXh0ZW5kc19uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcmVudCBub3QgaW4gbWFuaWZlc3QgKGUuZy4sIG5hdGl2ZSBKYXZhU2NyaXB0IGNsYXNzKSwgc3RvcCBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzZGF0YSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBObyBwYXJlbnQsIHdlJ3ZlIHJlYWNoZWQgdGhlIHJvb3RcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudF9jbGFzc2RhdGEgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgY2xhc3NlcyB0aGF0IGV4dGVuZCBhIGdpdmVuIGJhc2UgY2xhc3NcbiAgICAgKiBAcGFyYW0ge0NsYXNzfHN0cmluZ30gYmFzZV9jbGFzcyAtIFRoZSBiYXNlIGNsYXNzIChvYmplY3Qgb3IgbmFtZSBzdHJpbmcpIHRvIGNoZWNrIGZvclxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2Ygb2JqZWN0cyB3aXRoIHtjbGFzc19uYW1lLCBjbGFzc19vYmplY3R9IGZvciBjbGFzc2VzIHRoYXQgZXh0ZW5kIHRoZSBiYXNlIGNsYXNzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9leHRlbmRpbmcoYmFzZV9jbGFzcykge1xuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9jbGFzc2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBjbGFzcyBvYmplY3QgaWYgbmVlZGVkXG4gICAgICAgIGxldCBiYXNlX2NsYXNzX29iamVjdCA9IGJhc2VfY2xhc3M7XG4gICAgICAgIGlmICh0eXBlb2YgYmFzZV9jbGFzcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGJhc2VfY2xhc3Nfb2JqZWN0ID0gTWFuaWZlc3QuZ2V0X2NsYXNzX2J5X25hbWUoYmFzZV9jbGFzcyk7XG4gICAgICAgICAgICBpZiAoIWJhc2VfY2xhc3Nfb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBCYXNlIGNsYXNzIG5vdCBmb3VuZDogJHtiYXNlX2NsYXNzfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGNsYXNzX25hbWUgaW4gTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICAgICAgaWYgKE1hbmlmZXN0LmpzX2lzX3N1YmNsYXNzX29mKGNsYXNzZGF0YS5jbGFzcywgYmFzZV9jbGFzc19vYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NfbmFtZTogY2xhc3NfbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3Nfb2JqZWN0OiBjbGFzc2RhdGEuY2xhc3MsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IGFscGhhYmV0aWNhbGx5IGJ5IGNsYXNzIG5hbWUgdG8gZW5zdXJlIGRldGVybWluaXN0aWMgYmVoYXZpb3IgYW5kIHByZXZlbnQgcmFjZSBjb25kaXRpb24gYnVnc1xuICAgICAgICBjbGFzc2VzLnNvcnQoKGEsIGIpID0+IGEuY2xhc3NfbmFtZS5sb2NhbGVDb21wYXJlKGIuY2xhc3NfbmFtZSkpO1xuXG4gICAgICAgIHJldHVybiBjbGFzc2VzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGEgY2xhc3MgaXMgYSBzdWJjbGFzcyBvZiBhbm90aGVyIGNsYXNzXG4gICAgICogTWF0Y2hlcyBQSFAgTWFuaWZlc3Q6OmpzX2lzX3N1YmNsYXNzX29mKCkgc2lnbmF0dXJlIGFuZCBiZWhhdmlvclxuICAgICAqIEBwYXJhbSB7Q2xhc3N8c3RyaW5nfSBzdWJjbGFzcyAtIFRoZSBjaGlsZCBjbGFzcyAob2JqZWN0IG9yIG5hbWUpIHRvIGNoZWNrXG4gICAgICogQHBhcmFtIHtDbGFzc3xzdHJpbmd9IHN1cGVyY2xhc3MgLSBUaGUgcGFyZW50IGNsYXNzIChvYmplY3Qgb3IgbmFtZSkgdG8gY2hlY2sgYWdhaW5zdFxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHN1YmNsYXNzIGV4dGVuZHMgc3VwZXJjbGFzcyAoZGlyZWN0bHkgb3IgaW5kaXJlY3RseSlcbiAgICAgKi9cbiAgICBzdGF0aWMganNfaXNfc3ViY2xhc3Nfb2Yoc3ViY2xhc3MsIHN1cGVyY2xhc3MpIHtcbiAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgbmFtZXMgdG8gY2xhc3Mgb2JqZWN0c1xuICAgICAgICBsZXQgc3ViY2xhc3Nfb2JqZWN0ID0gc3ViY2xhc3M7XG4gICAgICAgIGlmICh0eXBlb2Ygc3ViY2xhc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBzdWJjbGFzc19vYmplY3QgPSBNYW5pZmVzdC5nZXRfY2xhc3NfYnlfbmFtZShzdWJjbGFzcyk7XG4gICAgICAgICAgICBpZiAoIXN1YmNsYXNzX29iamVjdCkge1xuICAgICAgICAgICAgICAgIC8vIENhbid0IHJlc29sdmUgc3ViY2xhc3MgLSByZXR1cm4gZmFsc2UgcGVyIHNwZWNcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3VwZXJjbGFzc19vYmplY3QgPSBzdXBlcmNsYXNzO1xuICAgICAgICBpZiAodHlwZW9mIHN1cGVyY2xhc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBzdXBlcmNsYXNzX29iamVjdCA9IE1hbmlmZXN0LmdldF9jbGFzc19ieV9uYW1lKHN1cGVyY2xhc3MpO1xuICAgICAgICAgICAgaWYgKCFzdXBlcmNsYXNzX29iamVjdCkge1xuICAgICAgICAgICAgICAgIC8vIENhbid0IHJlc29sdmUgc3VwZXJjbGFzcyAtIGZhaWwgbG91ZCBwZXIgc3BlY1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3VwZXJjbGFzcyBub3QgZm91bmQgaW4gbWFuaWZlc3Q6ICR7c3VwZXJjbGFzc31gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENsYXNzZXMgYXJlIG5vdCBzdWJjbGFzc2VzIG9mIHRoZW1zZWx2ZXNcbiAgICAgICAgaWYgKHN1YmNsYXNzX29iamVjdCA9PT0gc3VwZXJjbGFzc19vYmplY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhbGsgdXAgdGhlIGluaGVyaXRhbmNlIGNoYWluXG4gICAgICAgIGxldCBjdXJyZW50X2NsYXNzID0gc3ViY2xhc3Nfb2JqZWN0O1xuICAgICAgICB3aGlsZSAoY3VycmVudF9jbGFzcykge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRfY2xhc3MgPT09IHN1cGVyY2xhc3Nfb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBNb3ZlIHVwIHRvIHBhcmVudCBjbGFzc1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRfY2xhc3MuX2V4dGVuZHMpIHtcbiAgICAgICAgICAgICAgICAvLyBfZXh0ZW5kcyBtYXkgYmUgYSBzdHJpbmcgb3IgY2xhc3MgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50X2NsYXNzLl9leHRlbmRzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzID0gTWFuaWZlc3QuZ2V0X2NsYXNzX2J5X25hbWUoY3VycmVudF9jbGFzcy5fZXh0ZW5kcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudF9jbGFzcyA9IGN1cnJlbnRfY2xhc3MuX2V4dGVuZHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYSBjbGFzcyBieSBpdHMgbmFtZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc19uYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGNsYXNzXG4gICAgICogQHJldHVybnMge0NsYXNzfG51bGx9IFRoZSBjbGFzcyBvYmplY3Qgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2NsYXNzX2J5X25hbWUoY2xhc3NfbmFtZSkge1xuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9jbGFzc2VzIHx8ICFNYW5pZmVzdC5fY2xhc3Nlc1tjbGFzc19uYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV0uY2xhc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGFsbCByZWdpc3RlcmVkIGNsYXNzZXNcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIG9iamVjdHMgd2l0aCB7Y2xhc3NfbmFtZSwgY2xhc3Nfb2JqZWN0LCBleHRlbmRzfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfYWxsX2NsYXNzZXMoKSB7XG4gICAgICAgIGlmICghTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgY2xhc3NfbmFtZSBpbiBNYW5pZmVzdC5fY2xhc3Nlcykge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NkYXRhID0gTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV07XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICAgIGNsYXNzX25hbWU6IGNsYXNzZGF0YS5uYW1lLFxuICAgICAgICAgICAgICAgIGNsYXNzX29iamVjdDogY2xhc3NkYXRhLmNsYXNzLFxuICAgICAgICAgICAgICAgIGV4dGVuZHM6IGNsYXNzZGF0YS5leHRlbmRzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IGFscGhhYmV0aWNhbGx5IGJ5IGNsYXNzIG5hbWUgdG8gZW5zdXJlIGRldGVybWluaXN0aWMgYmVoYXZpb3IgYW5kIHByZXZlbnQgcmFjZSBjb25kaXRpb24gYnVnc1xuICAgICAgICByZXN1bHRzLnNvcnQoKGEsIGIpID0+IGEuY2xhc3NfbmFtZS5sb2NhbGVDb21wYXJlKGIuY2xhc3NfbmFtZSkpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVpbGQga2V5IGZyb20gdGhlIGFwcGxpY2F0aW9uIGNvbmZpZ3VyYXRpb25cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYnVpbGQga2V5IG9yIFwiTk9CVUlMRFwiIGlmIG5vdCBhdmFpbGFibGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYnVpbGRfa2V5KCkge1xuICAgICAgICBpZiAod2luZG93LnJzeGFwcCAmJiB3aW5kb3cucnN4YXBwLmJ1aWxkX2tleSkge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5yc3hhcHAuYnVpbGRfa2V5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnTk9CVUlMRCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGRlY29yYXRvcnMgZm9yIGEgc3BlY2lmaWMgY2xhc3MgYW5kIG1ldGhvZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfENsYXNzfSBjbGFzc19uYW1lIC0gVGhlIGNsYXNzIG5hbWUgb3IgY2xhc3Mgb2JqZWN0XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZF9uYW1lIC0gVGhlIG1ldGhvZCBuYW1lXG4gICAgICogQHJldHVybnMge0FycmF5fG51bGx9IEFycmF5IG9mIGRlY29yYXRvciBvYmplY3RzIG9yIG51bGwgaWYgbm9uZSBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfZGVjb3JhdG9ycyhjbGFzc19uYW1lLCBtZXRob2RfbmFtZSkge1xuICAgICAgICAvLyBDb252ZXJ0IGNsYXNzIG9iamVjdCB0byBuYW1lIGlmIG5lZWRlZFxuICAgICAgICBpZiAodHlwZW9mIGNsYXNzX25hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjbGFzc19uYW1lID0gY2xhc3NfbmFtZS5fbmFtZSB8fCBjbGFzc19uYW1lLm5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbGFzc19pbmZvID0gTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV07XG4gICAgICAgIGlmICghY2xhc3NfaW5mbyB8fCAhY2xhc3NfaW5mby5kZWNvcmF0b3JzIHx8ICFjbGFzc19pbmZvLmRlY29yYXRvcnNbbWV0aG9kX25hbWVdKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYW5zZm9ybSBjb21wYWN0IGZvcm1hdCB0byBvYmplY3QgZm9ybWF0XG4gICAgICAgIHJldHVybiBNYW5pZmVzdC5fdHJhbnNmb3JtX2RlY29yYXRvcnMoY2xhc3NfaW5mby5kZWNvcmF0b3JzW21ldGhvZF9uYW1lXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBtZXRob2RzIHdpdGggZGVjb3JhdG9ycyBmb3IgYSBjbGFzc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfENsYXNzfSBjbGFzc19uYW1lIC0gVGhlIGNsYXNzIG5hbWUgb3IgY2xhc3Mgb2JqZWN0XG4gICAgICogQHJldHVybnMge09iamVjdH0gT2JqZWN0IHdpdGggbWV0aG9kIG5hbWVzIGFzIGtleXMgYW5kIGRlY29yYXRvciBhcnJheXMgYXMgdmFsdWVzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9hbGxfZGVjb3JhdG9ycyhjbGFzc19uYW1lKSB7XG4gICAgICAgIC8vIENvbnZlcnQgY2xhc3Mgb2JqZWN0IHRvIG5hbWUgaWYgbmVlZGVkXG4gICAgICAgIGlmICh0eXBlb2YgY2xhc3NfbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNsYXNzX25hbWUgPSBjbGFzc19uYW1lLl9uYW1lIHx8IGNsYXNzX25hbWUubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzX2luZm8gPSBNYW5pZmVzdC5fY2xhc3Nlc1tjbGFzc19uYW1lXTtcbiAgICAgICAgaWYgKCFjbGFzc19pbmZvIHx8ICFjbGFzc19pbmZvLmRlY29yYXRvcnMpIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYW5zZm9ybSBhbGwgZGVjb3JhdG9ycyBmcm9tIGNvbXBhY3QgdG8gb2JqZWN0IGZvcm1hdFxuICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgbWV0aG9kX25hbWUgaW4gY2xhc3NfaW5mby5kZWNvcmF0b3JzKSB7XG4gICAgICAgICAgICByZXN1bHRbbWV0aG9kX25hbWVdID0gTWFuaWZlc3QuX3RyYW5zZm9ybV9kZWNvcmF0b3JzKGNsYXNzX2luZm8uZGVjb3JhdG9yc1ttZXRob2RfbmFtZV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtIGNvbXBhY3QgZGVjb3JhdG9yIGZvcm1hdCB0byBvYmplY3QgZm9ybWF0XG4gICAgICogQHBhcmFtIHtBcnJheX0gY29tcGFjdF9kZWNvcmF0b3JzIC0gQXJyYXkgb2YgW25hbWUsIFthcmdzXV0gdHVwbGVzXG4gICAgICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBkZWNvcmF0b3Igb2JqZWN0cyB3aXRoIG5hbWUgYW5kIGFyZ3VtZW50cyBwcm9wZXJ0aWVzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX3RyYW5zZm9ybV9kZWNvcmF0b3JzKGNvbXBhY3RfZGVjb3JhdG9ycykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29tcGFjdF9kZWNvcmF0b3JzKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBhY3RfZGVjb3JhdG9ycy5tYXAoZGVjb3JhdG9yID0+IHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRlY29yYXRvcikgJiYgZGVjb3JhdG9yLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogZGVjb3JhdG9yWzBdLFxuICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHM6IGRlY29yYXRvclsxXSB8fCBbXVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBIYW5kbGUgbWFsZm9ybWVkIGRlY29yYXRvciBkYXRhXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG5hbWU6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgICBhcmd1bWVudHM6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhIG1ldGhvZCBoYXMgYSBzcGVjaWZpYyBkZWNvcmF0b3JcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDbGFzc30gY2xhc3NfbmFtZSAtIFRoZSBjbGFzcyBuYW1lIG9yIGNsYXNzIG9iamVjdFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2RfbmFtZSAtIFRoZSBtZXRob2QgbmFtZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkZWNvcmF0b3JfbmFtZSAtIFRoZSBkZWNvcmF0b3IgbmFtZSB0byBjaGVjayBmb3JcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWV0aG9kIGhhcyB0aGUgZGVjb3JhdG9yXG4gICAgICovXG4gICAgc3RhdGljIGhhc19kZWNvcmF0b3IoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUsIGRlY29yYXRvcl9uYW1lKSB7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBNYW5pZmVzdC5nZXRfZGVjb3JhdG9ycyhjbGFzc19uYW1lLCBtZXRob2RfbmFtZSk7XG4gICAgICAgIGlmICghZGVjb3JhdG9ycykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRlY29yYXRvcnMuc29tZShkID0+IGQubmFtZSA9PT0gZGVjb3JhdG9yX25hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgc3ViY2xhc3NlcyBvZiBhIGdpdmVuIGNsYXNzIHVzaW5nIHRoZSBwcmUtYnVpbHQgaW5kZXhcbiAgICAgKiBUaGlzIGlzIHRoZSBKYXZhU2NyaXB0IGVxdWl2YWxlbnQgb2YgUEhQJ3MgTWFuaWZlc3Q6OmpzX2dldF9zdWJjbGFzc2VzX29mKClcbiAgICAgKiBAcGFyYW0ge0NsYXNzfHN0cmluZ30gYmFzZV9jbGFzcyAtIFRoZSBiYXNlIGNsYXNzIChvYmplY3Qgb3IgbmFtZSBzdHJpbmcpIHRvIGdldCBzdWJjbGFzc2VzIG9mXG4gICAgICogQHJldHVybnMge0FycmF5PENsYXNzPn0gQXJyYXkgb2YgYWN0dWFsIGNsYXNzIG9iamVjdHMgdGhhdCBhcmUgc3ViY2xhc3NlcyBvZiB0aGUgYmFzZSBjbGFzc1xuICAgICAqL1xuICAgIHN0YXRpYyBqc19nZXRfc3ViY2xhc3Nlc19vZihiYXNlX2NsYXNzKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgaW5kZXggaWYgbmVlZGVkXG4gICAgICAgIGlmICghTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4KSB7XG4gICAgICAgICAgICBNYW5pZmVzdC5fYnVpbGRfc3ViY2xhc3NfaW5kZXgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnZlcnQgY2xhc3Mgb2JqZWN0IHRvIG5hbWUgaWYgbmVlZGVkXG4gICAgICAgIGxldCBiYXNlX2NsYXNzX25hbWUgPSBiYXNlX2NsYXNzO1xuICAgICAgICBpZiAodHlwZW9mIGJhc2VfY2xhc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBiYXNlX2NsYXNzX25hbWUgPSBiYXNlX2NsYXNzLl9uYW1lIHx8IGJhc2VfY2xhc3MubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBiYXNlIGNsYXNzIGV4aXN0c1xuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9jbGFzc2VzW2Jhc2VfY2xhc3NfbmFtZV0pIHtcbiAgICAgICAgICAgIC8vIEJhc2UgY2xhc3Mgbm90IGluIG1hbmlmZXN0IC0gcmV0dXJuIGVtcHR5IGFycmF5XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgc3ViY2xhc3MgbmFtZXMgZnJvbSB0aGUgaW5kZXhcbiAgICAgICAgY29uc3Qgc3ViY2xhc3NfbmFtZXMgPSBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXhbYmFzZV9jbGFzc19uYW1lXSB8fCBbXTtcblxuICAgICAgICAvLyBDb252ZXJ0IG5hbWVzIHRvIGFjdHVhbCBjbGFzcyBvYmplY3RzXG4gICAgICAgIGNvbnN0IHN1YmNsYXNzX29iamVjdHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc3ViY2xhc3NfbmFtZSBvZiBzdWJjbGFzc19uYW1lcykge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NkYXRhID0gTWFuaWZlc3QuX2NsYXNzZXNbc3ViY2xhc3NfbmFtZV07XG4gICAgICAgICAgICBzdWJjbGFzc19vYmplY3RzLnB1c2goY2xhc3NkYXRhLmNsYXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNvcnQgYnkgY2xhc3MgbmFtZSBmb3IgZGV0ZXJtaW5pc3RpYyBiZWhhdmlvclxuICAgICAgICBzdWJjbGFzc19vYmplY3RzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5hbWVfYSA9IGEuX25hbWUgfHwgYS5uYW1lO1xuICAgICAgICAgICAgY29uc3QgbmFtZV9iID0gYi5fbmFtZSB8fCBiLm5hbWU7XG4gICAgICAgICAgICByZXR1cm4gbmFtZV9hLmxvY2FsZUNvbXBhcmUobmFtZV9iKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN1YmNsYXNzX29iamVjdHM7XG4gICAgfVxufVxuXG4vLyBSU1ggbWFuaWZlc3QgYXV0b21hdGljYWxseSBtYWtlcyBjbGFzc2VzIGdsb2JhbCAtIG5vIG1hbnVhbCBhc3NpZ25tZW50IG5lZWRlZFxuIiwiLyoqXG4gKiBSc3hfQmVoYXZpb3JzIC0gQ29yZSBGcmFtZXdvcmsgVXNlciBFeHBlcmllbmNlIEVuaGFuY2VtZW50c1xuICpcbiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYXV0b21hdGljIHF1YWxpdHktb2YtbGlmZSBiZWhhdmlvcnMgdGhhdCBpbXByb3ZlIHRoZSBkZWZhdWx0XG4gKiBicm93c2VyIGV4cGVyaWVuY2UgZm9yIFJTWCBhcHBsaWNhdGlvbnMuIFRoZXNlIGJlaGF2aW9ycyBhcmUgdHJhbnNwYXJlbnQgdG9cbiAqIGFwcGxpY2F0aW9uIGRldmVsb3BlcnMgYW5kIHJ1biBhdXRvbWF0aWNhbGx5IG9uIGZyYW1ld29yayBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBUaGVzZSBiZWhhdmlvcnMgdXNlIGpRdWVyeSBldmVudCBkZWxlZ2F0aW9uIHRvIGhhbmRsZSBib3RoIGV4aXN0aW5nIGFuZCBkeW5hbWljYWxseVxuICogYWRkZWQgY29udGVudC4gVGhleSBhcmUgaW1wbGVtZW50ZWQgd2l0aCBsb3cgcHJpb3JpdHkgdG8gYWxsb3cgYXBwbGljYXRpb24gY29kZSB0b1xuICogb3ZlcnJpZGUgZGVmYXVsdCBiZWhhdmlvcnMgd2hlbiBuZWVkZWQuXG4gKlxuICogQGludGVybmFsIEZyYW1ld29yayB1c2Ugb25seSAtIG5vdCBwYXJ0IG9mIHB1YmxpYyBBUElcbiAqL1xuY2xhc3MgUnN4X0JlaGF2aW9ycyB7XG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfY29yZV9pbml0KCkge1xuICAgICAgICBSc3hfQmVoYXZpb3JzLl9pbml0X2lnbm9yZV9pbnZhbGlkX2FuY2hvcl9saW5rcygpO1xuICAgICAgICBSc3hfQmVoYXZpb3JzLl90cmltX2NvcGllZF90ZXh0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogLSBBbmNob3IgbGluayBoYW5kbGluZzogUHJldmVudHMgYnJva2VuIFwiI1wiIGxpbmtzIGZyb20gY2F1c2luZyBwYWdlIGp1bXBzIG9yIFVSTCBjaGFuZ2VzXG4gICAgICogLSBJZ25vcmVzIFwiI1wiIChlbXB0eSBoYXNoKSB0byBwcmV2ZW50IHNjcm9sbC10by10b3AgYmVoYXZpb3JcbiAgICAgKiAtIElnbm9yZXMgXCIjcGxhY2Vob2xkZXIqXCIgbGlua3MgdXNlZCBhcyByb3V0ZSBwbGFjZWhvbGRlcnMgZHVyaW5nIGRldmVsb3BtZW50XG4gICAgICogLSBWYWxpZGF0ZXMgYW5jaG9yIHRhcmdldHMgZXhpc3QgYmVmb3JlIGFsbG93aW5nIG5hdmlnYXRpb25cbiAgICAgKiAtIFByZXNlcnZlcyBub3JtYWwgYW5jaG9yIGJlaGF2aW9yIHdoZW4gdGFyZ2V0cyBleGlzdFxuICAgICAqL1xuICAgIHN0YXRpYyBfaW5pdF9pZ25vcmVfaW52YWxpZF9hbmNob3JfbGlua3MoKSB7XG4gICAgICAgIHJldHVybjsgLy8gZGlzYWJsZWQgZm9yIG5vdyAtIG1ha2UgdGhpcyBpbnRvIGEgY29uZmlndXJhYmxlIG9wdGlvblxuXG4gICAgICAgIC8vIFVzZSBldmVudCBkZWxlZ2F0aW9uIG9uIGRvY3VtZW50IHRvIGhhbmRsZSBhbGwgY3VycmVudCBhbmQgZnV0dXJlIGFuY2hvciBjbGlja3NcbiAgICAgICAgLy8gVXNlIG1vdXNlZG93biBpbnN0ZWFkIG9mIGNsaWNrIHRvIHJ1biBiZWZvcmUgbW9zdCBhcHBsaWNhdGlvbiBoYW5kbGVyc1xuICAgICAgICAkKGRvY3VtZW50KS5vbignbW91c2Vkb3duJywgJ2FbaHJlZl49XCIjXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaW5rID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IGhyZWYgPSAkbGluay5hdHRyKCdocmVmJyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGFub3RoZXIgaGFuZGxlciBoYXMgYWxyZWFkeSBwcmV2ZW50ZWQgZGVmYXVsdFxuICAgICAgICAgICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFsbG93IGRhdGEtcnN4LWFsbG93LWhhc2ggYXR0cmlidXRlIHRvIGJ5cGFzcyB0aGlzIGJlaGF2aW9yXG4gICAgICAgICAgICBpZiAoJGxpbmsuZGF0YSgncnN4LWFsbG93LWhhc2gnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSGFuZGxlIGVtcHR5IGhhc2ggLSBwcmV2ZW50IHNjcm9sbCB0byB0b3BcbiAgICAgICAgICAgIGlmIChocmVmID09PSAnIycpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBwbGFjZWhvbGRlciBsaW5rcyB1c2VkIGR1cmluZyBkZXZlbG9wbWVudFxuICAgICAgICAgICAgaWYgKGhyZWYuc3RhcnRzV2l0aCgnI3BsYWNlaG9sZGVyJykpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEZvciBvdGhlciBoYXNoIGxpbmtzLCBjaGVjayBpZiB0YXJnZXQgZXhpc3RzXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRJZCA9IGhyZWYuc3Vic3RyaW5nKDEpO1xuICAgICAgICAgICAgaWYgKHRhcmdldElkKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGVsZW1lbnQgd2l0aCBtYXRjaGluZyBJRCBvciBuYW1lIGF0dHJpYnV0ZVxuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldEV4aXN0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldElkKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbbmFtZT1cIiR7dGFyZ2V0SWR9XCJdYCkgIT09IG51bGw7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldEV4aXN0cykge1xuICAgICAgICAgICAgICAgICAgICAvLyBUYXJnZXQgZG9lc24ndCBleGlzdCAtIHByZXZlbnQgbmF2aWdhdGlvblxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gVGFyZ2V0IGV4aXN0cyAtIGFsbG93IG5vcm1hbCBhbmNob3IgYmVoYXZpb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogLSBDb3B5IHRleHQgdHJpbW1pbmc6IEF1dG9tYXRpY2FsbHkgcmVtb3ZlcyBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBjb3BpZWQgdGV4dFxuICAgICAqIC0gSG9sZCBTaGlmdCB0byBwcmVzZXJ2ZSB3aGl0ZXNwYWNlXG4gICAgICogLSBTa2lwcyB0cmltbWluZyBpbiBjb2RlIGJsb2NrcywgdGV4dGFyZWFzLCBhbmQgY29udGVudGVkaXRhYmxlIGVsZW1lbnRzXG4gICAgICovXG4gICAgc3RhdGljIF90cmltX2NvcGllZF90ZXh0KCkge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjb3B5JywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAvLyBEb24ndCB0cmltIGlmIHVzZXIgaXMgaG9sZGluZyBTaGlmdCAoYWxsb3dzIGNvcHlpbmcgd2l0aCB3aGl0ZXNwYWNlIGlmIG5lZWRlZClcbiAgICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSkgcmV0dXJuO1xuXG4gICAgICAgICAgICBsZXQgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgICAgICAgICAgbGV0IHNlbGVjdGVkX3RleHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcblxuICAgICAgICAgICAgLy8gRG9uJ3QgdHJpbSBpZiBzZWxlY3Rpb24gaXMgZW1wdHlcbiAgICAgICAgICAgIGlmICghc2VsZWN0ZWRfdGV4dCkgcmV0dXJuO1xuXG4gICAgICAgICAgICAvLyBEb24ndCB0cmltIGlmIGNvcHlpbmcgZnJvbSBjb2RlIGJsb2NrcywgdGV4dGFyZWFzLCBvciBjb250ZW50LWVkaXRhYmxlIChwcmVzZXJ2ZSBmb3JtYXR0aW5nKVxuICAgICAgICAgICAgbGV0IGNvbnRhaW5lciA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xuICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gMykgY29udGFpbmVyID0gY29udGFpbmVyLnBhcmVudE5vZGU7IC8vIFRleHQgbm9kZSB0byBlbGVtZW50XG4gICAgICAgICAgICBpZiAoY29udGFpbmVyLmNsb3Nlc3QoJ3ByZSwgY29kZSwgLmNvZGUtYmxvY2ssIHRleHRhcmVhLCBbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpKSByZXR1cm47XG5cbiAgICAgICAgICAgIGxldCB0cmltbWVkX3RleHQgPSBzZWxlY3RlZF90ZXh0LnRyaW0oKTtcblxuICAgICAgICAgICAgLy8gT25seSBtb2RpZnkgaWYgdGhlcmUncyBhY3R1YWxseSB3aGl0ZXNwYWNlIHRvIHRyaW1cbiAgICAgICAgICAgIGlmICh0cmltbWVkX3RleHQgIT09IHNlbGVjdGVkX3RleHQgJiYgdHJpbW1lZF90ZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGV2ZW50LmNsaXBib2FyZERhdGEuc2V0RGF0YSgndGV4dC9wbGFpbicsIHRyaW1tZWRfdGV4dCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0NvcHk6IHRyaW1tZWQgd2hpdGVzcGFjZSBmcm9tIHNlbGVjdGlvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvLyBTaW1wbGUga2V5IHZhbHVlIGNhY2hlLiAgQ2FuIG9ubHkgc3RvcmUgNTAwMCBlbnRyaWVzLCB3aWxsIHJlc2V0IGFmdGVyIDUwMDAgZW50cmllcy5cblxuLy8gVG9kbzoga2VlcCBsb2NhbCBjYWNoZSBjb25jZXB0IHRoZSBzYW1lLCByZXBsYWNlIGdsb2JhbCBjYWNoZSBjb25jZXB0IHdpdGggdGhlIG5vdiAyMDE5IHZlcnNpb24gb2Zcbi8vIHNlc3Npb24gY2FjaGUuICBVc2UgYSBzZXNzaW9uIGtleSAmIGJ1aWxkIGtleSB0byB0cmFjayBjYWNoZSBrZXlzIHNvIGNhY2hlZCB2YWx1ZXMgb25seSBsYXN0IHVudGlsIHVzZXIgbG9ncyBvdXQuXG4vLyByZXZpZXcgc2Vzc2lvbiBjb2RlIHRvIGVuc3VyZSB0aGF0IHNlc3Npb24ga2V5ICphbHdheXMqIHJvdGF0ZXMgb24gbG9nb3V0LiAgTWFrZSBzZXNzaW9uIGlkIGEgcHJvdGVjdGVkIHZhbHVlLlxuY2xhc3MgUnN4X0NhY2hlIHtcbiAgICBzdGF0aWMgb25fY29yZV9kZWZpbmUoKSB7XG4gICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlcyA9IHtcbiAgICAgICAgICAgIGdsb2JhbDoge30sXG4gICAgICAgICAgICBpbnN0YW5jZToge30sXG4gICAgICAgIH07XG5cbiAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzX3NldCA9IDA7XG4gICAgfVxuXG4gICAgLy8gQWxpYXMgZm9yIGdldF9pbnN0YW5jZVxuICAgIHN0YXRpYyBnZXQoa2V5KSB7XG4gICAgICAgIHJldHVybiBSc3hfQ2FjaGUuZ2V0X2luc3RhbmNlKGtleSk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyBmcm9tIHRoZSBwb29sIG9mIGNhY2hlZCBkYXRhIGZvciB0aGlzICdpbnN0YW5jZScuICBBbiBpbnN0YW5jZVxuICAgIC8vIGluIHRoaXMgY2FzZSBpcyBhIHZpcnR1YWwgcGFnZSBsb2FkIC8gbmF2aWdhdGlvbiBpbiB0aGUgU1BBLiAgQ2FsbCBNYWluLmxpYi5yZXNldCgpIHRvIHJlc2V0LlxuICAgIC8vIFJldHVybnMgbnVsbCBvbiBmYWlsdXJlXG4gICAgc3RhdGljIGdldF9pbnN0YW5jZShrZXkpIHtcbiAgICAgICAgaWYgKE1haW4uZGVidWcoJ25vX2FwaV9jYWNoZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBrZXlfZW5jb2RlZCA9IFJzeF9DYWNoZS5fZW5jb2Rla2V5KGtleSk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBDb3JlX0NhY2hlLl9jYWNoZXMuaW5zdGFuY2Vba2V5X2VuY29kZWRdICE9IHVuZGVmKSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShDb3JlX0NhY2hlLl9jYWNoZXMuaW5zdGFuY2Vba2V5X2VuY29kZWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgbnVsbCBvbiBmYWlsdXJlXG4gICAgLy8gUmV0dXJucyBhIGNhY2hlZCB2YWx1ZSBmcm9tIGdsb2JhbCBjYWNoZSAodW5pcXVlIHRvIHBhZ2UgbG9hZCwgc3Vydml2ZXMgcmVzZXQoKSlcbiAgICBzdGF0aWMgZ2V0X2dsb2JhbChrZXkpIHtcbiAgICAgICAgaWYgKE1haW4uZGVidWcoJ25vX2FwaV9jYWNoZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBrZXlfZW5jb2RlZCA9IFJzeF9DYWNoZS5fZW5jb2Rla2V5KGtleSk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBDb3JlX0NhY2hlLl9jYWNoZXMuZ2xvYmFsW2tleV9lbmNvZGVkXSAhPSB1bmRlZikge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoQ29yZV9DYWNoZS5fY2FjaGVzLmdsb2JhbFtrZXlfZW5jb2RlZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gU2V0cyBhIHZhbHVlIGluIGluc3RhbmNlIGFuZCBnbG9iYWwgY2FjaGUgKG5vdCBzaGFyZWQgYmV0d2VlbiBicm93c2VyIHRhYnMpXG4gICAgc3RhdGljIHNldChrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChNYWluLmRlYnVnKCdub19hcGlfY2FjaGUnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID4gNjQgKiAxMDI0KSB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdDQUNIRScsICdXYXJuaW5nIC0gbm90IGNhY2hpbmcgbGFyZ2UgY2FjaGUgZW50cnknLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGtleV9lbmNvZGVkID0gUnN4X0NhY2hlLl9lbmNvZGVrZXkoa2V5KTtcblxuICAgICAgICBDb3JlX0NhY2hlLl9jYWNoZXMuZ2xvYmFsW2tleV9lbmNvZGVkXSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzLmluc3RhbmNlW2tleV9lbmNvZGVkXSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcblxuICAgICAgICAvLyBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKFwiQ0FDSEVcIiwgXCJTZXRcIiwga2V5LCB2YWx1ZSk7XG5cbiAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzX3NldCsrO1xuXG4gICAgICAgIC8vIFJlc2V0IGNhY2hlIGFmdGVyIDUwMDAgaXRlbXMgc2V0XG4gICAgICAgIGlmIChDb3JlX0NhY2hlLl9jYWNoZXNfc2V0ID4gNTAwMCkge1xuICAgICAgICAgICAgLy8gR2V0IGFuIGFjY3VyYXRlIGNvdW50XG4gICAgICAgICAgICBDb3JlX0NhY2hlLl9jYWNoZXNfc2V0ID0gY291bnQoQ29yZV9DYWNoZS5fY2FjaGVzLmdsb2JhbCk7XG5cbiAgICAgICAgICAgIGlmIChDb3JlX0NhY2hlLl9jYWNoZXNfc2V0ID4gNTAwMCkge1xuICAgICAgICAgICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgZ2xvYmFsOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2U6IHt9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzX3NldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIG51bGwgb24gZmFpbHVyZVxuICAgIC8vIFJldHVybnMgYSBjYWNoZWQgdmFsdWUgZnJvbSBzZXNzaW9uIGNhY2hlIChzaGFyZWQgYmV0d2VlbiBicm93c2VyIHRhYnMpXG4gICAgc3RhdGljIGdldF9zZXNzaW9uKGtleSkge1xuICAgICAgICBpZiAoTWFpbi5kZWJ1Zygnbm9fYXBpX2NhY2hlJykpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFSc3hfQ2FjaGUuX3N1cHBvcnRzU3RvcmFnZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBrZXlfZW5jb2RlZCA9IFJzeF9DYWNoZS5fZW5jb2Rla2V5KGtleSk7XG5cbiAgICAgICAgbGV0IHJzID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShrZXlfZW5jb2RlZCk7XG5cbiAgICAgICAgaWYgKCFlbXB0eShycykpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gU2V0cyBhIHZhbHVlIGluIHNlc3Npb24gY2FjaGUgKHNoYXJlZCBiZXR3ZWVuIGJyb3dzZXIgdGFicylcbiAgICBzdGF0aWMgc2V0X3Nlc3Npb24oa2V5LCB2YWx1ZSwgX3RyeWFnYWluID0gdHJ1ZSkge1xuICAgICAgICBpZiAoTWFpbi5kZWJ1Zygnbm9fYXBpX2NhY2hlJykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPiA2NCAqIDEwMjQpIHtcbiAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoJ0NBQ0hFJywgJ1dhcm5pbmcgLSBub3QgY2FjaGluZyBsYXJnZSBjYWNoZSBlbnRyeScsIGtleSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIVJzeF9DYWNoZS5fc3VwcG9ydHNTdG9yYWdlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGtleV9lbmNvZGVkID0gUnN4X0NhY2hlLl9lbmNvZGVrZXkoa2V5KTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShrZXlfZW5jb2RlZCk7XG4gICAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGtleV9lbmNvZGVkLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoUnN4X0NhY2hlLl9pc091dE9mU3BhY2UoZSkgJiYgc2Vzc2lvblN0b3JhZ2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICBpZiAoX3RyeWFnYWluKSB7XG4gICAgICAgICAgICAgICAgICAgIENvcmVfQ2FjaGUuc2V0X3Nlc3Npb24oa2V5LCB2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBfcmVzZXQoKSB7XG4gICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlcy5pbnN0YW5jZSA9IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciBnaXZlbiBrZXkgb2YgYW55IHR5cGUgaW5jbHVkaW5nIGFuIG9iamVjdCwgcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZ1xuICAgICAqIHRoZSBrZXkgdGhhdCB0aGUgY2FjaGVkIHZhbHVlIHNob3VsZCBiZSBzdG9yZWQgYXMgaW4gc2Vzc2lvbnN0b3JhZ2VcbiAgICAgKi9cbiAgICBzdGF0aWMgX2VuY29kZWtleShrZXkpIHtcbiAgICAgICAgY29uc3QgcHJlZml4ID0gJ2NhY2hlXyc7XG5cbiAgICAgICAgLy8gU2Vzc2lvbiByZWltcGxlbWVudFxuICAgICAgICAvLyB2YXIgcHJlZml4ID0gXCJjYWNoZV9cIiArIFNwYS5zZXNzaW9uKCkudXNlcl9pZCgpICsgXCJfXCI7XG5cbiAgICAgICAgaWYgKGlzX3N0cmluZyhrZXkpICYmIGtleS5sZW5ndGggPCAxNTAgJiYga2V5LmluZGV4T2YoJyAnKSA9PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuIHByZWZpeCArIE1hbmlmZXN0LmJ1aWxkX2tleSgpICsgJ18nICsga2V5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHByZWZpeCArIGhhc2goW01hbmlmZXN0LmJ1aWxkX2tleSgpLCBrZXldKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIERldGVybWluZXMgaWYgc2Vzc2lvblN0b3JhZ2UgaXMgc3VwcG9ydGVkIGluIHRoZSBicm93c2VyO1xuICAgIC8vIHJlc3VsdCBpcyBjYWNoZWQgZm9yIGJldHRlciBwZXJmb3JtYW5jZSBpbnN0ZWFkIG9mIGJlaW5nIHJ1biBlYWNoIHRpbWUuXG4gICAgLy8gRmVhdHVyZSBkZXRlY3Rpb24gaXMgYmFzZWQgb24gaG93IE1vZGVybml6ciBkb2VzIGl0O1xuICAgIC8vIGl0J3Mgbm90IHN0cmFpZ2h0Zm9yd2FyZCBkdWUgdG8gRkY0IGlzc3Vlcy5cbiAgICAvLyBJdCdzIG5vdCBydW4gYXQgcGFyc2UtdGltZSBhcyBpdCB0YWtlcyAyMDBtcyBpbiBBbmRyb2lkLlxuICAgIC8vIENvZGUgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcGFtZWxhZm94L2xzY2FjaGUvYmxvYi9tYXN0ZXIvbHNjYWNoZS5qcywgQXBhY2hlIExpY2Vuc2UgUGFtZWxhZm94XG4gICAgc3RhdGljIF9zdXBwb3J0c1N0b3JhZ2UoKSB7XG4gICAgICAgIGxldCBrZXkgPSAnX19jYWNoZXRlc3RfXyc7XG4gICAgICAgIGxldCB2YWx1ZSA9IGtleTtcblxuICAgICAgICBpZiAoUnN4X0NhY2hlLl9fc3VwcG9ydHNTdG9yYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBSc3hfQ2FjaGUuX19zdXBwb3J0c1N0b3JhZ2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzb21lIGJyb3dzZXJzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgeW91IHRyeSB0byBhY2Nlc3MgbG9jYWwgc3RvcmFnZSAoZS5nLiBicmF2ZSBicm93c2VyKVxuICAgICAgICAvLyBoZW5jZSBjaGVjayBpcyBpbnNpZGUgYSB0cnkvY2F0Y2hcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghc2Vzc2lvblN0b3JhZ2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KTtcbiAgICAgICAgICAgIFJzeF9DYWNoZS5fX3N1cHBvcnRzU3RvcmFnZSA9IHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGhpdCB0aGUgbGltaXQsIGFuZCB3ZSBkb24ndCBoYXZlIGFuIGVtcHR5IHNlc3Npb25TdG9yYWdlIHRoZW4gaXQgbWVhbnMgd2UgaGF2ZSBzdXBwb3J0XG4gICAgICAgICAgICBpZiAoUnN4X0NhY2hlLl9pc091dE9mU3BhY2UoZSkgJiYgc2Vzc2lvblN0b3JhZ2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgUnN4X0NhY2hlLl9fc3VwcG9ydHNTdG9yYWdlID0gdHJ1ZTsgLy8ganVzdCBtYXhlZCBpdCBvdXQgYW5kIGV2ZW4gdGhlIHNldCB0ZXN0IGZhaWxlZC5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgUnN4X0NhY2hlLl9fc3VwcG9ydHNTdG9yYWdlID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUnN4X0NhY2hlLl9fc3VwcG9ydHNTdG9yYWdlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIHRvIHNldCBpZiB0aGUgZXJyb3IgaXMgdXMgZGVhbGluZyB3aXRoIGJlaW5nIG91dCBvZiBzcGFjZVxuICAgIHN0YXRpYyBfaXNPdXRPZlNwYWNlKGUpIHtcbiAgICAgICAgcmV0dXJuIGUgJiYgKGUubmFtZSA9PT0gJ1FVT1RBX0VYQ0VFREVEX0VSUicgfHwgZS5uYW1lID09PSAnTlNfRVJST1JfRE9NX1FVT1RBX1JFQUNIRUQnIHx8IGUubmFtZSA9PT0gJ1F1b3RhRXhjZWVkZWRFcnJvcicpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X0luaXQgLSBDb3JlIGZyYW1ld29yayBpbml0aWFsaXphdGlvbiBhbmQgZW52aXJvbm1lbnQgdmFsaWRhdGlvblxuICovXG5jbGFzcyBSc3hfSW5pdCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHZpYSBSc3guX3JzeF9jb3JlX2Jvb3RcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgY29yZSBlbnZpcm9ubWVudCBhbmQgcnVucyBiYXNpYyBzYW5pdHkgY2hlY2tzXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfY29yZV9pbml0KCkge1xuICAgICAgICBpZiAoIVJzeC5pc19wcm9kKCkpIHtcbiAgICAgICAgICAgIFJzeF9Jbml0Ll9fZW52aXJvbm1lbnRfY2hlY2tzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXZlbG9wbWVudCBlbnZpcm9ubWVudCBjaGVja3MgdG8gZW5zdXJlIHByb3BlciBjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgc3RhdGljIF9fZW52aXJvbm1lbnRfY2hlY2tzKCkge1xuICAgICAgICAvLyBGaW5kIGFsbCBzY3JpcHQgdGFncyBpbiB0aGUgRE9NXG4gICAgICAgIGNvbnN0IHNjcmlwdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzY3JpcHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSBzY3JpcHRzW2ldO1xuXG4gICAgICAgICAgICAvLyBTa2lwIGlubGluZSBzY3JpcHRzIChubyBzcmMgYXR0cmlidXRlKVxuICAgICAgICAgICAgaWYgKCFzY3JpcHQuc3JjKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHNjcmlwdCBoYXMgZGVmZXIgYXR0cmlidXRlXG4gICAgICAgICAgICBpZiAoIXNjcmlwdC5kZWZlcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNyYyA9IHNjcmlwdC5zcmMgfHwgJyhpbmxpbmUgc2NyaXB0KSc7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVhc29uID0gYEFsbCBzY3JpcHQgdGFncyB1c2VkIGluIGFuIFJTcGFkZSBwcm9qZWN0IG11c3QgaGF2ZSBkZWZlciBhdHRyaWJ1dGUuIEZvdW5kIHNjcmlwdCB3aXRob3V0IGRlZmVyOiAke3NyY31gO1xuXG4gICAgICAgICAgICAgICAgLy8gU3RvcCBmcmFtZXdvcmsgYm9vdCB3aXRoIHJlYXNvblxuICAgICAgICAgICAgICAgIFJzeC5fcnN4X2NvcmVfYm9vdF9zdG9wKHJlYXNvbik7XG5cbiAgICAgICAgICAgICAgICAvLyBBbHNvIGxvZyB0byBjb25zb2xlIGZvciB2aXNpYmlsaXR5XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW1JTWCBCT09UIFNUT1BQRURdICR7cmVhc29ufWApO1xuXG4gICAgICAgICAgICAgICAgLy8gU3RvcCBjaGVja2luZyBhZnRlciBmaXJzdCB2aW9sYXRpb25cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59IiwiLy8gQEZJTEUtU1VCQ0xBU1MtMDEtRVhDRVBUSU9OXG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgSmF2YVNjcmlwdCBPUk0gbW9kZWxzXG4gKlxuICogUHJvdmlkZXMgY29yZSBmdW5jdGlvbmFsaXR5IGZvciBmZXRjaGluZyByZWNvcmRzIGZyb20gYmFja2VuZCBQSFAgbW9kZWxzLlxuICogQWxsIG1vZGVsIHN0dWJzIGdlbmVyYXRlZCBieSB0aGUgbWFuaWZlc3QgZXh0ZW5kIHRoaXMgYmFzZSBjbGFzcy5cbiAqXG4gKiBFeGFtcGxlIHVzYWdlOlxuICogICAvLyBGZXRjaCBzaW5nbGUgcmVjb3JkXG4gKiAgIGNvbnN0IHVzZXIgPSBhd2FpdCBVc2VyX01vZGVsLmZldGNoKDEyMyk7XG4gKlxuICogICAvLyBGZXRjaCBtdWx0aXBsZSByZWNvcmRzXG4gKiAgIGNvbnN0IHVzZXJzID0gYXdhaXQgVXNlcl9Nb2RlbC5mZXRjaChbMSwgMiwgM10pO1xuICpcbiAqICAgLy8gQ3JlYXRlIGluc3RhbmNlIHdpdGggZGF0YVxuICogICBjb25zdCB1c2VyID0gbmV3IFVzZXJfTW9kZWwoe2lkOiAxLCBuYW1lOiAnSm9obid9KTtcbiAqXG4gKiAgQEluc3RhbnRpYXRhYmxlXG4gKi9cbmNsYXNzIFJzeF9Kc19Nb2RlbCB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0b3IgLSBJbml0aWFsaXplIG1vZGVsIGluc3RhbmNlIHdpdGggZGF0YVxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgLSBLZXktdmFsdWUgcGFpcnMgdG8gcG9wdWxhdGUgdGhlIG1vZGVsXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZGF0YSA9IHt9KSB7XG4gICAgICAgIC8vIF9fTU9ERUwgU1lTVEVNOiBFbmFibGVzIGF1dG9tYXRpYyBPUk0gaW5zdGFudGlhdGlvbiB3aGVuIGZldGNoaW5nIGZyb20gUEhQIG1vZGVscy5cbiAgICAgICAgLy8gUEhQIG1vZGVscyBhZGQgXCJfX01PREVMXCI6IFwiQ2xhc3NOYW1lXCIgdG8gSlNPTiwgSmF2YVNjcmlwdCB1c2VzIGl0IHRvIGNyZWF0ZSBwcm9wZXIgaW5zdGFuY2VzLlxuICAgICAgICAvLyBUaGlzIHByb3ZpZGVzIHR5cGVkIG1vZGVsIG9iamVjdHMgaW5zdGVhZCBvZiBwbGFpbiBKU09OLCB3aXRoIG1ldGhvZHMgYW5kIHR5cGUgY2hlY2tpbmcuXG5cbiAgICAgICAgLy8gVGhpcyBjb25zdHJ1Y3RvciBmaWx0ZXJzIG91dCB0aGUgX19NT0RFTCBtYXJrZXIgdGhhdCB3YXMgdXNlZCB0byBpZGVudGlmeSB3aGljaCBjbGFzc1xuICAgICAgICAvLyB0byBpbnN0YW50aWF0ZSwga2VlcGluZyBvbmx5IHRoZSBhY3R1YWwgZGF0YSBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZS5cbiAgICAgICAgY29uc3QgeyBfX01PREVMLCAuLi5tb2RlbERhdGEgfSA9IGRhdGE7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgbW9kZWxEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCByZWNvcmQocykgZnJvbSB0aGUgYmFja2VuZCBtb2RlbFxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgbWlycm9ycyB0aGUgUEhQIE1vZGVsOjpmZXRjaCgpIGZ1bmN0aW9uYWxpdHkuXG4gICAgICogVGhlIGJhY2tlbmQgbW9kZWwgbXVzdCBoYXZlIGEgZmV0Y2goKSBtZXRob2Qgd2l0aCB0aGVcbiAgICAgKiAjW0FqYXhfRW5kcG9pbnRfTW9kZWxfRmV0Y2hdIGFubm90YXRpb24gdG8gYmUgY2FsbGFibGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcnxBcnJheX0gaWQgLSBTaW5nbGUgSUQgb3IgYXJyYXkgb2YgSURzIHRvIGZldGNoXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IC0gU2luZ2xlIG1vZGVsIGluc3RhbmNlLCBhcnJheSBvZiBpbnN0YW5jZXMsIG9yIGZhbHNlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGZldGNoKGlkKSB7XG4gICAgICAgIGNvbnN0IEN1cnJlbnRDbGFzcyA9IHRoaXM7XG4gICAgICAgIC8vIEdldCB0aGUgbW9kZWwgY2xhc3MgbmFtZSBmcm9tIHRoZSBjdXJyZW50IGNsYXNzXG4gICAgICAgIGNvbnN0IG1vZGVsTmFtZSA9IEN1cnJlbnRDbGFzcy5uYW1lO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2gvJHttb2RlbE5hbWV9YCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YTogeyBpZDogaWQgfSxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSByZXNwb25zZSBiYXNlZCBvbiB0eXBlXG4gICAgICAgIGlmIChyZXNwb25zZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVzZSBfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSB0byBoYW5kbGUgT1JNIGluc3RhbnRpYXRpb25cbiAgICAgICAgLy8gVGhpcyB3aWxsIGF1dG9tYXRpY2FsbHkgZGV0ZWN0IF9fTU9ERUwgcHJvcGVydGllcyBhbmQgY3JlYXRlIGFwcHJvcHJpYXRlIGluc3RhbmNlc1xuICAgICAgICByZXR1cm4gUnN4X0pzX01vZGVsLl9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKHJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG1vZGVsIGNsYXNzIG5hbWVcbiAgICAgKiBVc2VkIGludGVybmFsbHkgZm9yIEFQSSBjYWxsc1xuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNsYXNzIG5hbWVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0TW9kZWxOYW1lKCkge1xuICAgICAgICBjb25zdCBDdXJyZW50Q2xhc3MgPSB0aGlzO1xuICAgICAgICByZXR1cm4gQ3VycmVudENsYXNzLm5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVmcmVzaCB0aGlzIGluc3RhbmNlIHdpdGggbGF0ZXN0IGRhdGEgZnJvbSBzZXJ2ZXJcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBVcGRhdGVkIGluc3RhbmNlIG9yIGZhbHNlIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIGFzeW5jIHJlZnJlc2goKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBpZiAoIXRoYXQuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IHJlZnJlc2ggbW9kZWwgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZnJlc2ggPSBhd2FpdCB0aGF0LmNvbnN0cnVjdG9yLmZldGNoKHRoYXQuaWQpO1xuXG4gICAgICAgIGlmIChmcmVzaCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSB0aGlzIGluc3RhbmNlIHdpdGggZnJlc2ggZGF0YVxuICAgICAgICBPYmplY3QuYXNzaWduKHRoYXQsIGZyZXNoKTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydCBtb2RlbCBpbnN0YW5jZSB0byBwbGFpbiBvYmplY3RcbiAgICAgKiBVc2VmdWwgZm9yIHNlcmlhbGl6YXRpb24gb3Igc2VuZGluZyB0byBBUElzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBQbGFpbiBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICAgKi9cbiAgICB0b09iamVjdCgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIGNvbnN0IG9iaiA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiB0aGF0KSB7XG4gICAgICAgICAgICBpZiAodGhhdC5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIHR5cGVvZiB0aGF0W2tleV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHRoYXRba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgbW9kZWwgaW5zdGFuY2UgdG8gSlNPTiBzdHJpbmdcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEpTT04gcmVwcmVzZW50YXRpb25cbiAgICAgKi9cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhhdC50b09iamVjdCgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBpbnN0YW50aWF0ZSBPUk0gbW9kZWxzIGluIHJlc3BvbnNlIGRhdGFcbiAgICAgKlxuICAgICAqIExvb2tzIGZvciBvYmplY3RzIHdpdGggX19NT0RFTCBwcm9wZXJ0eSBhbmQgaW5zdGFudGlhdGVzIHRoZSBhcHByb3ByaWF0ZVxuICAgICAqIEphdmFTY3JpcHQgbW9kZWwgY2xhc3MgaWYgaXQgZXhpc3RzIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgLSBUaGUgZGF0YSB0byBwcm9jZXNzIChjYW4gYmUgYW55IHR5cGUpXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBkYXRhIHdpdGggT1JNIG9iamVjdHMgaW5zdGFudGlhdGVkXG4gICAgICovXG4gICAgc3RhdGljIF9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKGRhdGEpIHtcbiAgICAgICAgLy8gX19NT0RFTCBTWVNURU06IEVuYWJsZXMgYXV0b21hdGljIE9STSBpbnN0YW50aWF0aW9uIHdoZW4gZmV0Y2hpbmcgZnJvbSBQSFAgbW9kZWxzLlxuICAgICAgICAvLyBQSFAgbW9kZWxzIGFkZCBcIl9fTU9ERUxcIjogXCJDbGFzc05hbWVcIiB0byBKU09OLCBKYXZhU2NyaXB0IHVzZXMgaXQgdG8gY3JlYXRlIHByb3BlciBpbnN0YW5jZXMuXG4gICAgICAgIC8vIFRoaXMgcHJvdmlkZXMgdHlwZWQgbW9kZWwgb2JqZWN0cyBpbnN0ZWFkIG9mIHBsYWluIEpTT04sIHdpdGggbWV0aG9kcyBhbmQgdHlwZSBjaGVja2luZy5cblxuICAgICAgICAvLyBUaGlzIHJlY3Vyc2l2ZSBwcm9jZXNzb3Igc2NhbnMgYWxsIEFQSSByZXNwb25zZSBkYXRhIGxvb2tpbmcgZm9yIF9fTU9ERUwgbWFya2Vycy5cbiAgICAgICAgLy8gV2hlbiBmb3VuZCwgaXQgYXR0ZW1wdHMgdG8gaW5zdGFudGlhdGUgdGhlIGFwcHJvcHJpYXRlIEphdmFTY3JpcHQgbW9kZWwgY2xhc3MsXG4gICAgICAgIC8vIGNvbnZlcnRpbmcge19fTU9ERUw6IFwiVXNlcl9Nb2RlbFwiLCBpZDogMSwgbmFtZTogXCJKb2huXCJ9IGludG8gbmV3IFVzZXJfTW9kZWwoey4uLn0pLlxuICAgICAgICAvLyBXb3JrcyByZWN1cnNpdmVseSB0aHJvdWdoIGFycmF5cyBhbmQgbmVzdGVkIG9iamVjdHMgdG8gaGFuZGxlIGNvbXBsZXggZGF0YSBzdHJ1Y3R1cmVzLlxuICAgICAgICAvLyBIYW5kbGUgbnVsbC91bmRlZmluZWRcbiAgICAgICAgaWYgKGRhdGEgPT09IG51bGwgfHwgZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBhcnJheXMgLSByZWN1cnNpdmVseSBwcm9jZXNzIGVhY2ggZWxlbWVudFxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGEubWFwKChpdGVtKSA9PiBSc3hfSnNfTW9kZWwuX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUoaXRlbSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIG9iamVjdHNcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBvYmplY3QgaGFzIGEgX19NT0RFTCBwcm9wZXJ0eVxuICAgICAgICAgICAgaWYgKGRhdGEuX19NT0RFTCAmJiB0eXBlb2YgZGF0YS5fX01PREVMID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIC8vIFRyeSB0byBmaW5kIHRoZSBtb2RlbCBjbGFzcyBpbiB0aGUgZ2xvYmFsIHNjb3BlXG4gICAgICAgICAgICAgICAgY29uc3QgTW9kZWxDbGFzcyA9IHdpbmRvd1tkYXRhLl9fTU9ERUxdO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIG1vZGVsIGNsYXNzIGV4aXN0cyBhbmQgZXh0ZW5kcyBSc3hfSnNfTW9kZWwsIGluc3RhbnRpYXRlIGl0XG4gICAgICAgICAgICAgICAgLy8gRHluYW1pYyBtb2RlbCByZXNvbHV0aW9uIHJlcXVpcmVzIGNoZWNraW5nIGNsYXNzIGV4aXN0ZW5jZSAtIEBKUy1ERUZFTlNJVkUtMDEtRVhDRVBUSU9OXG4gICAgICAgICAgICAgICAgaWYgKE1vZGVsQ2xhc3MgJiYgTW9kZWxDbGFzcy5wcm90b3R5cGUgaW5zdGFuY2VvZiBSc3hfSnNfTW9kZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2RlbENsYXNzKGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgcHJvY2VzcyBhbGwgb2JqZWN0IHByb3BlcnRpZXNcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2tleV0gPSBSc3hfSnNfTW9kZWwuX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUoZGF0YVtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmV0dXJuIHByaW1pdGl2ZSB2YWx1ZXMgYXMtaXNcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBWaWV3X1RyYW5zaXRpb25zIC0gU21vb3RoIHBhZ2UtdG8tcGFnZSB0cmFuc2l0aW9ucyB1c2luZyBWaWV3IFRyYW5zaXRpb25zIEFQSVxuICpcbiAqIEVuYWJsZXMgY3Jvc3MtZG9jdW1lbnQgdmlldyB0cmFuc2l0aW9ucyBzbyB0aGUgYnJvd3NlciBkb2Vzbid0IHBhaW50IHRoZSBuZXcgcGFnZVxuICogdW50aWwgaXQncyByZWFkeSwgY3JlYXRpbmcgc21vb3RoIGFuaW1hdGlvbnMgYmV0d2VlbiBwYWdlcy5cbiAqXG4gKiBGYWxscyBiYWNrIGdyYWNlZnVsbHkgaWYgVmlldyBUcmFuc2l0aW9ucyBBUEkgaXMgbm90IGF2YWlsYWJsZS5cbiAqL1xuY2xhc3MgUnN4X1ZpZXdfVHJhbnNpdGlvbnMge1xuICAgIC8qKlxuICAgICAqIENhbGxlZCBkdXJpbmcgZnJhbWV3b3JrIGNvcmUgaW5pdCBwaGFzZVxuICAgICAqIENoZWNrcyBmb3IgVmlldyBUcmFuc2l0aW9ucyBBUEkgc3VwcG9ydCBhbmQgZW5hYmxlcyBpZiBhdmFpbGFibGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2luaXQoKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIFZpZXcgVHJhbnNpdGlvbnMgQVBJIGlzIHN1cHBvcnRlZFxuICAgICAgICBpZiAoIWRvY3VtZW50LnN0YXJ0Vmlld1RyYW5zaXRpb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ1ZJRVdfVFJBTlNJVElPTlMnLCAnVmlldyBUcmFuc2l0aW9ucyBBUEkgbm90IHN1cHBvcnRlZCwgc2tpcHBpbmcnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEVuYWJsZSBjcm9zcy1kb2N1bWVudCB2aWV3IHRyYW5zaXRpb25zIHZpYSBDU1NcbiAgICAgICAgUnN4X1ZpZXdfVHJhbnNpdGlvbnMuX2luamVjdF90cmFuc2l0aW9uX2NzcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluamVjdCBDU1MgdG8gZW5hYmxlIGNyb3NzLWRvY3VtZW50IHZpZXcgdHJhbnNpdGlvbnNcbiAgICAgKlxuICAgICAqIFRoZSBAdmlldy10cmFuc2l0aW9uIHsgbmF2aWdhdGlvbjogYXV0bzsgfSBydWxlIHRlbGxzIHRoZSBicm93c2VyIHRvOlxuICAgICAqIDEuIENhcHR1cmUgYSBzbmFwc2hvdCBvZiB0aGUgY3VycmVudCBwYWdlIGJlZm9yZSBuYXZpZ2F0aW9uXG4gICAgICogMi4gRmV0Y2ggdGhlIG5ldyBwYWdlXG4gICAgICogMy4gV2FpdCB1bnRpbCB0aGUgbmV3IHBhZ2UgaXMgZnVsbHkgbG9hZGVkIGFuZCBwYWludGVkIChkb2N1bWVudC5yZWFkeSlcbiAgICAgKiA0LiBBbmltYXRlIHNtb290aGx5IGJldHdlZW4gdGhlIHR3byBzdGF0ZXNcbiAgICAgKlxuICAgICAqIFRoaXMgcHJldmVudHMgdGhlIHdoaXRlIGZsYXNoIGR1cmluZyBuYXZpZ2F0aW9uIGFuZCBjcmVhdGVzIGFwcC1saWtlIHRyYW5zaXRpb25zLlxuICAgICAqL1xuICAgIHN0YXRpYyBfaW5qZWN0X3RyYW5zaXRpb25fY3NzKCkge1xuICAgICAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG5cbiAgICAgICAgc3R5bGUudGV4dENvbnRlbnQgPSBgXG4gICAgICAgICAgICBAdmlldy10cmFuc2l0aW9uIHtcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiBhdXRvO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKiBEaXNhYmxlIGFuaW1hdGlvbiAtIGluc3RhbnQgdHJhbnNpdGlvbiAqL1xuICAgICAgICAgICAgOjp2aWV3LXRyYW5zaXRpb24tZ3JvdXAoKiksXG4gICAgICAgICAgICA6OnZpZXctdHJhbnNpdGlvbi1vbGQoKiksXG4gICAgICAgICAgICA6OnZpZXctdHJhbnNpdGlvbi1uZXcoKikge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi1kdXJhdGlvbjogMHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIGA7XG5cbiAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBSZWFkV3JpdGVMb2NrIGltcGxlbWVudGF0aW9uIGZvciBSU3BhZGUgZnJhbWV3b3JrXG4gKiBQcm92aWRlcyBleGNsdXNpdmUgKHdyaXRlKSBhbmQgc2hhcmVkIChyZWFkKSBsb2NraW5nIG1lY2hhbmlzbXMgZm9yIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIFJlYWRXcml0ZUxvY2sge1xuICAgIHN0YXRpYyAjbG9ja3MgPSBuZXcgTWFwKCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3IgY3JlYXRlIGEgbG9jayBvYmplY3QgZm9yIGEgZ2l2ZW4gbmFtZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljICNnZXRfbG9jayhuYW1lKSB7XG4gICAgICAgIGxldCBzID0gdGhpcy4jbG9ja3MuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoIXMpIHtcbiAgICAgICAgICAgIHMgPSB7IHJlYWRlcnM6IDAsIHdyaXRlcl9hY3RpdmU6IGZhbHNlLCByZWFkZXJfcTogW10sIHdyaXRlcl9xOiBbXSB9O1xuICAgICAgICAgICAgdGhpcy4jbG9ja3Muc2V0KG5hbWUsIHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIHRoZSBuZXh0IG9wZXJhdGlvbiBmb3IgYSBsb2NrXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgI3NjaGVkdWxlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMuI2dldF9sb2NrKG5hbWUpO1xuICAgICAgICBpZiAocy53cml0ZXJfYWN0aXZlIHx8IHMucmVhZGVycyA+IDApIHJldHVybjtcblxuICAgICAgICAvLyBydW4gb25lIHdyaXRlciBpZiBxdWV1ZWRcbiAgICAgICAgaWYgKHMud3JpdGVyX3EubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgeyBjYiwgcmVzb2x2ZSwgcmVqZWN0IH0gPSBzLndyaXRlcl9xLnNoaWZ0KCk7XG4gICAgICAgICAgICBzLndyaXRlcl9hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgICAgICAudGhlbihjYilcbiAgICAgICAgICAgICAgICAudGhlbihyZXNvbHZlLCByZWplY3QpXG4gICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzLndyaXRlcl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4jc2NoZWR1bGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBvdGhlcndpc2UgcnVuIGFsbCBxdWV1ZWQgcmVhZGVycyBpbiBwYXJhbGxlbFxuICAgICAgICBpZiAocy5yZWFkZXJfcS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBiYXRjaCA9IHMucmVhZGVyX3Euc3BsaWNlKDApO1xuICAgICAgICAgICAgcy5yZWFkZXJzICs9IGJhdGNoLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgeyBjYiwgcmVzb2x2ZSwgcmVqZWN0IH0gb2YgYmF0Y2gpIHtcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbihjYilcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzLnJlYWRlcnMgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzLnJlYWRlcnMgPT09IDApIHRoaXMuI3NjaGVkdWxlKG5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjcXVpcmUgYW4gZXhjbHVzaXZlIG11dGV4IGxvY2sgYnkgbmFtZS5cbiAgICAgKiBPbmx5IG9uZSB3cml0ZXIgcnVucyBhdCBhIHRpbWU7IGJsb2NrcyByZWFkZXJzIHVudGlsIGZpbmlzaGVkLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHBhcmFtIHsoKSA9PiBhbnl8UHJvbWlzZTxhbnk+fSBjYlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgc3RhdGljIGFjcXVpcmUobmFtZSwgY2IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHMgPSB0aGlzLiNnZXRfbG9jayhuYW1lKTtcbiAgICAgICAgICAgIHMud3JpdGVyX3EucHVzaCh7IGNiLCByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgICAgICB0aGlzLiNzY2hlZHVsZShuYW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWNxdWlyZSBhIHNoYXJlZCByZWFkIGxvY2sgYnkgbmFtZS5cbiAgICAgKiBNdWx0aXBsZSByZWFkZXJzIGNhbiBydW4gaW4gcGFyYWxsZWw7IGJsb2NrcyB3aGVuIHdyaXRlciBpcyBhY3RpdmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0geygpID0+IGFueXxQcm9taXNlPGFueT59IGNiXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYWNxdWlyZV9yZWFkKG5hbWUsIGNiKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzID0gdGhpcy4jZ2V0X2xvY2sobmFtZSk7XG4gICAgICAgICAgICBpZiAocy53cml0ZXJfYWN0aXZlIHx8IHMud3JpdGVyX3EubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHMucmVhZGVyX3EucHVzaCh7IGNiLCByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuI3NjaGVkdWxlKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcy5yZWFkZXJzICs9IDE7XG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgICAgICAgIC50aGVuKGNiKVxuICAgICAgICAgICAgICAgIC50aGVuKHJlc29sdmUsIHJlamVjdClcbiAgICAgICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHMucmVhZGVycyAtPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAocy5yZWFkZXJzID09PSAwKSB0aGlzLiNzY2hlZHVsZShuYW1lKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yY2UtdW5sb2NrIGEgbXV0ZXggKHVzZSB3aXRoIGNhdXRpb24pLlxuICAgICAqIENvbXBsZXRlbHkgcmVtb3ZlcyB0aGUgbG9jayBzdGF0ZSwgcG90ZW50aWFsbHkgYnJlYWtpbmcgd2FpdGluZyBvcGVyYXRpb25zLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICovXG4gICAgc3RhdGljIGZvcmNlX3VubG9jayhuYW1lKSB7XG4gICAgICAgIHRoaXMuI2xvY2tzLmRlbGV0ZShuYW1lKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgcGVuZGluZyBvcGVyYXRpb25zIG9uIGEgbXV0ZXguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcmV0dXJucyB7e3JlYWRlcnM6IG51bWJlciwgd3JpdGVyX2FjdGl2ZTogYm9vbGVhbiwgcmVhZGVyX3E6IG51bWJlciwgd3JpdGVyX3E6IG51bWJlcn19XG4gICAgICovXG4gICAgc3RhdGljIHBlbmRpbmcobmFtZSkge1xuICAgICAgICBjb25zdCBzID0gdGhpcy4jbG9ja3MuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoIXMpIHJldHVybiB7IHJlYWRlcnM6IDAsIHdyaXRlcl9hY3RpdmU6IGZhbHNlLCByZWFkZXJfcTogMCwgd3JpdGVyX3E6IDAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlYWRlcnM6IHMucmVhZGVycyxcbiAgICAgICAgICAgIHdyaXRlcl9hY3RpdmU6IHMud3JpdGVyX2FjdGl2ZSxcbiAgICAgICAgICAgIHJlYWRlcl9xOiBzLnJlYWRlcl9xLmxlbmd0aCxcbiAgICAgICAgICAgIHdyaXRlcl9xOiBzLndyaXRlcl9xLmxlbmd0aFxuICAgICAgICB9O1xuICAgIH1cbn0iLCIvKipcbiAqIEZvcm0gdXRpbGl0aWVzIGZvciB2YWxpZGF0aW9uIGFuZCBlcnJvciBoYW5kbGluZ1xuICovXG5jbGFzcyBGb3JtX1V0aWxzIHtcbiAgICAvKipcbiAgICAgKiBGcmFtZXdvcmsgaW5pdGlhbGl6YXRpb24gaG9vayB0byByZWdpc3RlciBqUXVlcnkgcGx1Z2luXG4gICAgICogQ3JlYXRlcyAkLmZuLmFqYXhfc3VibWl0KCkgZm9yIGZvcm0gZWxlbWVudHNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgICQuZm4uYWpheF9zdWJtaXQgPSBmdW5jdGlvbihvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgaWYgKCEkZWxlbWVudC5pcygnZm9ybScpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhamF4X3N1Ym1pdCgpIGNhbiBvbmx5IGJlIGNhbGxlZCBvbiBmb3JtIGVsZW1lbnRzJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHVybCA9ICRlbGVtZW50LmF0dHIoJ2FjdGlvbicpO1xuICAgICAgICAgICAgaWYgKCF1cmwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Zvcm0gbXVzdCBoYXZlIGFuIGFjdGlvbiBhdHRyaWJ1dGUnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgeyBjb250cm9sbGVyLCBhY3Rpb24gfSA9IEFqYXguYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24odXJsKTtcblxuICAgICAgICAgICAgcmV0dXJuIEZvcm1fVXRpbHMuYWpheF9zdWJtaXQoJGVsZW1lbnQsIGNvbnRyb2xsZXIsIGFjdGlvbiwgb3B0aW9ucyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3MgZm9ybSB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAqXG4gICAgICogUkVRVUlSRUQgSFRNTCBTVFJVQ1RVUkU6XG4gICAgICogRm9yIGlubGluZSBmaWVsZCBlcnJvcnMgdG8gZGlzcGxheSBwcm9wZXJseSwgZm9ybSBmaWVsZHMgbXVzdCBmb2xsb3cgdGhpcyBzdHJ1Y3R1cmU6XG4gICAgICpcbiAgICAgKiA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAqICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiIGZvcj1cImZpZWxkLW5hbWVcIj5GaWVsZCBMYWJlbDwvbGFiZWw+XG4gICAgICogICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cImZpZWxkLW5hbWVcIiBuYW1lPVwiZmllbGQtbmFtZVwiIHR5cGU9XCJ0ZXh0XCI+XG4gICAgICogPC9kaXY+XG4gICAgICpcbiAgICAgKiBLZXkgcmVxdWlyZW1lbnRzOlxuICAgICAqIC0gV3JhcCBlYWNoIGZpZWxkIGluIGEgY29udGFpbmVyIHdpdGggY2xhc3MgXCJmb3JtLWdyb3VwXCIgKG9yIFwiZm9ybS1jaGVja1wiIC8gXCJpbnB1dC1ncm91cFwiKVxuICAgICAqIC0gSW5wdXQgbXVzdCBoYXZlIGEgXCJuYW1lXCIgYXR0cmlidXRlIG1hdGNoaW5nIHRoZSBlcnJvciBrZXlcbiAgICAgKiAtIFVzZSBcImZvcm0tY29udHJvbFwiIGNsYXNzIG9uIGlucHV0cyBmb3IgQm9vdHN0cmFwIDUgc3R5bGluZ1xuICAgICAqXG4gICAgICogQWNjZXB0cyB0aHJlZSBmb3JtYXRzOlxuICAgICAqIC0gU3RyaW5nOiBTaW5nbGUgZXJyb3Igc2hvd24gYXMgYWxlcnRcbiAgICAgKiAtIEFycmF5IG9mIHN0cmluZ3M6IE11bHRpcGxlIGVycm9ycyBzaG93biBhcyBidWxsZXRlZCBhbGVydFxuICAgICAqIC0gT2JqZWN0OiBGaWVsZCBuYW1lcyBtYXBwZWQgdG8gZXJyb3JzLCBzaG93biBpbmxpbmUgKHVubWF0Y2hlZCBzaG93biBhcyBhbGVydClcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJlbnRfc2VsZWN0b3IgLSBqUXVlcnkgc2VsZWN0b3IgZm9yIHBhcmVudCBlbGVtZW50XG4gICAgICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fEFycmF5fSBlcnJvcnMgLSBFcnJvciBtZXNzYWdlcyB0byBkaXNwbGF5XG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBhbmltYXRpb25zIGNvbXBsZXRlXG4gICAgICovXG4gICAgc3RhdGljIGFwcGx5X2Zvcm1fZXJyb3JzKHBhcmVudF9zZWxlY3RvciwgZXJyb3JzKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JzKTtcblxuICAgICAgICBjb25zdCAkcGFyZW50ID0gJChwYXJlbnRfc2VsZWN0b3IpO1xuXG4gICAgICAgIC8vIFJlc2V0IHRoZSBmb3JtIGVycm9ycyBiZWZvcmUgYXBwbHlpbmcgbmV3IG9uZXNcbiAgICAgICAgRm9ybV9VdGlscy5yZXNldF9mb3JtX2Vycm9ycyhwYXJlbnRfc2VsZWN0b3IpO1xuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSBpbnB1dCB0byBzdGFuZGFyZCBmb3JtYXRcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IEZvcm1fVXRpbHMuX25vcm1hbGl6ZV9lcnJvcnMoZXJyb3JzKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGxldCBhbmltYXRpb25zID0gW107XG5cbiAgICAgICAgICAgIGlmIChub3JtYWxpemVkLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgLy8gU2luZ2xlIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zID0gRm9ybV9VdGlscy5fYXBwbHlfZ2VuZXJhbF9lcnJvcnMoJHBhcmVudCwgbm9ybWFsaXplZC5kYXRhKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm9ybWFsaXplZC50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgICAgICAgICAgLy8gQXJyYXkgb2YgZXJyb3IgbWVzc2FnZXNcbiAgICAgICAgICAgICAgICBjb25zdCBkZWR1cGxpY2F0ZWQgPSBGb3JtX1V0aWxzLl9kZWR1cGxpY2F0ZV9lcnJvcnMobm9ybWFsaXplZC5kYXRhKTtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zID0gRm9ybV9VdGlscy5fYXBwbHlfZ2VuZXJhbF9lcnJvcnMoJHBhcmVudCwgZGVkdXBsaWNhdGVkKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm9ybWFsaXplZC50eXBlID09PSAnZmllbGRzJykge1xuICAgICAgICAgICAgICAgIC8vIEZpZWxkLXNwZWNpZmljIGVycm9yc1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEZvcm1fVXRpbHMuX2FwcGx5X2ZpZWxkX2Vycm9ycygkcGFyZW50LCBub3JtYWxpemVkLmRhdGEpO1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbnMgPSByZXN1bHQuYW5pbWF0aW9ucztcblxuICAgICAgICAgICAgICAgIC8vIENvdW50IG1hdGNoZWQgZmllbGRzXG4gICAgICAgICAgICAgICAgY29uc3QgbWF0Y2hlZF9jb3VudCA9IE9iamVjdC5rZXlzKG5vcm1hbGl6ZWQuZGF0YSkubGVuZ3RoIC0gT2JqZWN0LmtleXMocmVzdWx0LnVubWF0Y2hlZCkubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVubWF0Y2hlZF9kZWR1cGxpY2F0ZWQgPSBGb3JtX1V0aWxzLl9kZWR1cGxpY2F0ZV9lcnJvcnMocmVzdWx0LnVubWF0Y2hlZCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5tYXRjaGVkX2NvdW50ID0gT2JqZWN0LmtleXModW5tYXRjaGVkX2RlZHVwbGljYXRlZCkubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgLy8gU2hvdyBzdW1tYXJ5IGFsZXJ0IGlmIHRoZXJlIGFyZSBhbnkgZmllbGQgZXJyb3JzIChtYXRjaGVkIG9yIHVubWF0Y2hlZClcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlZF9jb3VudCA+IDAgfHwgdW5tYXRjaGVkX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWlsZCBzdW1tYXJ5IG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN1bW1hcnlfbXNnID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaGVkX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyeV9tc2cgPSBtYXRjaGVkX2NvdW50ID09PSAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnUGxlYXNlIGNvcnJlY3QgdGhlIGVycm9yIGhpZ2hsaWdodGVkIGJlbG93LidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdQbGVhc2UgY29ycmVjdCB0aGUgZXJyb3JzIGhpZ2hsaWdodGVkIGJlbG93Lic7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgdW5tYXRjaGVkIGVycm9ycywgYWRkIHRoZW0gYXMgYSBidWxsZXRlZCBsaXN0XG4gICAgICAgICAgICAgICAgICAgIGlmICh1bm1hdGNoZWRfY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdW1tYXJ5X2FuaW1hdGlvbnMgPSBGb3JtX1V0aWxzLl9hcHBseV9jb21iaW5lZF9lcnJvcigkcGFyZW50LCBzdW1tYXJ5X21zZywgdW5tYXRjaGVkX2RlZHVwbGljYXRlZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25zLnB1c2goLi4uc3VtbWFyeV9hbmltYXRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEp1c3QgdGhlIHN1bW1hcnkgbWVzc2FnZSwgbm8gdW5tYXRjaGVkIGVycm9yc1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3VtbWFyeV9hbmltYXRpb25zID0gRm9ybV9VdGlscy5fYXBwbHlfZ2VuZXJhbF9lcnJvcnMoJHBhcmVudCwgc3VtbWFyeV9tc2cpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKC4uLnN1bW1hcnlfYW5pbWF0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlc29sdmUgdGhlIHByb21pc2Ugb25jZSBhbGwgYW5pbWF0aW9ucyBhcmUgY29tcGxldGVcbiAgICAgICAgICAgIFByb21pc2UuYWxsKGFuaW1hdGlvbnMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFNjcm9sbCB0byBlcnJvciBjb250YWluZXIgaWYgaXQgZXhpc3RzXG4gICAgICAgICAgICAgICAgY29uc3QgJGVycm9yX2NvbnRhaW5lciA9ICRwYXJlbnQuZmluZCgnW2RhdGEtaWQ9XCJlcnJvcl9jb250YWluZXJcIl0nKS5maXJzdCgpO1xuICAgICAgICAgICAgICAgIGlmICgkZXJyb3JfY29udGFpbmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGFpbmVyX3RvcCA9ICRlcnJvcl9jb250YWluZXIub2Zmc2V0KCkudG9wO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBmaXhlZCBoZWFkZXIgb2Zmc2V0XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpeGVkX2hlYWRlcl9oZWlnaHQgPSBGb3JtX1V0aWxzLl9nZXRfZml4ZWRfaGVhZGVyX2hlaWdodCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFNjcm9sbCB0byBwb3NpdGlvbiBlcnJvciBjb250YWluZXIgMjBweCBiZWxvdyBhbnkgZml4ZWQgaGVhZGVyc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRfc2Nyb2xsID0gY29udGFpbmVyX3RvcCAtIGZpeGVkX2hlYWRlcl9oZWlnaHQgLSAyMDtcbiAgICAgICAgICAgICAgICAgICAgJCgnaHRtbCwgYm9keScpLmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiB0YXJnZXRfc2Nyb2xsXG4gICAgICAgICAgICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsZWFycyBmb3JtIHZhbGlkYXRpb24gZXJyb3JzIGFuZCByZXNldHMgYWxsIGZvcm0gdmFsdWVzIHRvIGRlZmF1bHRzXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSBmb3JtX3NlbGVjdG9yIC0galF1ZXJ5IHNlbGVjdG9yIG9yIGpRdWVyeSBvYmplY3QgZm9yIGZvcm0gZWxlbWVudFxuICAgICAqL1xuICAgIHN0YXRpYyByZXNldChmb3JtX3NlbGVjdG9yKSB7XG4gICAgICAgIGNvbnN0ICRmb3JtID0gdHlwZW9mIGZvcm1fc2VsZWN0b3IgPT09ICdzdHJpbmcnID8gJChmb3JtX3NlbGVjdG9yKSA6IGZvcm1fc2VsZWN0b3I7XG5cbiAgICAgICAgRm9ybV9VdGlscy5yZXNldF9mb3JtX2Vycm9ycyhmb3JtX3NlbGVjdG9yKTtcbiAgICAgICAgJGZvcm0udHJpZ2dlcigncmVzZXQnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXJpYWxpemVzIGZvcm0gZGF0YSBpbnRvIGtleS12YWx1ZSBvYmplY3RcbiAgICAgKiBSZXR1cm5zIGFsbCBpbnB1dCBlbGVtZW50cyB3aXRoIG5hbWUgYXR0cmlidXRlcyBhcyBvYmplY3QgcHJvcGVydGllc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gZm9ybV9zZWxlY3RvciAtIGpRdWVyeSBzZWxlY3RvciBvciBqUXVlcnkgb2JqZWN0IGZvciBmb3JtIGVsZW1lbnRcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBGb3JtIGRhdGEgYXMga2V5LXZhbHVlIHBhaXJzXG4gICAgICovXG4gICAgc3RhdGljIHNlcmlhbGl6ZShmb3JtX3NlbGVjdG9yKSB7XG4gICAgICAgIGNvbnN0ICRmb3JtID0gdHlwZW9mIGZvcm1fc2VsZWN0b3IgPT09ICdzdHJpbmcnID8gJChmb3JtX3NlbGVjdG9yKSA6IGZvcm1fc2VsZWN0b3I7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcblxuICAgICAgICAkZm9ybS5zZXJpYWxpemVBcnJheSgpLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGRhdGFbaXRlbS5uYW1lXSA9IGl0ZW0udmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1Ym1pdHMgZm9ybSB0byBSU1ggY29udHJvbGxlciBhY3Rpb24gdmlhIEFKQVhcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGZvcm1fc2VsZWN0b3IgLSBqUXVlcnkgc2VsZWN0b3Igb3IgalF1ZXJ5IG9iamVjdCBmb3IgZm9ybSBlbGVtZW50XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnRyb2xsZXIgLSBDb250cm9sbGVyIGNsYXNzIG5hbWUgKGUuZy4sICdVc2VyX0NvbnRyb2xsZXInKVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gLSBBY3Rpb24gbWV0aG9kIG5hbWUgKGUuZy4sICdzYXZlX3Byb2ZpbGUnKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiB7b25fc3VjY2VzczogZm4sIG9uX2Vycm9yOiBmbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggcmVzcG9uc2UgZGF0YVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBhamF4X3N1Ym1pdChmb3JtX3NlbGVjdG9yLCBjb250cm9sbGVyLCBhY3Rpb24sIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCAkZm9ybSA9IHR5cGVvZiBmb3JtX3NlbGVjdG9yID09PSAnc3RyaW5nJyA/ICQoZm9ybV9zZWxlY3RvcikgOiBmb3JtX3NlbGVjdG9yO1xuICAgICAgICBjb25zdCBmb3JtX2RhdGEgPSBGb3JtX1V0aWxzLnNlcmlhbGl6ZSgkZm9ybSk7XG5cbiAgICAgICAgRm9ybV9VdGlscy5yZXNldF9mb3JtX2Vycm9ycyhmb3JtX3NlbGVjdG9yKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBBamF4LmNhbGwoY29udHJvbGxlciwgYWN0aW9uLCBmb3JtX2RhdGEpO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5vbl9zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5vbl9zdWNjZXNzKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKGVycm9yLnR5cGUgPT09ICdmb3JtX2Vycm9yJyAmJiBlcnJvci5kZXRhaWxzKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyhmb3JtX3NlbGVjdG9yLCBlcnJvci5kZXRhaWxzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyhmb3JtX3NlbGVjdG9yLCBlcnJvci5tZXNzYWdlIHx8ICdBbiBlcnJvciBvY2N1cnJlZCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5vbl9lcnJvcikge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMub25fZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZm9ybSB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJlbnRfc2VsZWN0b3IgLSBqUXVlcnkgc2VsZWN0b3IgZm9yIHBhcmVudCBlbGVtZW50XG4gICAgICovXG4gICAgc3RhdGljIHJlc2V0X2Zvcm1fZXJyb3JzKHBhcmVudF9zZWxlY3Rvcikge1xuICAgICAgICBjb25zdCAkcGFyZW50ID0gJChwYXJlbnRfc2VsZWN0b3IpO1xuXG4gICAgICAgIC8vIFJlbW92ZSBmbGFzaCBtZXNzYWdlc1xuICAgICAgICAkKCcuZmxhc2gtbWVzc2FnZXMnKS5yZW1vdmUoKTtcblxuICAgICAgICAvLyBSZW1vdmUgYWxlcnQtZGFuZ2VyIG1lc3NhZ2VzXG4gICAgICAgICRwYXJlbnQuZmluZCgnLmFsZXJ0LWRhbmdlcicpLnJlbW92ZSgpO1xuXG4gICAgICAgIC8vIFJlbW92ZSB2YWxpZGF0aW9uIGVycm9yIGNsYXNzZXMgYW5kIHRleHQgZnJvbSBmb3JtIGVsZW1lbnRzXG4gICAgICAgICRwYXJlbnQuZmluZCgnLmlzLWludmFsaWQnKS5yZW1vdmVDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICAkcGFyZW50LmZpbmQoJy5pbnZhbGlkLWZlZWRiYWNrJykucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAvKipcbiAgICAgKiBOb3JtYWxpemVzIGVycm9yIGlucHV0IGludG8gc3RhbmRhcmQgZm9ybWF0c1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdHxBcnJheX0gZXJyb3JzIC0gUmF3IGVycm9yIGlucHV0XG4gICAgICogQHJldHVybnMge09iamVjdH0gTm9ybWFsaXplZCBlcnJvcnMgYXMge3R5cGU6ICdzdHJpbmcnfCdhcnJheSd8J2ZpZWxkcycsIGRhdGE6IC4uLn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfbm9ybWFsaXplX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gSGFuZGxlIG51bGwvdW5kZWZpbmVkXG4gICAgICAgIGlmICghZXJyb3JzKSB7XG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnc3RyaW5nJywgZGF0YTogJ0FuIGVycm9yIGhhcyBvY2N1cnJlZCcgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvcnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnc3RyaW5nJywgZGF0YTogZXJyb3JzIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgYXJyYXlcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXJyb3JzKSkge1xuICAgICAgICAgICAgLy8gQXJyYXkgb2Ygc3RyaW5ncyAtIGdlbmVyYWwgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3JzLmV2ZXJ5KChlKSA9PiB0eXBlb2YgZSA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ2FycmF5JywgZGF0YTogZXJyb3JzIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBcnJheSB3aXRoIG9iamVjdCBhcyBmaXJzdCBlbGVtZW50IC0gZXh0cmFjdCBpdFxuICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwICYmIHR5cGVvZiBlcnJvcnNbMF0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZvcm1fVXRpbHMuX25vcm1hbGl6ZV9lcnJvcnMoZXJyb3JzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEVtcHR5IG9yIG1peGVkIGFycmF5XG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnYXJyYXknLCBkYXRhOiBbXSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIG9iamVjdCAtIGNoZWNrIGZvciBMYXJhdmVsIHJlc3BvbnNlIHdyYXBwZXJcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBVbndyYXAge2Vycm9yczogey4uLn19IG9yIHtlcnJvcjogey4uLn19XG4gICAgICAgICAgICBjb25zdCB1bndyYXBwZWQgPSBlcnJvcnMuZXJyb3JzIHx8IGVycm9ycy5lcnJvcjtcbiAgICAgICAgICAgIGlmICh1bndyYXBwZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRm9ybV9VdGlscy5fbm9ybWFsaXplX2Vycm9ycyh1bndyYXBwZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDb252ZXJ0IExhcmF2ZWwgdmFsaWRhdG9yIGZvcm1hdCB7ZmllbGQ6IFttc2cxLCBtc2cyXX0gdG8ge2ZpZWxkOiBtc2cxfVxuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3JzLmhhc093blByb3BlcnR5KGZpZWxkKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGVycm9yc1tmaWVsZF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkW2ZpZWxkXSA9IHZhbHVlWzBdO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRbZmllbGRdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkW2ZpZWxkXSA9IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6ICdmaWVsZHMnLCBkYXRhOiBub3JtYWxpemVkIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5hbCBjYXRjaC1hbGwqXG4gICAgICAgIHJldHVybiB7IHR5cGU6ICdzdHJpbmcnLCBkYXRhOiBTdHJpbmcoZXJyb3JzKSB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZHVwbGljYXRlIGVycm9yIG1lc3NhZ2VzIGZyb20gYXJyYXkgb3Igb2JqZWN0IHZhbHVlc1xuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBlcnJvcnMgLSBFcnJvcnMgdG8gZGVkdXBsaWNhdGVcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBEZWR1cGxpY2F0ZWQgZXJyb3JzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2RlZHVwbGljYXRlX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXJyb3JzKSkge1xuICAgICAgICAgICAgcmV0dXJuIFsuLi5uZXcgU2V0KGVycm9ycyldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBjb25zdCBzZWVuID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGVycm9yc1trZXldO1xuICAgICAgICAgICAgICAgIGlmICghc2Vlbi5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlZW4uYWRkKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGZpZWxkLXNwZWNpZmljIHZhbGlkYXRpb24gZXJyb3JzIHRvIGZvcm0gaW5wdXRzXG4gICAgICogQHBhcmFtIHtqUXVlcnl9ICRwYXJlbnQgLSBQYXJlbnQgZWxlbWVudCBjb250YWluaW5nIGZvcm1cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZmllbGRfZXJyb3JzIC0gT2JqZWN0IG1hcHBpbmcgZmllbGQgbmFtZXMgdG8gZXJyb3IgbWVzc2FnZXNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBPYmplY3QgY29udGFpbmluZyB7YW5pbWF0aW9uczogQXJyYXksIHVubWF0Y2hlZDogT2JqZWN0fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9hcHBseV9maWVsZF9lcnJvcnMoJHBhcmVudCwgZmllbGRfZXJyb3JzKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXTtcbiAgICAgICAgY29uc3QgdW5tYXRjaGVkID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCBmaWVsZF9uYW1lIGluIGZpZWxkX2Vycm9ycykge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JfbWVzc2FnZSA9IGZpZWxkX2Vycm9yc1tmaWVsZF9uYW1lXTtcbiAgICAgICAgICAgIGNvbnN0ICRpbnB1dCA9ICRwYXJlbnQuZmluZChgW25hbWU9XCIke2ZpZWxkX25hbWV9XCJdYCk7XG5cbiAgICAgICAgICAgIGlmICghJGlucHV0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHVubWF0Y2hlZFtmaWVsZF9uYW1lXSA9IGVycm9yX21lc3NhZ2U7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0ICRlcnJvciA9ICQoJzxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+PC9kaXY+JykuaHRtbChlcnJvcl9tZXNzYWdlKTtcbiAgICAgICAgICAgIGNvbnN0ICR0YXJnZXQgPSAkaW5wdXQuY2xvc2VzdCgnLmZvcm0tZ3JvdXAsIC5mb3JtLWNoZWNrLCAuaW5wdXQtZ3JvdXAnKTtcblxuICAgICAgICAgICAgaWYgKCEkdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHVubWF0Y2hlZFtmaWVsZF9uYW1lXSA9IGVycm9yX21lc3NhZ2U7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICRpbnB1dC5hZGRDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICAgICAgJGVycm9yLmFwcGVuZFRvKCR0YXJnZXQpO1xuICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKCRlcnJvci5oaWRlKCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGFuaW1hdGlvbnMsIHVubWF0Y2hlZCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgY29tYmluZWQgZXJyb3IgbWVzc2FnZSB3aXRoIHN1bW1hcnkgYW5kIHVubWF0Y2hlZCBmaWVsZCBlcnJvcnNcbiAgICAgKiBAcGFyYW0ge2pRdWVyeX0gJHBhcmVudCAtIFBhcmVudCBlbGVtZW50IGNvbnRhaW5pbmcgZm9ybVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdW1tYXJ5X21zZyAtIFN1bW1hcnkgbWVzc2FnZSAoZS5nLiwgXCJQbGVhc2UgY29ycmVjdCB0aGUgZXJyb3JzIGJlbG93XCIpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHVubWF0Y2hlZF9lcnJvcnMgLSBPYmplY3Qgb2YgZmllbGQgZXJyb3JzIHRoYXQgY291bGRuJ3QgYmUgbWF0Y2hlZCB0byBmaWVsZHNcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIGFuaW1hdGlvbiBwcm9taXNlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9hcHBseV9jb21iaW5lZF9lcnJvcigkcGFyZW50LCBzdW1tYXJ5X21zZywgdW5tYXRjaGVkX2Vycm9ycykge1xuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gW107XG4gICAgICAgIGNvbnN0ICRlcnJvcl9jb250YWluZXIgPSAkcGFyZW50LmZpbmQoJ1tkYXRhLWlkPVwiZXJyb3JfY29udGFpbmVyXCJdJykuZmlyc3QoKTtcbiAgICAgICAgY29uc3QgJHRhcmdldCA9ICRlcnJvcl9jb250YWluZXIubGVuZ3RoID4gMCA/ICRlcnJvcl9jb250YWluZXIgOiAkcGFyZW50O1xuXG4gICAgICAgIC8vIENyZWF0ZSBhbGVydCB3aXRoIHN1bW1hcnkgbWVzc2FnZSBhbmQgYnVsbGV0ZWQgbGlzdCBvZiB1bm1hdGNoZWQgZXJyb3JzXG4gICAgICAgIGNvbnN0ICRhbGVydCA9ICQoJzxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIiByb2xlPVwiYWxlcnRcIj48L2Rpdj4nKTtcblxuICAgICAgICAvLyBBZGQgc3VtbWFyeSBtZXNzYWdlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmIChzdW1tYXJ5X21zZykge1xuICAgICAgICAgICAgJCgnPHAgY2xhc3M9XCJtYi0yXCI+PC9wPicpLnRleHQoc3VtbWFyeV9tc2cpLmFwcGVuZFRvKCRhbGVydCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgdW5tYXRjaGVkIGVycm9ycyBhcyBidWxsZXRlZCBsaXN0XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh1bm1hdGNoZWRfZXJyb3JzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCAkbGlzdCA9ICQoJzx1bCBjbGFzcz1cIm1iLTBcIj48L3VsPicpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZF9uYW1lIGluIHVubWF0Y2hlZF9lcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvcl9tc2cgPSB1bm1hdGNoZWRfZXJyb3JzW2ZpZWxkX25hbWVdO1xuICAgICAgICAgICAgICAgICQoJzxsaT48L2xpPicpLmh0bWwoZXJyb3JfbXNnKS5hcHBlbmRUbygkbGlzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkbGlzdC5hcHBlbmRUbygkYWxlcnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCRlcnJvcl9jb250YWluZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKCRhbGVydC5oaWRlKCkuYXBwZW5kVG8oJHRhcmdldCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCgkYWxlcnQuaGlkZSgpLnByZXBlbmRUbygkdGFyZ2V0KS5mYWRlSW4oMzAwKS5wcm9taXNlKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFuaW1hdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbGllcyBnZW5lcmFsIGVycm9yIG1lc3NhZ2VzIGFzIGFsZXJ0IGJveFxuICAgICAqIEBwYXJhbSB7alF1ZXJ5fSAkcGFyZW50IC0gUGFyZW50IGVsZW1lbnQgdG8gcHJlcGVuZCBhbGVydCB0b1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fSBtZXNzYWdlcyAtIEVycm9yIG1lc3NhZ2UocykgdG8gZGlzcGxheVxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2YgYW5pbWF0aW9uIHByb21pc2VzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2FwcGx5X2dlbmVyYWxfZXJyb3JzKCRwYXJlbnQsIG1lc3NhZ2VzKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXTtcblxuICAgICAgICAvLyBMb29rIGZvciBhIHNwZWNpZmljIGVycm9yIGNvbnRhaW5lciBkaXYgKGUuZy4sIGluIFJzeF9Gb3JtIGNvbXBvbmVudClcbiAgICAgICAgY29uc3QgJGVycm9yX2NvbnRhaW5lciA9ICRwYXJlbnQuZmluZCgnW2RhdGEtaWQ9XCJlcnJvcl9jb250YWluZXJcIl0nKS5maXJzdCgpO1xuICAgICAgICBjb25zdCAkdGFyZ2V0ID0gJGVycm9yX2NvbnRhaW5lci5sZW5ndGggPiAwID8gJGVycm9yX2NvbnRhaW5lciA6ICRwYXJlbnQ7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIFNpbmdsZSBlcnJvciAtIHNpbXBsZSBhbGVydCB3aXRob3V0IGxpc3RcbiAgICAgICAgICAgIGNvbnN0ICRhbGVydCA9ICQoJzxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIiByb2xlPVwiYWxlcnRcIj48L2Rpdj4nKS50ZXh0KG1lc3NhZ2VzKTtcbiAgICAgICAgICAgIGlmICgkZXJyb3JfY29udGFpbmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zLnB1c2goJGFsZXJ0LmhpZGUoKS5hcHBlbmRUbygkdGFyZ2V0KS5mYWRlSW4oMzAwKS5wcm9taXNlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zLnB1c2goJGFsZXJ0LmhpZGUoKS5wcmVwZW5kVG8oJHRhcmdldCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSAmJiBtZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBNdWx0aXBsZSBlcnJvcnMgLSBidWxsZXRlZCBsaXN0XG4gICAgICAgICAgICBjb25zdCAkYWxlcnQgPSAkKCc8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+PHVsIGNsYXNzPVwibWItMFwiPjwvdWw+PC9kaXY+Jyk7XG4gICAgICAgICAgICBjb25zdCAkbGlzdCA9ICRhbGVydC5maW5kKCd1bCcpO1xuXG4gICAgICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKChtc2cpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gKG1zZyArICcnKS50cmltKCkgfHwgJ0FuIGVycm9yIGhhcyBvY2N1cnJlZCc7XG4gICAgICAgICAgICAgICAgJCgnPGxpPjwvbGk+JykuaHRtbCh0ZXh0KS5hcHBlbmRUbygkbGlzdCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCRlcnJvcl9jb250YWluZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCgkYWxlcnQuaGlkZSgpLmFwcGVuZFRvKCR0YXJnZXQpLmZhZGVJbigzMDApLnByb21pc2UoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCgkYWxlcnQuaGlkZSgpLnByZXBlbmRUbygkdGFyZ2V0KS5mYWRlSW4oMzAwKS5wcm9taXNlKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBtZXNzYWdlcyA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkobWVzc2FnZXMpKSB7XG4gICAgICAgICAgICAvLyBPYmplY3Qgb2YgdW5tYXRjaGVkIGZpZWxkIGVycm9ycyAtIGNvbnZlcnQgdG8gYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX2xpc3QgPSBPYmplY3QudmFsdWVzKG1lc3NhZ2VzKVxuICAgICAgICAgICAgICAgIC5tYXAoKHYpID0+IFN0cmluZyh2KS50cmltKCkpXG4gICAgICAgICAgICAgICAgLmZpbHRlcigodikgPT4gdik7XG4gICAgICAgICAgICBpZiAoZXJyb3JfbGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZvcm1fVXRpbHMuX2FwcGx5X2dlbmVyYWxfZXJyb3JzKCRwYXJlbnQsIGVycm9yX2xpc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFuaW1hdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdG90YWwgaGVpZ2h0IG9mIGZpeGVkL3N0aWNreSBoZWFkZXJzIGF0IHRoZSB0b3Agb2YgdGhlIHBhZ2VcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUb3RhbCBoZWlnaHQgaW4gcGl4ZWxzIG9mIGZpeGVkIHRvcCBlbGVtZW50c1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9nZXRfZml4ZWRfaGVhZGVyX2hlaWdodCgpIHtcbiAgICAgICAgbGV0IHRvdGFsX2hlaWdodCA9IDA7XG5cbiAgICAgICAgLy8gRmluZCBhbGwgZml4ZWQgb3Igc3RpY2t5IHBvc2l0aW9uZWQgZWxlbWVudHNcbiAgICAgICAgJCgnKicpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkZWwgPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSAkZWwuY3NzKCdwb3NpdGlvbicpO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGNoZWNrIGZpeGVkIG9yIHN0aWNreSBlbGVtZW50c1xuICAgICAgICAgICAgaWYgKHBvc2l0aW9uICE9PSAnZml4ZWQnICYmIHBvc2l0aW9uICE9PSAnc3RpY2t5Jykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyBwb3NpdGlvbmVkIGF0IG9yIG5lYXIgdGhlIHRvcFxuICAgICAgICAgICAgY29uc3QgdG9wID0gcGFyc2VJbnQoJGVsLmNzcygndG9wJykpIHx8IDA7XG4gICAgICAgICAgICBpZiAodG9wID4gNTApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIE5vdCBhIHRvcCBoZWFkZXJcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyB2aXNpYmxlXG4gICAgICAgICAgICBpZiAoISRlbC5pcygnOnZpc2libGUnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBzcGFucyBzaWduaWZpY2FudCB3aWR0aCAobGlrZWx5IGEgaGVhZGVyL25hdmJhcilcbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gJGVsLm91dGVyV2lkdGgoKTtcbiAgICAgICAgICAgIGNvbnN0IHZpZXdwb3J0X3dpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gICAgICAgICAgICBpZiAod2lkdGggPCB2aWV3cG9ydF93aWR0aCAqIDAuNSkge1xuICAgICAgICAgICAgICAgIHJldHVybjsgLy8gVG9vIG5hcnJvdyB0byBiZSBhIGhlYWRlclxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgdGhpcyBlbGVtZW50J3MgaGVpZ2h0XG4gICAgICAgICAgICB0b3RhbF9oZWlnaHQgKz0gJGVsLm91dGVySGVpZ2h0KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0b3RhbF9oZWlnaHQ7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBEZWJ1Z2dlciBjbGFzcyBmb3IgY29uc29sZV9kZWJ1ZyBhbmQgYnJvd3NlciBlcnJvciBsb2dnaW5nXG4gKiBIYW5kbGVzIGJhdGNoZWQgc3VibWlzc2lvbiB0byBzZXJ2ZXIgd2hlbiBjb25maWd1cmVkXG4gKi9cbmNsYXNzIERlYnVnZ2VyIHtcbiAgICAvLyBCYXRjaGluZyBzdGF0ZSBmb3IgY29uc29sZV9kZWJ1ZyBtZXNzYWdlc1xuICAgIHN0YXRpYyBfY29uc29sZV9iYXRjaCA9IFtdO1xuICAgIHN0YXRpYyBfY29uc29sZV90aW1lciA9IG51bGw7XG4gICAgc3RhdGljIF9jb25zb2xlX2JhdGNoX2NvdW50ID0gMDtcblxuICAgIC8vIEJhdGNoaW5nIHN0YXRlIGZvciBlcnJvciBtZXNzYWdlc1xuICAgIHN0YXRpYyBfZXJyb3JfYmF0Y2ggPSBbXTtcbiAgICBzdGF0aWMgX2Vycm9yX3RpbWVyID0gbnVsbDtcbiAgICBzdGF0aWMgX2Vycm9yX2NvdW50ID0gMDtcbiAgICBzdGF0aWMgX2Vycm9yX2JhdGNoX2NvdW50ID0gMDtcblxuICAgIC8vIENvbnN0YW50c1xuICAgIHN0YXRpYyBERUJPVU5DRV9NUyA9IDIwMDA7XG4gICAgc3RhdGljIE1BWF9FUlJPUlNfUEVSX1BBR0UgPSAyMDtcbiAgICBzdGF0aWMgTUFYX0VSUk9SX0JBVENIRVMgPSA1O1xuXG4gICAgLy8gU3RvcmUgc3RhcnQgdGltZSBmb3IgYmVuY2htYXJraW5nXG4gICAgc3RhdGljIF9zdGFydF90aW1lID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZnJhbWV3b3JrIGVycm9yIGhhbmRsaW5nXG4gICAgICogQ2FsbGVkIGR1cmluZyBmcmFtZXdvcmsgaW5pdGlhbGl6YXRpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2luaXQoKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGJyb3dzZXIgZXJyb3IgbG9nZ2luZyBpcyBlbmFibGVkXG4gICAgICAgIGlmICh3aW5kb3cucnN4YXBwICYmIHdpbmRvdy5yc3hhcHAubG9nX2Jyb3dzZXJfZXJyb3JzKSB7XG4gICAgICAgICAgICAvLyBSZWdpc3RlciBnbG9iYWwgZXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgRGVidWdnZXIuX2hhbmRsZV9icm93c2VyX2Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXZlbnQubWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IGV2ZW50LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICBsaW5lbm86IGV2ZW50LmxpbmVubyxcbiAgICAgICAgICAgICAgICAgICAgY29sbm86IGV2ZW50LmNvbG5vLFxuICAgICAgICAgICAgICAgICAgICBzdGFjazogZXZlbnQuZXJyb3IgPyBldmVudC5lcnJvci5zdGFjayA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUmVnaXN0ZXIgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uIGhhbmRsZXJcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBEZWJ1Z2dlci5faGFuZGxlX2Jyb3dzZXJfZXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBldmVudC5yZWFzb24gPyBldmVudC5yZWFzb24ubWVzc2FnZSB8fCBTdHJpbmcoZXZlbnQucmVhc29uKSA6ICdVbmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb24nLFxuICAgICAgICAgICAgICAgICAgICBzdGFjazogZXZlbnQucmVhc29uICYmIGV2ZW50LnJlYXNvbi5zdGFjayA/IGV2ZW50LnJlYXNvbi5zdGFjayA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd1bmhhbmRsZWRyZWplY3Rpb24nLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWdpc3RlciB1aSByZWZyZXNoIGhhbmRsZXJcbiAgICAgICAgUnN4Lm9uKCdyZWZyZXNoJywgRGVidWdnZXIub25fcmVmcmVzaCk7XG4gICAgfVxuXG4gICAgLy8gSW4gZGV2IG1vZGUsIHNvbWUgdWkgZWxlbWVudHMgY2FuIGJlIGF1dG9tYXRpY2FsbHkgYXBwbGllZCB0byBhc3Npc3Qgd2l0aCBkZXZlbG9wbWVudFxuICAgIHN0YXRpYyBvbl9yZWZyZXNoKCkge1xuICAgICAgICBpZiAoIVJzeC5pc19wcm9kKCkpIHtcbiAgICAgICAgICAgIC8vIEFkZCBhbiB1bmRlcmxpbmUgMiBweCBibHVlIHRvIGFsbCBhIHRhZ3Mgd2l0aCBocmVmID09PSBcIiNcIiB1c2luZyBqcXVlcnlcbiAgICAgICAgICAgIC8vIFRvZG86IG1heWJlIHRoaXMgc2hvdWxkIGJlIGEgY29uZmlndXJhYmxlIGRlYnVnIG9wdGlvbj9cbiAgICAgICAgICAgIC8vICQoJ2FbaHJlZj1cIiNcIl0nKS5jc3Moe1xuICAgICAgICAgICAgLy8gICAgICdib3JkZXItYm90dG9tJzogJzJweCBzb2xpZCBibHVlJyxcbiAgICAgICAgICAgIC8vICAgICAndGV4dC1kZWNvcmF0aW9uJzogJ25vbmUnXG4gICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgY29uc29sZV9kZWJ1Z1xuICAgICAqIE1pcnJvcnMgUEhQIGZ1bmN0aW9uYWxpdHkgd2l0aCBiYXRjaGluZyBmb3IgTGFyYXZlbCBsb2dcbiAgICAgKi9cbiAgICBzdGF0aWMgY29uc29sZV9kZWJ1ZyhjaGFubmVsLCAuLi52YWx1ZXMpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgY29uc29sZV9kZWJ1ZyBpcyBlbmFibGVkXG4gICAgICAgIGlmICghd2luZG93LnJzeGFwcCB8fCAhd2luZG93LnJzeGFwcC5jb25zb2xlX2RlYnVnIHx8ICF3aW5kb3cucnN4YXBwLmNvbnNvbGVfZGVidWcuZW5hYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29uZmlnID0gd2luZG93LnJzeGFwcC5jb25zb2xlX2RlYnVnO1xuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSBjaGFubmVsIG5hbWVcbiAgICAgICAgY2hhbm5lbCA9IFN0cmluZyhjaGFubmVsKVxuICAgICAgICAgICAgLnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgIC5yZXBsYWNlKC9bXFxbXFxdXS9nLCAnJyk7XG5cbiAgICAgICAgLy8gQXBwbHkgZmlsdGVyaW5nXG4gICAgICAgIGlmIChjb25maWcuZmlsdGVyX21vZGUgPT09ICdzcGVjaWZpYycpIHtcbiAgICAgICAgICAgIGNvbnN0IHNwZWNpZmljID0gY29uZmlnLnNwZWNpZmljX2NoYW5uZWw7XG4gICAgICAgICAgICBpZiAoc3BlY2lmaWMpIHtcbiAgICAgICAgICAgICAgICAvLyBTcGxpdCBjb21tYS1zZXBhcmF0ZWQgdmFsdWVzIGFuZCBub3JtYWxpemVcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVscyA9IHNwZWNpZmljLnNwbGl0KCcsJykubWFwKChjKSA9PiBjLnRyaW0oKS50b1VwcGVyQ2FzZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNoYW5uZWxzLmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnLmZpbHRlcl9tb2RlID09PSAnd2hpdGVsaXN0Jykge1xuICAgICAgICAgICAgY29uc3Qgd2hpdGVsaXN0ID0gKGNvbmZpZy5maWx0ZXJfY2hhbm5lbHMgfHwgW10pLm1hcCgoYykgPT4gYy50b1VwcGVyQ2FzZSgpKTtcbiAgICAgICAgICAgIGlmICghd2hpdGVsaXN0LmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5maWx0ZXJfbW9kZSA9PT0gJ2JsYWNrbGlzdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGJsYWNrbGlzdCA9IChjb25maWcuZmlsdGVyX2NoYW5uZWxzIHx8IFtdKS5tYXAoKGMpID0+IGMudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgICBpZiAoYmxhY2tsaXN0LmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJlcGFyZSB0aGUgbWVzc2FnZVxuICAgICAgICBsZXQgbWVzc2FnZSA9IHtcbiAgICAgICAgICAgIGNoYW5uZWw6IGNoYW5uZWwsXG4gICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEFkZCBsb2NhdGlvbiBpZiBjb25maWd1cmVkXG4gICAgICAgIGlmIChjb25maWcuaW5jbHVkZV9sb2NhdGlvbiB8fCBjb25maWcuaW5jbHVkZV9iYWNrdHJhY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgICBjb25zdCBzdGFjayA9IGVycm9yLnN0YWNrIHx8ICcnO1xuICAgICAgICAgICAgY29uc3Qgc3RhY2tMaW5lcyA9IHN0YWNrLnNwbGl0KCdcXG4nKTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5pbmNsdWRlX2xvY2F0aW9uICYmIHN0YWNrTGluZXMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgICAgIC8vIFNraXAgRXJyb3IgbGluZSBhbmQgdGhpcyBmdW5jdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxlckxpbmUgPSBzdGFja0xpbmVzWzJdIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrLio/XFxzK1xcKCguKj8pOihcXGQrKTooXFxkKylcXCkvKSB8fCBjYWxsZXJMaW5lLm1hdGNoKC9hdFxccysoLio/KTooXFxkKyk6KFxcZCspLyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubG9jYXRpb24gPSBgJHttYXRjaFsxXX06JHttYXRjaFsyXX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5pbmNsdWRlX2JhY2t0cmFjZSkge1xuICAgICAgICAgICAgICAgIC8vIEluY2x1ZGUgZmlyc3QgNSBzdGFjayBmcmFtZXMsIHNraXBwaW5nIHRoaXMgZnVuY3Rpb25cbiAgICAgICAgICAgICAgICBtZXNzYWdlLmJhY2t0cmFjZSA9IHN0YWNrTGluZXNcbiAgICAgICAgICAgICAgICAgICAgLnNsaWNlKDIsIDcpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE91dHB1dCB0byBicm93c2VyIGNvbnNvbGUgaWYgZW5hYmxlZFxuICAgICAgICBpZiAoY29uZmlnLm91dHB1dHMgJiYgY29uZmlnLm91dHB1dHMuYnJvd3Nlcikge1xuICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gY29uZmlnLmluY2x1ZGVfYmVuY2htYXJrID8gYFske0RlYnVnZ2VyLl9nZXRfdGltZV9wcmVmaXgoKX1dIGAgOiAnJztcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxQcmVmaXggPSBgWyR7Y2hhbm5lbH1dYDtcblxuICAgICAgICAgICAgLy8gVXNlIGFwcHJvcHJpYXRlIGNvbnNvbGUgbWV0aG9kIGJhc2VkIG9uIGNoYW5uZWxcbiAgICAgICAgICAgIGxldCBjb25zb2xlTWV0aG9kID0gJ2xvZyc7XG4gICAgICAgICAgICBpZiAoY2hhbm5lbC5pbmNsdWRlcygnRVJST1InKSkgY29uc29sZU1ldGhvZCA9ICdlcnJvcic7XG4gICAgICAgICAgICBlbHNlIGlmIChjaGFubmVsLmluY2x1ZGVzKCdXQVJOJykpIGNvbnNvbGVNZXRob2QgPSAnd2Fybic7XG4gICAgICAgICAgICBlbHNlIGlmIChjaGFubmVsLmluY2x1ZGVzKCdJTkZPJykpIGNvbnNvbGVNZXRob2QgPSAnaW5mbyc7XG5cbiAgICAgICAgICAgIGNvbnNvbGVbY29uc29sZU1ldGhvZF0ocHJlZml4ICsgY2hhbm5lbFByZWZpeCwgLi4udmFsdWVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJhdGNoIGZvciBMYXJhdmVsIGxvZyBpZiBlbmFibGVkXG4gICAgICAgIGlmIChjb25maWcub3V0cHV0cyAmJiBjb25maWcub3V0cHV0cy5sYXJhdmVsX2xvZykge1xuICAgICAgICAgICAgRGVidWdnZXIuX2JhdGNoX2NvbnNvbGVfbWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvZyBhbiBlcnJvciB0byB0aGUgc2VydmVyXG4gICAgICogVXNlZCBtYW51YWxseSBvciBieSBBamF4IGVycm9yIGhhbmRsaW5nXG4gICAgICovXG4gICAgc3RhdGljIGxvZ19lcnJvcihlcnJvcikge1xuICAgICAgICAvLyBDaGVjayBpZiBicm93c2VyIGVycm9yIGxvZ2dpbmcgaXMgZW5hYmxlZFxuICAgICAgICBpZiAoIXdpbmRvdy5yc3hhcHAgfHwgIXdpbmRvdy5yc3hhcHAubG9nX2Jyb3dzZXJfZXJyb3JzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOb3JtYWxpemUgZXJyb3IgZm9ybWF0XG4gICAgICAgIGxldCBlcnJvckRhdGEgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGVycm9yRGF0YS5tZXNzYWdlID0gZXJyb3I7XG4gICAgICAgICAgICBlcnJvckRhdGEudHlwZSA9ICdtYW51YWwnO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yRGF0YS5tZXNzYWdlID0gZXJyb3IubWVzc2FnZTtcbiAgICAgICAgICAgIGVycm9yRGF0YS5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgICAgICAgICAgZXJyb3JEYXRhLnR5cGUgPSAnZXhjZXB0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBlcnJvckRhdGEgPSBlcnJvcjtcbiAgICAgICAgICAgIGlmICghZXJyb3JEYXRhLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvckRhdGEudHlwZSA9ICdtYW51YWwnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgRGVidWdnZXIuX2hhbmRsZV9icm93c2VyX2Vycm9yKGVycm9yRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEhhbmRsZSBicm93c2VyIGVycm9ycyB3aXRoIGJhdGNoaW5nXG4gICAgICovXG4gICAgc3RhdGljIF9oYW5kbGVfYnJvd3Nlcl9lcnJvcihlcnJvckRhdGEpIHtcbiAgICAgICAgLy8gQ2hlY2sgbGltaXRzXG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfY291bnQgPj0gRGVidWdnZXIuTUFYX0VSUk9SU19QRVJfUEFHRSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfYmF0Y2hfY291bnQgPj0gRGVidWdnZXIuTUFYX0VSUk9SX0JBVENIRVMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl9jb3VudCsrO1xuXG4gICAgICAgIC8vIEFkZCBtZXRhZGF0YVxuICAgICAgICBlcnJvckRhdGEudXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XG4gICAgICAgIGVycm9yRGF0YS51c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgICAgICBlcnJvckRhdGEudGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gICAgICAgIC8vIEFkZCB0byBiYXRjaFxuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfYmF0Y2gucHVzaChlcnJvckRhdGEpO1xuXG4gICAgICAgIC8vIENsZWFyIGV4aXN0aW5nIHRpbWVyXG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfdGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChEZWJ1Z2dlci5fZXJyb3JfdGltZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRlYm91bmNlIHRpbWVyXG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl90aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgRGVidWdnZXIuX2ZsdXNoX2Vycm9yX2JhdGNoKCk7XG4gICAgICAgIH0sIERlYnVnZ2VyLkRFQk9VTkNFX01TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogQmF0Y2ggY29uc29sZV9kZWJ1ZyBtZXNzYWdlcyBmb3IgTGFyYXZlbCBsb2dcbiAgICAgKi9cbiAgICBzdGF0aWMgX2JhdGNoX2NvbnNvbGVfbWVzc2FnZShtZXNzYWdlKSB7XG4gICAgICAgIERlYnVnZ2VyLl9jb25zb2xlX2JhdGNoLnB1c2gobWVzc2FnZSk7XG5cbiAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgdGltZXJcbiAgICAgICAgaWYgKERlYnVnZ2VyLl9jb25zb2xlX3RpbWVyKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoRGVidWdnZXIuX2NvbnNvbGVfdGltZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRlYm91bmNlIHRpbWVyXG4gICAgICAgIERlYnVnZ2VyLl9jb25zb2xlX3RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5fZmx1c2hfY29uc29sZV9iYXRjaCgpO1xuICAgICAgICB9LCBEZWJ1Z2dlci5ERUJPVU5DRV9NUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEZsdXNoIGNvbnNvbGVfZGVidWcgYmF0Y2ggdG8gc2VydmVyXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9mbHVzaF9jb25zb2xlX2JhdGNoKCkge1xuICAgICAgICBpZiAoRGVidWdnZXIuX2NvbnNvbGVfYmF0Y2gubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IERlYnVnZ2VyLl9jb25zb2xlX2JhdGNoO1xuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV9iYXRjaCA9IFtdO1xuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV90aW1lciA9IG51bGw7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBBamF4LmNhbGwoUnN4LlJvdXRlKCdEZWJ1Z2dlcl9Db250cm9sbGVyJywgJ2xvZ19jb25zb2xlX21lc3NhZ2VzJyksIHsgbWVzc2FnZXM6IG1lc3NhZ2VzIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gU2lsZW50bHkgZmFpbCAtIGRvbid0IGNyZWF0ZSBlcnJvciBsb29wXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gc2VuZCBjb25zb2xlX2RlYnVnIG1lc3NhZ2VzIHRvIHNlcnZlcjonLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogRmx1c2ggZXJyb3IgYmF0Y2ggdG8gc2VydmVyXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9mbHVzaF9lcnJvcl9iYXRjaCgpIHtcbiAgICAgICAgaWYgKERlYnVnZ2VyLl9lcnJvcl9iYXRjaC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVycm9ycyA9IERlYnVnZ2VyLl9lcnJvcl9iYXRjaDtcbiAgICAgICAgRGVidWdnZXIuX2Vycm9yX2JhdGNoID0gW107XG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl90aW1lciA9IG51bGw7XG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl9iYXRjaF9jb3VudCsrO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gQWpheC5jYWxsKFJzeC5Sb3V0ZSgnRGVidWdnZXJfQ29udHJvbGxlcicsICdsb2dfYnJvd3Nlcl9lcnJvcnMnKSwgeyBlcnJvcnM6IGVycm9ycyB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFNpbGVudGx5IGZhaWwgLSBkb24ndCBjcmVhdGUgZXJyb3IgbG9vcFxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHNlbmQgYnJvd3NlciBlcnJvcnMgdG8gc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBHZXQgdGltZSBwcmVmaXggZm9yIGJlbmNobWFya2luZ1xuICAgICAqL1xuICAgIHN0YXRpYyBfZ2V0X3RpbWVfcHJlZml4KCkge1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoIURlYnVnZ2VyLl9zdGFydF90aW1lKSB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5fc3RhcnRfdGltZSA9IG5vdztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbGFwc2VkID0gbm93IC0gRGVidWdnZXIuX3N0YXJ0X3RpbWU7XG4gICAgICAgIHJldHVybiAoZWxhcHNlZCAvIDEwMDApLnRvRml4ZWQoMykgKyAncyc7XG4gICAgfVxufVxuIiwiLy8gQEpTLVRISVMtMDEtRVhDRVBUSU9OXG4vKipcbiAqIGpRdWVyeSBoZWxwZXIgZXh0ZW5zaW9ucyBmb3IgdGhlIFJTWCBmcmFtZXdvcmtcbiAqIFRoZXNlIGV4dGVuc2lvbnMgYWRkIHV0aWxpdHkgbWV0aG9kcyB0byBqUXVlcnkncyBwcm90b3R5cGVcbiAqIE5vdGU6ICd0aGlzJyByZWZlcmVuY2VzIGluIGpRdWVyeSBleHRlbnNpb25zIHJlZmVyIHRvIGpRdWVyeSBvYmplY3RzIGJ5IGRlc2lnblxuICovXG5jbGFzcyBSc3hfSnFfSGVscGVycyB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSBqUXVlcnkgZXh0ZW5zaW9ucyB3aGVuIHRoZSBmcmFtZXdvcmsgY29yZSBpcyBkZWZpbmVkXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBmcmFtZXdvcmsgaW5pdGlhbGl6YXRpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2RlZmluZSgpIHtcbiAgICAgICAgLy8gUmV0dXJucyB0cnVlIGlmIGpxdWVyeSBzZWxlY3RvciBtYXRjaGVkIGFuIGVsZW1lbnRcbiAgICAgICAgJC5mbi5leGlzdHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPiAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBqcXVlcnkgZWxlbWVudCBpcyB2aXNpYmxlXG4gICAgICAgICQuZm4uaXNfdmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzKCc6dmlzaWJsZScpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNjcm9sbHMgdG8gdGhlIHRhcmdldCBlbGVtZW50LCBvbmx5IHNjcm9sbHMgdXAuICBUb2RvOiBDcmVhdGUgYSB2ZXJzaW9uXG4gICAgICAgIC8vIG9mIHRoaXMgdGhhdCBhbHNvIHNjcm9sbHMgb25seSBkb3duLCBvciBib3RoXG4gICAgICAgICQuZm4uc2Nyb2xsX3VwX3RvID0gZnVuY3Rpb24gKHNwZWVkID0gMCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS53YXJuKFwiQ291bGQgbm90IGZpbmQgdGFyZ2V0IGVsZW1lbnQgdG8gc2Nyb2xsIHRvXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzX2luX2RvbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS53YXJuKFwiVGFyZ2V0IGVsZW1lbnQgZm9yIHNjcm9sbCBpcyBub3Qgb24gZG9tXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGVfdG9wID0gTWF0aC5yb3VuZCh0aGlzLm9mZnNldCgpLnRvcCk7XG4gICAgICAgICAgICBsZXQgc190b3AgPSAkKCdib2R5Jykuc2Nyb2xsVG9wKCk7XG4gICAgICAgICAgICBpZiAoZV90b3AgPCAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRhcmdldCA9IHNfdG9wICsgZV90b3A7XG4gICAgICAgICAgICAgICAgJCgnaHRtbCwgYm9keScpLmFuaW1hdGUoXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzcGVlZFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gJCgpLmlzKFwiOmZvY3VzXCIpIC0gY2hlY2sgaWYgZWxlbWVudCBoYXMgZm9jdXNcbiAgICAgICAgJC5leHByWyc6J10uZm9jdXMgPSBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKGVsZW0udHlwZSB8fCBlbGVtLmhyZWYpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNhdmUgbmF0aXZlIGNsaWNrIGJlaGF2aW9yIGJlZm9yZSBvdmVycmlkZVxuICAgICAgICAkLmZuLl9jbGlja19uYXRpdmUgPSAkLmZuLmNsaWNrO1xuXG4gICAgICAgIC8vIE92ZXJyaWRlIC5jbGljaygpIHRvIGNhbGwgcHJldmVudERlZmF1bHQgYnkgZGVmYXVsdFxuICAgICAgICAvLyBUaGlzIHByZXZlbnRzIGFjY2lkZW50YWwgcGFnZSBuYXZpZ2F0aW9uL2Zvcm0gc3VibWlzc2lvbiAtIHRoZSBjb3JyZWN0IGJlaGF2aW9yIDk1JSBvZiB0aGUgdGltZVxuICAgICAgICAkLmZuLmNsaWNrID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgICAgIC8vIElmIG5vIGhhbmRsZXIgcHJvdmlkZWQsIHRyaWdnZXIgY2xpY2sgZXZlbnQgKGpRdWVyeSAuY2xpY2soKSB3aXRoIG5vIGFyZ3MpXG4gICAgICAgICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWNrX25hdGl2ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBdHRhY2ggY2xpY2sgaGFuZGxlciB3aXRoIGF1dG9tYXRpYyBwcmV2ZW50RGVmYXVsdFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBTYXZlIG9yaWdpbmFsIHByZXZlbnREZWZhdWx0XG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxfcHJldmVudERlZmF1bHQgPSBlLnByZXZlbnREZWZhdWx0LmJpbmQoZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBPdmVycmlkZSBwcmV2ZW50RGVmYXVsdCB0byBzaG93IHdhcm5pbmcgd2hlbiBjYWxsZWQgZXhwbGljaXRseVxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdldmVudC5wcmV2ZW50RGVmYXVsdCgpIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IFJTcGFkZSAuY2xpY2soKSBoYW5kbGVycyBhbmQgY2FuIGJlIHJlbW92ZWQuJyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAvLyBDYWxsIHByZXZlbnREZWZhdWx0IGJlZm9yZSBoYW5kbGVyXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxfcHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBFc2NhcGUgaGF0Y2g6IGNsaWNrIGhhbmRsZXIgd2l0aG91dCBwcmV2ZW50RGVmYXVsdCBmb3IgdGhlIDUlIGNhc2VcbiAgICAgICAgJC5mbi5jbGlja19hbGxvd19kZWZhdWx0ID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xpY2tfbmF0aXZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xpY2tfbmF0aXZlKGhhbmRsZXIpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUganF1ZXJ5IGVsZW1lbnQgZXhpc3RzIGluIGFuZCBpcyBhdHRhY2hlZCB0byB0aGUgRE9NXG4gICAgICAgICQuZm4uaXNfaW5fZG9tID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0ICRlbGVtZW50ID0gdGhpcztcbiAgICAgICAgICAgIGxldCBfYW5jZXN0b3IgPSBmdW5jdGlvbiAoSFRNTG9iaikge1xuICAgICAgICAgICAgICAgIHdoaWxlIChIVE1Mb2JqLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgSFRNTG9iaiA9IEhUTUxvYmoucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEhUTUxvYmo7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIF9hbmNlc3RvcigkZWxlbWVudFswXSkgPT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiB0aGUgdmlld3BvcnRcbiAgICAgICAgJC5mbi5pc19pbl92aWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBzY3JvbGx0b3AgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgPiAwID8gJCh3aW5kb3cpLnNjcm9sbFRvcCgpIDogJCgnYm9keScpLnNjcm9sbFRvcCgpO1xuXG4gICAgICAgICAgICBsZXQgJGVsZW1lbnQgPSB0aGlzO1xuXG4gICAgICAgICAgICBjb25zdCB0b3Bfb2ZfZWxlbWVudCA9ICRlbGVtZW50Lm9mZnNldCgpLnRvcDtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbV9vZl9lbGVtZW50ID0gJGVsZW1lbnQub2Zmc2V0KCkudG9wICsgJGVsZW1lbnQub3V0ZXJIZWlnaHQoKTtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbV9vZl9zY3JlZW4gPSBzY3JvbGx0b3AgKyAkKHdpbmRvdykuaW5uZXJIZWlnaHQoKTtcbiAgICAgICAgICAgIGNvbnN0IHRvcF9vZl9zY3JlZW4gPSBzY3JvbGx0b3A7XG5cbiAgICAgICAgICAgIGlmIChib3R0b21fb2Zfc2NyZWVuID4gdG9wX29mX2VsZW1lbnQgJiYgdG9wX29mX3NjcmVlbiA8IGJvdHRvbV9vZl9lbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXRzIHRoZSB0YWduYW1lIG9mIGEganF1ZXJ5IGVsZW1lbnRcbiAgICAgICAgJC5mbi50YWduYW1lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcCgndGFnTmFtZScpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJucyB0cnVlIGlmIGEgaHJlZiBpcyBub3Qgc2FtZSBkb21haW5cbiAgICAgICAgJC5mbi5pc19leHRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGhvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdDtcbiAgICAgICAgICAgIGNvbnN0IGxpbmsgPSAkKCc8YT4nLCB7XG4gICAgICAgICAgICAgICAgaHJlZjogdGhpcy5hdHRyKCdocmVmJyksXG4gICAgICAgICAgICB9KVswXS5ob3N0bmFtZTtcbiAgICAgICAgICAgIHJldHVybiBsaW5rICE9PSBob3N0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEhUTUw1IGZvcm0gdmFsaWRhdGlvbiB3cmFwcGVyc1xuICAgICAgICAkLmZuLmNoZWNrVmFsaWRpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLmNoZWNrVmFsaWRpdHkoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAkLmZuLnJlcG9ydFZhbGlkaXR5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1swXS5yZXBvcnRWYWxpZGl0eSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgICQuZm4ucmVxdWVzdFN1Ym1pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB0aGlzWzBdLnJlcXVlc3RTdWJtaXQoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEZpbmQgcmVsYXRlZCBjb21wb25lbnRzIGJ5IHNlYXJjaGluZyB1cCB0aGUgYW5jZXN0b3IgdHJlZVxuICAgICAgICAvLyBMaWtlIC5jbG9zZXN0KCkgYnV0IHNlYXJjaGVzIHdpdGhpbiBhbmNlc3RvcnMgaW5zdGVhZCBvZiBtYXRjaGluZyB0aGVtXG4gICAgICAgICQuZm4uY2xvc2VzdF9zaWJsaW5nID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICBsZXQgJGN1cnJlbnQgPSB0aGlzO1xuICAgICAgICAgICAgbGV0ICRwYXJlbnQgPSAkY3VycmVudC5wYXJlbnQoKTtcblxuICAgICAgICAgICAgLy8gS2VlcCBnb2luZyB1cCB0aGUgdHJlZSB1bnRpbCB3ZSBoaXQgYm9keVxuICAgICAgICAgICAgd2hpbGUgKCRwYXJlbnQubGVuZ3RoID4gMCAmJiAhJHBhcmVudC5pcygnYm9keScpKSB7XG4gICAgICAgICAgICAgICAgLy8gU2VhcmNoIHdpdGhpbiB0aGlzIHBhcmVudCBmb3IgdGhlIHNlbGVjdG9yXG4gICAgICAgICAgICAgICAgbGV0ICRmb3VuZCA9ICRwYXJlbnQuZmluZChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKCRmb3VuZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkZm91bmQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gTW92ZSB1cCBvbmUgbGV2ZWxcbiAgICAgICAgICAgICAgICAkcGFyZW50ID0gJHBhcmVudC5wYXJlbnQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgd2UgcmVhY2hlZCBib2R5LCBzZWFyY2ggd2l0aGluIGJvZHkgYXMgd2VsbFxuICAgICAgICAgICAgaWYgKCRwYXJlbnQuaXMoJ2JvZHknKSkge1xuICAgICAgICAgICAgICAgIGxldCAkZm91bmQgPSAkcGFyZW50LmZpbmQoc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgIGlmICgkZm91bmQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZvdW5kO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmV0dXJuIGVtcHR5IGpRdWVyeSBvYmplY3QgaWYgbm90aGluZyBmb3VuZFxuICAgICAgICAgICAgcmV0dXJuICQoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBPdmVycmlkZSAkLmFqYXggdG8gcHJldmVudCBkaXJlY3QgQUpBWCBjYWxscyB0byBsb2NhbCBzZXJ2ZXJcbiAgICAgICAgLy8gRGV2ZWxvcGVycyBtdXN0IHVzZSB0aGUgQWpheCBlbmRwb2ludCBwYXR0ZXJuOiBhd2FpdCBDb250cm9sbGVyLm1ldGhvZChwYXJhbXMpXG4gICAgICAgIGNvbnN0IG5hdGl2ZV9hamF4ID0gJC5hamF4O1xuICAgICAgICAkLmFqYXggPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYm90aCAkLmFqYXgodXJsLCBvcHRpb25zKSBhbmQgJC5hamF4KG9wdGlvbnMpIHNpZ25hdHVyZXNcbiAgICAgICAgICAgIGxldCBzZXR0aW5ncztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHNldHRpbmdzID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy51cmwgPSB1cmw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldHRpbmdzID0gdXJsIHx8IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgbG9jYWwgcmVxdWVzdCAocmVsYXRpdmUgVVJMIG9yIHNhbWUgZG9tYWluKVxuICAgICAgICAgICAgY29uc3QgcmVxdWVzdF91cmwgPSBzZXR0aW5ncy51cmwgfHwgJyc7XG4gICAgICAgICAgICBjb25zdCBpc19yZWxhdGl2ZSA9ICFyZXF1ZXN0X3VybC5tYXRjaCgvXmh0dHBzPzpcXC9cXC8vKTtcbiAgICAgICAgICAgIGNvbnN0IGlzX3NhbWVfZG9tYWluID0gcmVxdWVzdF91cmwuc3RhcnRzV2l0aCh3aW5kb3cubG9jYXRpb24ub3JpZ2luKTtcbiAgICAgICAgICAgIGNvbnN0IGlzX2xvY2FsX3JlcXVlc3QgPSBpc19yZWxhdGl2ZSB8fCBpc19zYW1lX2RvbWFpbjtcblxuICAgICAgICAgICAgLy8gQWxsb3cgZnJhbWV3b3JrIEFqYXguY2FsbCgpIHRvIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuX19sb2NhbF9pbnRlZ3JhdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVfYWpheC5jYWxsKHRoaXMsIHNldHRpbmdzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxsb3cgZmlsZSB1cGxvYWQgZW5kcG9pbnQgLSByZXF1aXJlcyBuYXRpdmUgJC5hamF4IGZvciBGb3JtRGF0YSBzdXBwb3J0XG4gICAgICAgICAgICBjb25zdCBpc19maWxlX3VwbG9hZCA9IHJlcXVlc3RfdXJsID09PSAnL191cGxvYWQnIHx8IHJlcXVlc3RfdXJsLmVuZHNXaXRoKCcvX3VwbG9hZCcpO1xuICAgICAgICAgICAgaWYgKGlzX2ZpbGVfdXBsb2FkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZV9hamF4LmNhbGwodGhpcywgc2V0dGluZ3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBCbG9jayBsb2NhbCBBSkFYIHJlcXVlc3RzIHRoYXQgZG9uJ3QgdXNlIHRoZSBBamF4IGVuZHBvaW50IHBhdHRlcm5cbiAgICAgICAgICAgIGlmIChpc19sb2NhbF9yZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHBhcnNlIGNvbnRyb2xsZXIgYW5kIGFjdGlvbiBmcm9tIFVSTFxuICAgICAgICAgICAgICAgIGxldCBjb250cm9sbGVyX25hbWUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGxldCBhY3Rpb25fbmFtZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsX21hdGNoID0gcmVxdWVzdF91cmwubWF0Y2goL1xcL19yc3hfYXBpXFwvKFteXFwvXSspXFwvKFteXFwvXFw/XSspLyk7XG4gICAgICAgICAgICAgICAgaWYgKHVybF9tYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyX25hbWUgPSB1cmxfbWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbl9uYW1lID0gdXJsX21hdGNoWzJdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBlcnJvcl9tZXNzYWdlID0gJ0FKQVggcmVxdWVzdHMgdG8gbG9jYWxob3N0IHZpYSAkLmFqYXgoKSBhcmUgcHJvaGliaXRlZC5cXG5cXG4nO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRyb2xsZXJfbmFtZSAmJiBhY3Rpb25fbmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGBJbnN0ZWFkIG9mOlxcbmA7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYCAgJC5hamF4KHt1cmw6ICcke3JlcXVlc3RfdXJsfScsIC4uLn0pXFxuXFxuYDtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgVXNlOlxcbmA7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYCAgYXdhaXQgJHtjb250cm9sbGVyX25hbWV9LiR7YWN0aW9uX25hbWV9KHBhcmFtZXRlcnMpXFxuXFxuYDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGBVc2UgdGhlIEFqYXggZW5kcG9pbnQgcGF0dGVybjpcXG5gO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGAgIGF3YWl0IENvbnRyb2xsZXJfTmFtZS5hY3Rpb25fbmFtZShwYXJhbWV0ZXJzKVxcblxcbmA7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgVGhlIGNvbnRyb2xsZXIgbWV0aG9kIG11c3QgaGF2ZSB0aGUgI1tBamF4X0VuZHBvaW50XSBhdHRyaWJ1dGUuYDtcblxuICAgICAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbihlcnJvcl9tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxsb3cgZXh0ZXJuYWwgcmVxdWVzdHMgKGRpZmZlcmVudCBkb21haW4pXG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlX2FqYXguY2FsbCh0aGlzLCBzZXR0aW5ncyk7XG4gICAgICAgIH07XG4gICAgfVxufSIsIi8vIEBST1VURS1FWElTVFMtMDEtRVhDRVBUSU9OIC0gVGhpcyBmaWxlIGNvbnRhaW5zIGRvY3VtZW50YXRpb24gZXhhbXBsZXMgd2l0aCBmaWN0aW9uYWwgcm91dGUgbmFtZXNcblxuLyoqXG4gKiBSc3ggLSBDb3JlIEphdmFTY3JpcHQgUnVudGltZSBTeXN0ZW1cbiAqXG4gKiBUaGUgUnN4IGNsYXNzIGlzIHRoZSBjZW50cmFsIGh1YiBmb3IgdGhlIFJTWCBKYXZhU2NyaXB0IHJ1bnRpbWUsIHByb3ZpZGluZyBlc3NlbnRpYWxcbiAqIHN5c3RlbS1sZXZlbCB1dGlsaXRpZXMgdGhhdCBhbGwgb3RoZXIgZnJhbWV3b3JrIGNvbXBvbmVudHMgZGVwZW5kIG9uLiBJdCBzZXJ2ZXMgYXMgdGhlXG4gKiBmb3VuZGF0aW9uIGZvciB0aGUgY2xpZW50LXNpZGUgZnJhbWV3b3JrLCBoYW5kbGluZyBjb3JlIG9wZXJhdGlvbnMgdGhhdCBtdXN0IGJlIGdsb2JhbGx5XG4gKiBhY2Nlc3NpYmxlIGFuZCBjb25zaXN0ZW50bHkgYXZhaWxhYmxlLlxuICpcbiAqIENvcmUgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gRXZlbnQgU3lzdGVtOiBBcHBsaWNhdGlvbi13aWRlIGV2ZW50IGJ1cyBmb3IgZnJhbWV3b3JrIGxpZmVjeWNsZSBhbmQgY3VzdG9tIGV2ZW50c1xuICogLSBFbnZpcm9ubWVudCBEZXRlY3Rpb246IFJ1bnRpbWUgZW52aXJvbm1lbnQgaWRlbnRpZmljYXRpb24gKGRldi9wcm9kdWN0aW9uKVxuICogLSBSb3V0ZSBNYW5hZ2VtZW50OiBUeXBlLXNhZmUgcm91dGUgZ2VuZXJhdGlvbiBhbmQgVVJMIGJ1aWxkaW5nXG4gKiAtIFVuaXF1ZSBJRCBHZW5lcmF0aW9uOiBDbGllbnQtc2lkZSB1bmlxdWUgaWRlbnRpZmllciBnZW5lcmF0aW9uXG4gKiAtIEZyYW1ld29yayBCb290c3RyYXA6IE11bHRpLXBoYXNlIGluaXRpYWxpemF0aW9uIG9yY2hlc3RyYXRpb25cbiAqIC0gTG9nZ2luZzogQ2VudHJhbGl6ZWQgbG9nZ2luZyBpbnRlcmZhY2UgKGRlbGVnYXRlcyB0byBjb25zb2xlX2RlYnVnKVxuICpcbiAqIFRoZSBSc3ggY2xhc3MgZGVsaWJlcmF0ZWx5IGtlZXBzIGl0cyBzY29wZSBsaW1pdGVkIHRvIGNvcmUgdXRpbGl0aWVzLiBBZHZhbmNlZCBmZWF0dXJlc1xuICogYXJlIGRlbGVnYXRlZCB0byBzcGVjaWFsaXplZCBjbGFzc2VzOlxuICogLSBNYW5pZmVzdCBvcGVyYXRpb25zIOKGkiBNYW5pZmVzdCBjbGFzc1xuICogLSBDYWNoaW5nIOKGkiBSc3hfQ2FjaGUgY2xhc3NcbiAqIC0gQUpBWC9BUEkgY2FsbHMg4oaSIEFqYXhfKiBjbGFzc2VzXG4gKiAtIFJvdXRlIHByb3hpZXMg4oaSIFJzeF9Sb3V0ZV9Qcm94eSBjbGFzc1xuICogLSBCZWhhdmlvcnMg4oaSIFJzeF9CZWhhdmlvcnMgY2xhc3NcbiAqXG4gKiBBbGwgbWV0aG9kcyBhcmUgc3RhdGljIC0gUnN4IGlzIG5ldmVyIGluc3RhbnRpYXRlZC4gSXQncyBhdmFpbGFibGUgZ2xvYmFsbHkgZnJvbSB0aGVcbiAqIG1vbWVudCBidW5kbGVzIGxvYWQgYW5kIHJlbWFpbnMgY29uc3RhbnQgdGhyb3VnaG91dCB0aGUgYXBwbGljYXRpb24gbGlmZWN5Y2xlLlxuICpcbiAqIFVzYWdlIEV4YW1wbGVzOlxuICogYGBgamF2YXNjcmlwdFxuICogLy8gRXZlbnQgc3lzdGVtXG4gKiBSc3gub24oJ2FwcF9yZWFkeScsICgpID0+IGNvbnNvbGUubG9nKCdBcHAgaW5pdGlhbGl6ZWQnKSk7XG4gKiBSc3gudHJpZ2dlcignY3VzdG9tX2V2ZW50Jywge2RhdGE6ICd2YWx1ZSd9KTtcbiAqXG4gKiAvLyBFbnZpcm9ubWVudCBkZXRlY3Rpb25cbiAqIGlmIChSc3guaXNfZGV2KCkpIHsgY29uc29sZS5sb2coJ0RldmVsb3BtZW50IG1vZGUnKTsgfVxuICpcbiAqIC8vIFJvdXRlIGdlbmVyYXRpb25cbiAqIGNvbnN0IHVybCA9IFJzeC5Sb3V0ZSgnQ29udHJvbGxlcicsICdhY3Rpb24nKS51cmwoKTtcbiAqXG4gKiAvLyBVbmlxdWUgSURzXG4gKiBjb25zdCB1bmlxdWVJZCA9IFJzeC51aWQoKTsgLy8gZS5nLiwgXCJyc3hfMTIzNDU2Nzg5MF8xXCJcbiAqIGBgYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBnbG9iYWxcbiAqL1xuY2xhc3MgUnN4IHtcbiAgICAvLyBHZXRzIHNldCB0byB0cnVlIHRvIGludGVydXB0IHN0YXJ0dXAgc2VxdWVuY2VcbiAgICBzdGF0aWMgX19zdG9wcGVkID0gZmFsc2U7XG5cbiAgICAvLyBJbml0aWFsaXplIGV2ZW50IGhhbmRsZXJzIHN0b3JhZ2VcbiAgICBzdGF0aWMgX2luaXRfZXZlbnRzKCkge1xuICAgICAgICBpZiAodHlwZW9mIFJzeC5fZXZlbnRfaGFuZGxlcnMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBSc3guX2V2ZW50X2hhbmRsZXJzID0ge307XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBSc3guX3RyaWdnZXJlZF9ldmVudHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBSc3guX3RyaWdnZXJlZF9ldmVudHMgPSB7fTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlZ2lzdGVyIGFuIGV2ZW50IGhhbmRsZXJcbiAgICBzdGF0aWMgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIFJzeC5faW5pdF9ldmVudHMoKTtcblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFSc3guX2V2ZW50X2hhbmRsZXJzW2V2ZW50XSkge1xuICAgICAgICAgICAgUnN4Ll9ldmVudF9oYW5kbGVyc1tldmVudF0gPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIFJzeC5fZXZlbnRfaGFuZGxlcnNbZXZlbnRdLnB1c2goY2FsbGJhY2spO1xuXG4gICAgICAgIC8vIElmIHRoaXMgZXZlbnQgd2FzIGFscmVhZHkgdHJpZ2dlcmVkLCBjYWxsIHRoZSBjYWxsYmFjayBpbW1lZGlhdGVseVxuICAgICAgICBpZiAoUnN4Ll90cmlnZ2VyZWRfZXZlbnRzW2V2ZW50XSkge1xuICAgICAgICAgICAgY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCAnVHJpZ2dlcmluZyAnICsgZXZlbnQgKyAnIGZvciBsYXRlIHJlZ2lzdGVyZWQgY2FsbGJhY2snKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKFJzeC5fdHJpZ2dlcmVkX2V2ZW50c1tldmVudF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVHJpZ2dlciBhbiBldmVudCB3aXRoIG9wdGlvbmFsIGRhdGFcbiAgICBzdGF0aWMgdHJpZ2dlcihldmVudCwgZGF0YSA9IHt9KSB7XG4gICAgICAgIFJzeC5faW5pdF9ldmVudHMoKTtcblxuICAgICAgICAvLyBSZWNvcmQgdGhhdCB0aGlzIGV2ZW50IHdhcyB0cmlnZ2VyZWRcbiAgICAgICAgUnN4Ll90cmlnZ2VyZWRfZXZlbnRzW2V2ZW50XSA9IGRhdGE7XG5cbiAgICAgICAgaWYgKCFSc3guX2V2ZW50X2hhbmRsZXJzW2V2ZW50XSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCAnVHJpZ2dlcmluZyAnICsgZXZlbnQgKyAnIGZvciAnICsgUnN4Ll9ldmVudF9oYW5kbGVyc1tldmVudF0ubGVuZ3RoICsgJyBjYWxsYmFja3MnKTtcblxuICAgICAgICAvLyBDYWxsIGFsbCByZWdpc3RlcmVkIGhhbmRsZXJzIGZvciB0aGlzIGV2ZW50IGluIG9yZGVyXG4gICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgUnN4Ll9ldmVudF9oYW5kbGVyc1tldmVudF0pIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGRhdGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWxpYXMgZm9yIHRyaWdnZXIucmVmcmVzaCgnJyksIHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgbWFqb3IgVUkgdXBkYXRlcyB0byBhcHBseSBzdWNoIGVmZmVjdHMgYXNcbiAgICAvLyB1bmRlcmxpbmluZyBsaW5rcyB0byB1bmltcGxlbWVudGVkICMgcm91dGVzXG4gICAgc3RhdGljIHRyaWdnZXJfcmVmcmVzaCgpIHtcbiAgICAgICAgLy8gVXNlIFJzeC5vbigncmVmcmVzaCcsIGNhbGxiYWNrKTsgdG8gcmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgcmVmcmVzaFxuICAgICAgICB0aGlzLnRyaWdnZXIoJ3JlZnJlc2gnKTtcbiAgICB9XG5cbiAgICAvLyBMb2cgdG8gc2VydmVyIHRoYXQgYW4gZXZlbnQgaGFwcGVuZWRcbiAgICBzdGF0aWMgbG9nKHR5cGUsIG1lc3NhZ2UgPSAnbm90aWNlJykge1xuICAgICAgICBDb3JlX0xvZy5sb2codHlwZSwgbWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBhcHAgaXMgYmVpbmcgcnVuIGluIGRldiBtb2RlXG4gICAgLy8gVGhpcyBzaG91bGQgYWZmZWN0IGNhY2hpbmcgYW5kIHNvbWUgZGVidWcgY2hlY2tzXG4gICAgc3RhdGljIGlzX2RldigpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5yc3hhcHAuZGVidWc7XG4gICAgfVxuXG4gICAgc3RhdGljIGlzX3Byb2QoKSB7XG4gICAgICAgIHJldHVybiAhd2luZG93LnJzeGFwcC5kZWJ1ZztcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZXMgYSB1bmlxdWUgbnVtYmVyIGZvciB0aGUgYXBwbGljYXRpb24gaW5zdGFuY2VcbiAgICBzdGF0aWMgdWlkKCkge1xuICAgICAgICBpZiAodHlwZW9mIFJzeC5fdWlkID09IHVuZGVmKSB7XG4gICAgICAgICAgICBSc3guX3VpZCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJzeC5fdWlkKys7XG4gICAgfVxuXG4gICAgLy8gU3RvcmFnZSBmb3Igcm91dGUgZGVmaW5pdGlvbnMgbG9hZGVkIGZyb20gYnVuZGxlc1xuICAgIHN0YXRpYyBfcm91dGVzID0ge307XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmUgcm91dGVzIGZyb20gYnVuZGxlZCBkYXRhXG4gICAgICogQ2FsbGVkIGJ5IGdlbmVyYXRlZCBKYXZhU2NyaXB0IGluIGJ1bmRsZXNcbiAgICAgKi9cbiAgICBzdGF0aWMgX2RlZmluZV9yb3V0ZXMocm91dGVzKSB7XG4gICAgICAgIC8vIE1lcmdlIHJvdXRlcyBpbnRvIHRoZSBnbG9iYWwgcm91dGUgc3RvcmFnZVxuICAgICAgICBmb3IgKGNvbnN0IGNsYXNzX25hbWUgaW4gcm91dGVzKSB7XG4gICAgICAgICAgICBpZiAoIVJzeC5fcm91dGVzW2NsYXNzX25hbWVdKSB7XG4gICAgICAgICAgICAgICAgUnN4Ll9yb3V0ZXNbY2xhc3NfbmFtZV0gPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgbWV0aG9kX25hbWUgaW4gcm91dGVzW2NsYXNzX25hbWVdKSB7XG4gICAgICAgICAgICAgICAgUnN4Ll9yb3V0ZXNbY2xhc3NfbmFtZV1bbWV0aG9kX25hbWVdID0gcm91dGVzW2NsYXNzX25hbWVdW21ldGhvZF9uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIFVSTCBmb3IgYSBjb250cm9sbGVyIHJvdXRlXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBnZW5lcmF0ZXMgVVJMcyBmb3IgY29udHJvbGxlciBhY3Rpb25zIGJ5IGxvb2tpbmcgdXAgcm91dGUgcGF0dGVybnNcbiAgICAgKiBhbmQgcmVwbGFjaW5nIHBhcmFtZXRlcnMuIEl0IGhhbmRsZXMgYm90aCByZWd1bGFyIHJvdXRlcyBhbmQgQWpheCBlbmRwb2ludHMuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgcm91dGUgaXMgbm90IGZvdW5kIGluIHRoZSByb3V0ZSBkZWZpbml0aW9ucywgYSBkZWZhdWx0IHBhdHRlcm4gaXMgdXNlZDpcbiAgICAgKiBgL18ve2NvbnRyb2xsZXJ9L3thY3Rpb259YCB3aXRoIGFsbCBwYXJhbWV0ZXJzIGFwcGVuZGVkIGFzIHF1ZXJ5IHN0cmluZ3MuXG4gICAgICpcbiAgICAgKiBVc2FnZSBleGFtcGxlczpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogLy8gU2ltcGxlIHJvdXRlIHdpdGhvdXQgcGFyYW1ldGVycyAoZGVmYXVsdHMgdG8gJ2luZGV4JyBhY3Rpb24pXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGcm9udGVuZF9JbmRleF9Db250cm9sbGVyJyk7XG4gICAgICogLy8gUmV0dXJuczogL2Rhc2hib2FyZFxuICAgICAqXG4gICAgICogLy8gUm91dGUgd2l0aCBleHBsaWNpdCBhY3Rpb25cbiAgICAgKiBjb25zdCB1cmwgPSBSc3guUm91dGUoJ0Zyb250ZW5kX0luZGV4X0NvbnRyb2xsZXInLCAnaW5kZXgnKTtcbiAgICAgKiAvLyBSZXR1cm5zOiAvZGFzaGJvYXJkXG4gICAgICpcbiAgICAgKiAvLyBSb3V0ZSB3aXRoIGludGVnZXIgcGFyYW1ldGVyIChzZXRzICdpZCcpXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRfVmlld19Db250cm9sbGVyJywgJ3ZpZXcnLCAxMjMpO1xuICAgICAqIC8vIFJldHVybnM6IC9jbGllbnRzL3ZpZXcvMTIzXG4gICAgICpcbiAgICAgKiAvLyBSb3V0ZSB3aXRoIG5hbWVkIHBhcmFtZXRlcnMgKG9iamVjdClcbiAgICAgKiBjb25zdCB1cmwgPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NsaWVudF9WaWV3X0NvbnRyb2xsZXInLCAndmlldycsIHtpZDogJ0MwMDEnfSk7XG4gICAgICogLy8gUmV0dXJuczogL2NsaWVudHMvdmlldy9DMDAxXG4gICAgICpcbiAgICAgKiAvLyBSb3V0ZSB3aXRoIHJlcXVpcmVkIGFuZCBxdWVyeSBwYXJhbWV0ZXJzXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRfVmlld19Db250cm9sbGVyJywgJ3ZpZXcnLCB7XG4gICAgICogICAgIGlkOiAnQzAwMScsXG4gICAgICogICAgIHRhYjogJ2hpc3RvcnknXG4gICAgICogfSk7XG4gICAgICogLy8gUmV0dXJuczogL2NsaWVudHMvdmlldy9DMDAxP3RhYj1oaXN0b3J5XG4gICAgICpcbiAgICAgKiAvLyBSb3V0ZSBub3QgZm91bmQgLSB1c2VzIGRlZmF1bHQgcGF0dGVyblxuICAgICAqIGNvbnN0IHVybCA9IFJzeC5Sb3V0ZSgnVW5pbXBsZW1lbnRlZF9Db250cm9sbGVyJywgJ3NvbWVfYWN0aW9uJywge2ZvbzogJ2Jhcid9KTtcbiAgICAgKiAvLyBSZXR1cm5zOiAvXy9VbmltcGxlbWVudGVkX0NvbnRyb2xsZXIvc29tZV9hY3Rpb24/Zm9vPWJhclxuICAgICAqXG4gICAgICogLy8gUGxhY2Vob2xkZXIgcm91dGVcbiAgICAgKiBjb25zdCB1cmwgPSBSc3guUm91dGUoJ0Z1dHVyZV9Db250cm9sbGVyJywgJyNpbmRleCcpO1xuICAgICAqIC8vIFJldHVybnM6ICNcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc19uYW1lIFRoZSBjb250cm9sbGVyIGNsYXNzIG5hbWUgKGUuZy4sICdVc2VyX0NvbnRyb2xsZXInKVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbYWN0aW9uX25hbWU9J2luZGV4J10gVGhlIGFjdGlvbi9tZXRob2QgbmFtZSAoZGVmYXVsdHMgdG8gJ2luZGV4JykuIFVzZSAnI2FjdGlvbicgZm9yIHBsYWNlaG9sZGVycy5cbiAgICAgKiBAcGFyYW0ge251bWJlcnxPYmplY3R9IFtwYXJhbXM9bnVsbF0gUm91dGUgcGFyYW1ldGVycy4gSW50ZWdlciBzZXRzICdpZCcsIG9iamVjdCBwcm92aWRlcyBuYW1lZCBwYXJhbXMuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGdlbmVyYXRlZCBVUkxcbiAgICAgKi9cbiAgICBzdGF0aWMgUm91dGUoY2xhc3NfbmFtZSwgYWN0aW9uX25hbWUgPSAnaW5kZXgnLCBwYXJhbXMgPSBudWxsKSB7XG4gICAgICAgIC8vIE5vcm1hbGl6ZSBwYXJhbXMgdG8gb2JqZWN0XG4gICAgICAgIGxldCBwYXJhbXNfb2JqID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW1zID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcGFyYW1zX29iaiA9IHsgaWQ6IHBhcmFtcyB9O1xuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcGFyYW1zX29iaiA9IHBhcmFtcztcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbXMgIT09IG51bGwgJiYgcGFyYW1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1zIG11c3QgYmUgbnVtYmVyLCBvYmplY3QsIG9yIG51bGwnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBsYWNlaG9sZGVyIHJvdXRlOiBhY3Rpb24gc3RhcnRzIHdpdGggIyBtZWFucyB1bmltcGxlbWVudGVkL3NjYWZmb2xkaW5nXG4gICAgICAgIGlmIChhY3Rpb25fbmFtZS5zdGFydHNXaXRoKCcjJykpIHtcbiAgICAgICAgICAgIHJldHVybiAnIyc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiByb3V0ZSBleGlzdHMgaW4gZGVmaW5pdGlvbnNcbiAgICAgICAgbGV0IHBhdHRlcm47XG4gICAgICAgIGlmIChSc3guX3JvdXRlc1tjbGFzc19uYW1lXSAmJiBSc3guX3JvdXRlc1tjbGFzc19uYW1lXVthY3Rpb25fbmFtZV0pIHtcbiAgICAgICAgICAgIHBhdHRlcm4gPSBSc3guX3JvdXRlc1tjbGFzc19uYW1lXVthY3Rpb25fbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSb3V0ZSBub3QgZm91bmQgLSB1c2UgZGVmYXVsdCBwYXR0ZXJuIC9fL3tjb250cm9sbGVyfS97YWN0aW9ufVxuICAgICAgICAgICAgcGF0dGVybiA9IGAvXy8ke2NsYXNzX25hbWV9LyR7YWN0aW9uX25hbWV9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdlbmVyYXRlIFVSTCBmcm9tIHBhdHRlcm5cbiAgICAgICAgcmV0dXJuIFJzeC5fZ2VuZXJhdGVfdXJsX2Zyb21fcGF0dGVybihwYXR0ZXJuLCBwYXJhbXNfb2JqKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBVUkwgZnJvbSByb3V0ZSBwYXR0ZXJuIGJ5IHJlcGxhY2luZyBwYXJhbWV0ZXJzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0dGVybiBUaGUgcm91dGUgcGF0dGVybiAoZS5nLiwgJy91c2Vycy86aWQvdmlldycpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBQYXJhbWV0ZXJzIHRvIGZpbGwgaW50byB0aGUgcm91dGVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIFVSTFxuICAgICAqL1xuICAgIHN0YXRpYyBfZ2VuZXJhdGVfdXJsX2Zyb21fcGF0dGVybihwYXR0ZXJuLCBwYXJhbXMpIHtcbiAgICAgICAgLy8gRXh0cmFjdCByZXF1aXJlZCBwYXJhbWV0ZXJzIGZyb20gdGhlIHBhdHRlcm5cbiAgICAgICAgY29uc3QgcmVxdWlyZWRfcGFyYW1zID0gW107XG4gICAgICAgIGNvbnN0IG1hdGNoZXMgPSBwYXR0ZXJuLm1hdGNoKC86KFthLXpBLVpfXVthLXpBLVowLTlfXSopL2cpO1xuICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSA6IHByZWZpeCBmcm9tIGVhY2ggbWF0Y2hcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgbWF0Y2hlcykge1xuICAgICAgICAgICAgICAgIHJlcXVpcmVkX3BhcmFtcy5wdXNoKG1hdGNoLnN1YnN0cmluZygxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgcmVxdWlyZWQgcGFyYW1ldGVyc1xuICAgICAgICBjb25zdCBtaXNzaW5nID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWlyZWQgb2YgcmVxdWlyZWRfcGFyYW1zKSB7XG4gICAgICAgICAgICBpZiAoIShyZXF1aXJlZCBpbiBwYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgbWlzc2luZy5wdXNoKHJlcXVpcmVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtaXNzaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVxdWlyZWQgcGFyYW1ldGVycyBbJHttaXNzaW5nLmpvaW4oJywgJyl9XSBhcmUgbWlzc2luZyBmb3Igcm91dGUgJHtwYXR0ZXJufWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQnVpbGQgdGhlIFVSTCBieSByZXBsYWNpbmcgcGFyYW1ldGVyc1xuICAgICAgICBsZXQgdXJsID0gcGF0dGVybjtcbiAgICAgICAgY29uc3QgdXNlZF9wYXJhbXMgPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IHBhcmFtX25hbWUgb2YgcmVxdWlyZWRfcGFyYW1zKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcmFtc1twYXJhbV9uYW1lXTtcbiAgICAgICAgICAgIC8vIFVSTCBlbmNvZGUgdGhlIHZhbHVlXG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkX3ZhbHVlID0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcbiAgICAgICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCc6JyArIHBhcmFtX25hbWUsIGVuY29kZWRfdmFsdWUpO1xuICAgICAgICAgICAgdXNlZF9wYXJhbXNbcGFyYW1fbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29sbGVjdCBhbnkgZXh0cmEgcGFyYW1ldGVycyBmb3IgcXVlcnkgc3RyaW5nXG4gICAgICAgIGNvbnN0IHF1ZXJ5X3BhcmFtcyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcbiAgICAgICAgICAgIGlmICghdXNlZF9wYXJhbXNba2V5XSkge1xuICAgICAgICAgICAgICAgIHF1ZXJ5X3BhcmFtc1trZXldID0gcGFyYW1zW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBlbmQgcXVlcnkgc3RyaW5nIGlmIHRoZXJlIGFyZSBleHRyYSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhxdWVyeV9wYXJhbXMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5X3N0cmluZyA9IE9iamVjdC5lbnRyaWVzKHF1ZXJ5X3BhcmFtcylcbiAgICAgICAgICAgICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2VuY29kZVVSSUNvbXBvbmVudChrZXkpfT0ke2VuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSl9YClcbiAgICAgICAgICAgICAgICAuam9pbignJicpO1xuICAgICAgICAgICAgdXJsICs9ICc/JyArIHF1ZXJ5X3N0cmluZztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IENhbGwgYSBzcGVjaWZpYyBtZXRob2Qgb24gYWxsIGNsYXNzZXMgdGhhdCBoYXZlIGl0XG4gICAgICogQ29sbGVjdHMgcHJvbWlzZXMgZnJvbSByZXR1cm4gdmFsdWVzIGFuZCB3YWl0cyBmb3IgYWxsIHRvIHJlc29sdmVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kX25hbWUgVGhlIG1ldGhvZCBuYW1lIHRvIGNhbGwgb24gYWxsIGNsYXNzZXNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIG1ldGhvZCBjYWxscyBjb21wbGV0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfcnN4X2NhbGxfYWxsX2NsYXNzZXMobWV0aG9kX25hbWUpIHtcbiAgICAgICAgY29uc3QgYWxsX2NsYXNzZXMgPSBNYW5pZmVzdC5nZXRfYWxsX2NsYXNzZXMoKTtcbiAgICAgICAgY29uc3QgY2xhc3Nlc193aXRoX21ldGhvZCA9IFtdO1xuICAgICAgICBjb25zdCBwcm9taXNlX3BpbGUgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGNsYXNzX2luZm8gb2YgYWxsX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzX29iamVjdCA9IGNsYXNzX2luZm8uY2xhc3Nfb2JqZWN0O1xuICAgICAgICAgICAgY29uc3QgY2xhc3NfbmFtZSA9IGNsYXNzX2luZm8uY2xhc3NfbmFtZTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBjbGFzcyBoYXMgdGhlIG1ldGhvZCAoc3RhdGljIG1ldGhvZHMgYXJlIG9uIHRoZSBjbGFzcyBpdHNlbGYpXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNsYXNzX29iamVjdFttZXRob2RfbmFtZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBjbGFzc2VzX3dpdGhfbWV0aG9kLnB1c2goY2xhc3NfbmFtZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmV0dXJuX3ZhbHVlID0gYXdhaXQgY2xhc3Nfb2JqZWN0W21ldGhvZF9uYW1lXSgpO1xuXG4gICAgICAgICAgICAgICAgLy8gQ29sbGVjdCBwcm9taXNlcyBmcm9tIHJldHVybiB2YWx1ZVxuICAgICAgICAgICAgICAgIGlmIChyZXR1cm5fdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VfcGlsZS5wdXNoKHJldHVybl92YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJldHVybl92YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJldHVybl92YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZV9waWxlLnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoUnN4Ll9fc3RvcHBlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNsYXNzZXNfd2l0aF9tZXRob2QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCBgJHttZXRob2RfbmFtZX06ICR7Y2xhc3Nlc193aXRoX21ldGhvZC5sZW5ndGh9IGNsYXNzZXNgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEF3YWl0IGFsbCBwcm9taXNlcyBiZWZvcmUgcmV0dXJuaW5nXG4gICAgICAgIGlmIChwcm9taXNlX3BpbGUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCBgJHttZXRob2RfbmFtZX06IEF3YWl0aW5nICR7cHJvbWlzZV9waWxlLmxlbmd0aH0gcHJvbWlzZXNgKTtcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VfcGlsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogRXhlY3V0ZSBtdWx0aS1waGFzZSBpbml0aWFsaXphdGlvbiBmb3IgYWxsIHJlZ2lzdGVyZWQgY2xhc3Nlc1xuICAgICAqIFRoaXMgcnVucyB2YXJpb3VzIGluaXRpYWxpemF0aW9uIHBoYXNlcyBpbiBvcmRlciB0byBwcm9wZXJseSBzZXQgdXAgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBpbml0aWFsaXphdGlvbiBwaGFzZXMgY29tcGxldGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX3JzeF9jb3JlX2Jvb3QoKSB7XG4gICAgICAgIGlmIChSc3guX19ib290ZWQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JzeC5fcnN4X2NvcmVfYm9vdCBjYWxsZWQgbW9yZSB0aGFuIG9uY2UnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIFJzeC5fX2Jvb3RlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gR2V0IGFsbCByZWdpc3RlcmVkIGNsYXNzZXMgZnJvbSB0aGUgbWFuaWZlc3RcbiAgICAgICAgY29uc3QgYWxsX2NsYXNzZXMgPSBNYW5pZmVzdC5nZXRfYWxsX2NsYXNzZXMoKTtcblxuICAgICAgICBjb25zb2xlX2RlYnVnKCdSU1hfSU5JVCcsIGBTdGFydGluZyBfcnN4X2NvcmVfYm9vdCB3aXRoICR7YWxsX2NsYXNzZXMubGVuZ3RofSBjbGFzc2VzYCk7XG5cbiAgICAgICAgaWYgKCFhbGxfY2xhc3NlcyB8fCBhbGxfY2xhc3Nlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIE5vIGNsYXNzZXMgdG8gaW5pdGlhbGl6ZVxuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdObyBjbGFzc2VzIHJlZ2lzdGVyZWQgaW4ganMgLSB0aGVyZSBzaG91bGQgYmUgYXQgbGVhc3QgdGhlIGNvcmUgZnJhbWV3b3JrIGNsYXNzZXMnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERlZmluZSBpbml0aWFsaXphdGlvbiBwaGFzZXMgaW4gb3JkZXJcbiAgICAgICAgY29uc3QgcGhhc2VzID0gW1xuICAgICAgICAgICAgeyBldmVudDogJ2ZyYW1ld29ya19jb3JlX2RlZmluZScsIG1ldGhvZDogJ19vbl9mcmFtZXdvcmtfY29yZV9kZWZpbmUnIH0sXG4gICAgICAgICAgICB7IGV2ZW50OiAnZnJhbWV3b3JrX21vZHVsZXNfZGVmaW5lJywgbWV0aG9kOiAnX29uX2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZScgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdmcmFtZXdvcmtfY29yZV9pbml0JywgbWV0aG9kOiAnX29uX2ZyYW1ld29ya19jb3JlX2luaXQnIH0sXG4gICAgICAgICAgICB7IGV2ZW50OiAnYXBwX21vZHVsZXNfZGVmaW5lJywgbWV0aG9kOiAnb25fYXBwX21vZHVsZXNfZGVmaW5lJyB9LFxuICAgICAgICAgICAgeyBldmVudDogJ2FwcF9kZWZpbmUnLCBtZXRob2Q6ICdvbl9hcHBfZGVmaW5lJyB9LFxuICAgICAgICAgICAgeyBldmVudDogJ2ZyYW1ld29ya19tb2R1bGVzX2luaXQnLCBtZXRob2Q6ICdfb25fZnJhbWV3b3JrX21vZHVsZXNfaW5pdCcgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdhcHBfbW9kdWxlc19pbml0JywgbWV0aG9kOiAnb25fYXBwX21vZHVsZXNfaW5pdCcgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdhcHBfaW5pdCcsIG1ldGhvZDogJ29uX2FwcF9pbml0JyB9LFxuICAgICAgICAgICAgeyBldmVudDogJ2FwcF9yZWFkeScsIG1ldGhvZDogJ29uX2FwcF9yZWFkeScgfSxcbiAgICAgICAgXTtcblxuICAgICAgICAvLyBFeGVjdXRlIGVhY2ggcGhhc2UgaW4gb3JkZXJcbiAgICAgICAgZm9yIChjb25zdCBwaGFzZSBvZiBwaGFzZXMpIHtcbiAgICAgICAgICAgIGF3YWl0IFJzeC5fcnN4X2NhbGxfYWxsX2NsYXNzZXMocGhhc2UubWV0aG9kKTtcblxuICAgICAgICAgICAgaWYgKFJzeC5fX3N0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIFJzeC50cmlnZ2VyKHBoYXNlLmV2ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVpIHJlZnJlc2ggY2FsbGJhY2tzXG4gICAgICAgIFJzeC50cmlnZ2VyX3JlZnJlc2goKTtcblxuICAgICAgICAvLyBBbGwgcGhhc2VzIGNvbXBsZXRlXG4gICAgICAgIGNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgJ0luaXRpYWxpemF0aW9uIGNvbXBsZXRlJyk7XG5cbiAgICAgICAgLy8gVE9ETzogRmluZCBhIGdvb2Qgd2FpdCB0byB3YWl0IGZvciBhbGwganFodG1sIGNvbXBvbmVudHMgdG8gbG9hZCwgdGhlbiB0cmlnZ2VyIG9uX3JlYWR5IGFuZCBvbigncmVhZHknKSBlbXVsYXRpbmcgdGhlIHRvcCBsZXZlbCBsYXN0IHN5bnRheCB0aGF0IGpxaHRtbCBjb21wb25lbnRzIG9wZXJhdGVhcywgYnV0IGFzIGEgc3RhbmRhcmQganMgY2xhc3MgKHN1Y2ggYXMgYSBwYWdlIGNsYXNzKS4gIFRoZSBiaWdnZXN0IHF1ZXN0aW9uIGlzLCBob3cgZG8gd2UgZWZmaWNpZW50bHkgY2hvb3NlIG9ubHkgdGhlIHRvcCBsZXZlbCBqcWh0bWwgY29tcG9uZW50cy4gIGRvIHdlIG9ubHkgY29uc2lkZXIgY29tcG9uZW50cyBjcmV0YWVkIGRpcmVjdGx5IG9uIGJsYWRlIHRlbXBsYXRlcz8gdGhhdCBzZWFtcyByZWFzb25hYmxlLi4uXG5cbiAgICAgICAgLy8gVHJpZ2dlciBfZGVidWdfcmVhZHkgZXZlbnQgLSB0aGlzIGlzIE9OTFkgZm9yIHRvb2xpbmcgbGlrZSByc3g6ZGVidWdcbiAgICAgICAgLy8gRE8gTk9UIHVzZSB0aGlzIGluIGFwcGxpY2F0aW9uIGNvZGUgLSB1c2Ugb25fYXBwX3JlYWR5KCkgcGhhc2UgaW5zdGVhZFxuICAgICAgICAvLyBUaGlzIGV2ZW50IGV4aXN0cyBzb2xlbHkgZm9yIGRlYnVnZ2luZyB0b29scyB0aGF0IG5lZWQgdG8gcnVuIGFmdGVyIGZ1bGwgaW5pdGlhbGl6YXRpb25cbiAgICAgICAgUnN4LnRyaWdnZXIoJ19kZWJ1Z19yZWFkeScpO1xuICAgIH1cblxuICAgIC8qIENhbGxpbmcgdGhpcyBzdG9wcyB0aGUgYm9vdCBwcm9jZXNzLiAqL1xuICAgIHN0YXRpYyBhc3luYyBfcnN4X2NvcmVfYm9vdF9zdG9wKHJlYXNvbikge1xuICAgICAgICBjb25zb2xlLmVycm9yKHJlYXNvbik7XG4gICAgICAgIFJzeC5fX3N0b3BwZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlIFVSTCBoYXNoIGludG8ga2V5LXZhbHVlIG9iamVjdFxuICAgICAqIEhhbmRsZXMgZm9ybWF0OiAja2V5PXZhbHVlJmtleTI9dmFsdWUyXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBQYXJzZWQgaGFzaCBwYXJhbWV0ZXJzXG4gICAgICovXG4gICAgc3RhdGljIF9wYXJzZV9oYXNoKCkge1xuICAgICAgICBjb25zdCBoYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2g7XG4gICAgICAgIGlmICghaGFzaCB8fCBoYXNoID09PSAnIycpIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSBsZWFkaW5nICMgYW5kIHBhcnNlIGFzIHF1ZXJ5IHN0cmluZ1xuICAgICAgICBjb25zdCBoYXNoX3N0cmluZyA9IGhhc2guc3Vic3RyaW5nKDEpO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcblxuICAgICAgICBjb25zdCBwYWlycyA9IGhhc2hfc3RyaW5nLnNwbGl0KCcmJyk7XG4gICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykge1xuICAgICAgICAgICAgY29uc3QgW2tleSwgdmFsdWVdID0gcGFpci5zcGxpdCgnPScpO1xuICAgICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQoa2V5KV0gPSB2YWx1ZSA/IGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSkgOiAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VyaWFsaXplIG9iamVjdCBpbnRvIFVSTCBoYXNoIGZvcm1hdFxuICAgICAqIFByb2R1Y2VzIGZvcm1hdDogI2tleT12YWx1ZSZrZXkyPXZhbHVlMlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBLZXktdmFsdWUgcGFpcnMgdG8gZW5jb2RlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRW5jb2RlZCBoYXNoIHN0cmluZyAod2l0aCBsZWFkaW5nICMsIG9yIGVtcHR5IHN0cmluZylcbiAgICAgKi9cbiAgICBzdGF0aWMgX3NlcmlhbGl6ZV9oYXNoKHBhcmFtcykge1xuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW2tleV07XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICBwYWlycy5wdXNoKGAke2VuY29kZVVSSUNvbXBvbmVudChrZXkpfT0ke2VuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSl9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFpcnMubGVuZ3RoID4gMCA/ICcjJyArIHBhaXJzLmpvaW4oJyYnKSA6ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgcGFnZSBzdGF0ZSBmcm9tIFVSTCBoYXNoXG4gICAgICpcbiAgICAgKiBVc2FnZTpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogY29uc3Qgc3RhdGUgPSBSc3guZ2V0X2FsbF9wYWdlX3N0YXRlKCk7XG4gICAgICogLy8gUmV0dXJuczoge2RnX3BhZ2U6ICcyJywgZGdfc29ydDogJ25hbWUnfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH0gQWxsIGhhc2ggcGFyYW1ldGVycyBhcyBrZXktdmFsdWUgcGFpcnNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2FsbF9wYWdlX3N0YXRlKCkge1xuICAgICAgICByZXR1cm4gUnN4Ll9wYXJzZV9oYXNoKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHNpbmdsZSB2YWx1ZSBmcm9tIFVSTCBoYXNoIHN0YXRlXG4gICAgICpcbiAgICAgKiBVc2FnZTpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogY29uc3QgcGFnZSA9IFJzeC5nZXRfcGFnZV9zdGF0ZSgnZGdfcGFnZScpO1xuICAgICAqIC8vIFJldHVybnM6ICcyJyBvciBudWxsIGlmIG5vdCBzZXRcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSB0byByZXRyaWV2ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gVGhlIHZhbHVlIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGdldF9wYWdlX3N0YXRlKGtleSkge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IFJzeC5fcGFyc2VfaGFzaCgpO1xuICAgICAgICByZXR1cm4gc3RhdGVba2V5XSA/PyBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBzaW5nbGUgdmFsdWUgaW4gVVJMIGhhc2ggc3RhdGUgKHJlcGxhY2VzIGhpc3RvcnksIGRvZXNuJ3QgYWRkKVxuICAgICAqXG4gICAgICogVXNhZ2U6XG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIFJzeC5zZXRfcGFnZV9zdGF0ZSgnZGdfcGFnZScsIDIpO1xuICAgICAqIC8vIFVSTCBiZWNvbWVzOiBodHRwOi8vZXhhbXBsZS5jb20vcGFnZSNkZ19wYWdlPTJcbiAgICAgKlxuICAgICAqIFJzeC5zZXRfcGFnZV9zdGF0ZSgnZGdfcGFnZScsIG51bGwpOyAvLyBSZW1vdmUga2V5XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgdG8gc2V0XG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfG51bGx9IHZhbHVlIFRoZSB2YWx1ZSAobnVsbC9lbXB0eSByZW1vdmVzIHRoZSBrZXkpXG4gICAgICovXG4gICAgc3RhdGljIHNldF9wYWdlX3N0YXRlKGtleSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBSc3guX3BhcnNlX2hhc2goKTtcblxuICAgICAgICAvLyBVcGRhdGUgb3IgcmVtb3ZlIHRoZSBrZXlcbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICBkZWxldGUgc3RhdGVba2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXRlW2tleV0gPSBTdHJpbmcodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIFVSTCB3aXRob3V0IGFkZGluZyBoaXN0b3J5XG4gICAgICAgIGNvbnN0IG5ld19oYXNoID0gUnN4Ll9zZXJpYWxpemVfaGFzaChzdGF0ZSk7XG4gICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2ggKyBuZXdfaGFzaDtcbiAgICAgICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgJycsIHVybCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IG11bHRpcGxlIHZhbHVlcyBpbiBVUkwgaGFzaCBzdGF0ZSBhdCBvbmNlXG4gICAgICpcbiAgICAgKiBVc2FnZTpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogUnN4LnNldF9hbGxfcGFnZV9zdGF0ZSh7ZGdfcGFnZTogMiwgZGdfc29ydDogJ25hbWUnfSk7XG4gICAgICogLy8gVVJMIGJlY29tZXM6IGh0dHA6Ly9leGFtcGxlLmNvbS9wYWdlI2RnX3BhZ2U9MiZkZ19zb3J0PW5hbWVcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBuZXdfc3RhdGUgT2JqZWN0IHdpdGgga2V5LXZhbHVlIHBhaXJzIHRvIHNldFxuICAgICAqL1xuICAgIHN0YXRpYyBzZXRfYWxsX3BhZ2Vfc3RhdGUobmV3X3N0YXRlKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gUnN4Ll9wYXJzZV9oYXNoKCk7XG5cbiAgICAgICAgLy8gTWVyZ2UgbmV3IHN0YXRlXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG5ld19zdGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBuZXdfc3RhdGVba2V5XTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZVtrZXldO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdGF0ZVtrZXldID0gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBVUkwgd2l0aG91dCBhZGRpbmcgaGlzdG9yeVxuICAgICAgICBjb25zdCBuZXdfaGFzaCA9IFJzeC5fc2VyaWFsaXplX2hhc2goc3RhdGUpO1xuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUgKyB3aW5kb3cubG9jYXRpb24uc2VhcmNoICsgbmV3X2hhc2g7XG4gICAgICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsICcnLCB1cmwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbmRlciBhbiBlcnJvciBpbiBhIERPTSBlbGVtZW50XG4gICAgICpcbiAgICAgKiBEaXNwbGF5cyBlcnJvcnMgZnJvbSBBamF4IGNhbGxzIGluIGEgc3RhbmRhcmRpemVkIGZvcm1hdC4gSGFuZGxlcyBkaWZmZXJlbnRcbiAgICAgKiBlcnJvciB0eXBlcyAoZmF0YWwsIHZhbGlkYXRpb24sIGF1dGgsIGdlbmVyaWMpIHdpdGggYXBwcm9wcmlhdGUgZm9ybWF0dGluZy5cbiAgICAgKlxuICAgICAqIFVzYWdlOlxuICAgICAqIGBgYGphdmFzY3JpcHRcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBDb250cm9sbGVyLm1ldGhvZCgpO1xuICAgICAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICogICAgIFJzeC5yZW5kZXJfZXJyb3IoZXJyb3IsICcjZXJyb3JfY29udGFpbmVyJyk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcnxPYmplY3R9IGVycm9yIC0gRXJyb3Igb2JqZWN0IGZyb20gQWpheCBjYWxsXG4gICAgICogQHBhcmFtIHtqUXVlcnl8c3RyaW5nfSBjb250YWluZXIgLSBqUXVlcnkgZWxlbWVudCBvciBzZWxlY3RvciBmb3IgZXJyb3IgZGlzcGxheVxuICAgICAqL1xuICAgIHN0YXRpYyByZW5kZXJfZXJyb3IoZXJyb3IsIGNvbnRhaW5lcikge1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gJChjb250YWluZXIpO1xuXG4gICAgICAgIGlmICghJGNvbnRhaW5lci5leGlzdHMoKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignUnN4LnJlbmRlcl9lcnJvcjogQ29udGFpbmVyIG5vdCBmb3VuZCcsIGNvbnRhaW5lcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGVhciBleGlzdGluZyBjb250ZW50XG4gICAgICAgICRjb250YWluZXIuZW1wdHkoKTtcblxuICAgICAgICBsZXQgaHRtbCA9ICcnO1xuXG4gICAgICAgIC8vIEhhbmRsZSBkaWZmZXJlbnQgZXJyb3IgdHlwZXNcbiAgICAgICAgaWYgKGVycm9yLnR5cGUgPT09ICdmYXRhbCcgJiYgZXJyb3IuZGV0YWlscykge1xuICAgICAgICAgICAgLy8gRmF0YWwgUEhQIGVycm9yIHdpdGggZmlsZS9saW5lL2Vycm9yXG4gICAgICAgICAgICBjb25zdCBkZXRhaWxzID0gZXJyb3IuZGV0YWlscztcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBkZXRhaWxzLmZpbGUgfHwgJ1Vua25vd24gZmlsZSc7XG4gICAgICAgICAgICBjb25zdCBsaW5lID0gZGV0YWlscy5saW5lIHx8ICc/JztcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBkZXRhaWxzLmVycm9yIHx8IGVycm9yLm1lc3NhZ2UgfHwgJ0ZhdGFsIGVycm9yIG9jY3VycmVkJztcblxuICAgICAgICAgICAgaHRtbCA9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxoNT5VbmNhdWdodCBGYXRhbCBFcnJvciBpbiAke2ZpbGV9OiR7bGluZX06PC9oNT5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCI+JHtSc3guX2VzY2FwZV9odG1sKG1lc3NhZ2UpfTwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IudHlwZSA9PT0gJ2Zvcm1fZXJyb3InICYmIGVycm9yLmRldGFpbHMpIHtcbiAgICAgICAgICAgIC8vIFZhbGlkYXRpb24gZXJyb3JzIC0gc2hvdyB1bm1hdGNoZWQgZXJyb3JzIG9ubHlcbiAgICAgICAgICAgIC8vIChtYXRjaGVkIGVycm9ycyBzaG91bGQgYmUgaGFuZGxlZCBieSBGb3JtX1V0aWxzLmFwcGx5X2Zvcm1fZXJyb3JzKVxuICAgICAgICAgICAgY29uc3QgZXJyb3JzID0gZXJyb3IuZGV0YWlscztcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX2xpc3QgPSBbXTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBlcnJvcl9saXN0LnB1c2goZXJyb3JzW2ZpZWxkXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChlcnJvcl9saXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBodG1sID0gYFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtd2FybmluZ1wiIHJvbGU9XCJhbGVydFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGg1PlZhbGlkYXRpb24gRXJyb3JzOjwvaDU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJtYi0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtlcnJvcl9saXN0Lm1hcChlcnIgPT4gYDxsaT4ke1JzeC5fZXNjYXBlX2h0bWwoZXJyKX08L2xpPmApLmpvaW4oJycpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChlcnJvci50eXBlID09PSAnYXV0aF9yZXF1aXJlZCcgfHwgZXJyb3IudHlwZSA9PT0gJ3VuYXV0aG9yaXplZCcpIHtcbiAgICAgICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uL2F1dGhvcml6YXRpb24gZXJyb3JzXG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IubWVzc2FnZSB8fCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnO1xuICAgICAgICAgICAgaHRtbCA9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtd2FybmluZ1wiIHJvbGU9XCJhbGVydFwiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj4ke1JzeC5fZXNjYXBlX2h0bWwobWVzc2FnZSl9PC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvci50eXBlID09PSAnbmV0d29yaycpIHtcbiAgICAgICAgICAgIC8vIE5ldHdvcmsgZXJyb3JzXG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IubWVzc2FnZSB8fCAnVW5hYmxlIHRvIHJlYWNoIHNlcnZlci4gUGxlYXNlIGNoZWNrIHlvdXIgY29ubmVjdGlvbi4nO1xuICAgICAgICAgICAgaHRtbCA9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiPiR7UnN4Ll9lc2NhcGVfaHRtbChtZXNzYWdlKX08L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gR2VuZXJpYy91bmtub3duIGVycm9yXG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IubWVzc2FnZSB8fCBlcnJvci50b1N0cmluZygpIHx8ICdBbiB1bmtub3duIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgICAgIGh0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHJvbGU9XCJhbGVydFwiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj4ke1JzeC5fZXNjYXBlX2h0bWwobWVzc2FnZSl9PC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICAgICAgfVxuXG4gICAgICAgICRjb250YWluZXIuaHRtbChodG1sKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFc2NhcGUgSFRNTCB0byBwcmV2ZW50IFhTUyBpbiBlcnJvciBtZXNzYWdlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9lc2NhcGVfaHRtbCh0ZXh0KSB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgICAgICByZXR1cm4gZGl2LmlubmVySFRNTDtcbiAgICB9XG59XG4iLCIvLyBARklMRS1TVUJDTEFTUy0wMS1FWENFUFRJT05cblxuLyoqXG4gKiBDbGllbnQtc2lkZSBBamF4IGNsYXNzIGZvciBtYWtpbmcgQVBJIGNhbGxzIHRvIFJTWCBjb250cm9sbGVyc1xuICpcbiAqIEF1dG9tYXRpY2FsbHkgYmF0Y2hlcyBtdWx0aXBsZSBjYWxscyBpbnRvIHNpbmdsZSBIVFRQIHJlcXVlc3RzIHRvIHJlZHVjZSBuZXR3b3JrIG92ZXJoZWFkLlxuICogQmF0Y2hlcyB1cCB0byAyMCBjYWxscyBvciBmbHVzaGVzIGFmdGVyIHNldFRpbWVvdXQoMCkgZGVib3VuY2UuXG4gKi9cbmNsYXNzIEFqYXgge1xuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgQWpheCBzeXN0ZW1cbiAgICAgKiBDYWxsZWQgYXV0b21hdGljYWxseSB3aGVuIGNsYXNzIGlzIGxvYWRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBfb25fZnJhbWV3b3JrX2NvcmVfaW5pdCgpIHtcbiAgICAgICAgLy8gUXVldWUgb2YgcGVuZGluZyBjYWxscyB3YWl0aW5nIHRvIGJlIGJhdGNoZWRcbiAgICAgICAgQWpheC5fcGVuZGluZ19jYWxscyA9IHt9O1xuXG4gICAgICAgIC8vIFRpbWVyIGZvciBiYXRjaGluZyBmbHVzaFxuICAgICAgICBBamF4Ll9mbHVzaF90aW1lb3V0ID0gbnVsbDtcblxuICAgICAgICAvLyBDYWxsIGNvdW50ZXIgZm9yIGdlbmVyYXRpbmcgdW5pcXVlIGNhbGwgSURzXG4gICAgICAgIEFqYXguX2NhbGxfY291bnRlciA9IDA7XG5cbiAgICAgICAgLy8gTWF4aW11bSBiYXRjaCBzaXplIGJlZm9yZSBmb3JjaW5nIGltbWVkaWF0ZSBmbHVzaFxuICAgICAgICBBamF4Lk1BWF9CQVRDSF9TSVpFID0gMjA7XG5cbiAgICAgICAgLy8gRGVib3VuY2UgdGltZSBpbiBtaWxsaXNlY29uZHNcbiAgICAgICAgQWpheC5ERUJPVU5DRV9NUyA9IDA7XG5cbiAgICAgICAgLy8gVHJhY2sgcHJvbWlzZXMgZnJvbSBBamF4IGNhbGxzIHRvIGRldGVjdCB1bmNhdWdodCByZWplY3Rpb25zXG4gICAgICAgIEFqYXguX3RyYWNrZWRfcHJvbWlzZXMgPSBuZXcgV2Vha1NldCgpO1xuXG4gICAgICAgIC8vIFNldCB1cCBnbG9iYWwgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyIGZvciBBamF4IGVycm9yc1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBPbmx5IGhhbmRsZSByZWplY3Rpb25zIGZyb20gQWpheCBwcm9taXNlc1xuICAgICAgICAgICAgaWYgKEFqYXguX3RyYWNrZWRfcHJvbWlzZXMuaGFzKGV2ZW50LnByb21pc2UpKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gUHJldmVudCBicm93c2VyJ3MgZGVmYXVsdCBcIlVuY2F1Z2h0IChpbiBwcm9taXNlKVwiIGVycm9yXG5cbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGV2ZW50LnJlYXNvbjtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdVbmNhdWdodCBBamF4IGVycm9yOicsIGVycm9yKTtcblxuICAgICAgICAgICAgICAgIC8vIFNob3cgTW9kYWwuZXJyb3IoKSBmb3IgdW5jYXVnaHQgQWpheCBlcnJvcnNcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1vZGFsICE9PSAndW5kZWZpbmVkJyAmJiBNb2RhbC5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBNb2RhbC5lcnJvcihlcnJvciwgJ1VuY2F1Z2h0IEFqYXggRXJyb3InKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2UgYW4gQUpBWCBjYWxsIHRvIGFuIFJTWCBjb250cm9sbGVyIGFjdGlvblxuICAgICAqXG4gICAgICogQWxsIGNhbGxzIGFyZSBhdXRvbWF0aWNhbGx5IGJhdGNoZWQgdW5sZXNzIHdpbmRvdy5yc3hhcHAuYWpheF9kaXNhYmxlX2JhdGNoaW5nIGlzIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R8ZnVuY3Rpb259IHVybCAtIFRoZSBBamF4IFVSTCAoZS5nLiwgJy9fYWpheC9Db250cm9sbGVyX05hbWUvYWN0aW9uX25hbWUnKSBvciBhbiBvYmplY3QvZnVuY3Rpb24gd2l0aCBhIC5wYXRoIHByb3BlcnR5XG4gICAgICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgdG8gc2VuZCB0byB0aGUgYWN0aW9uXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IC0gUmVzb2x2ZXMgd2l0aCB0aGUgcmV0dXJuIHZhbHVlLCByZWplY3RzIHdpdGggZXJyb3JcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY2FsbCh1cmwsIHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIC8vIElmIHVybCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gd2l0aCBhIC5wYXRoIHByb3BlcnR5LCB1c2UgdGhhdCBhcyB0aGUgVVJMXG4gICAgICAgIGlmICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ29iamVjdCcgJiYgdXJsLnBhdGgpIHtcbiAgICAgICAgICAgIHVybCA9IHVybC5wYXRoO1xuICAgICAgICB9IGVsc2UgaWYgKHVybCAmJiB0eXBlb2YgdXJsID09PSAnZnVuY3Rpb24nICYmIHVybC5wYXRoKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwucGF0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIHVybCBpcyBhIG5vbi1lbXB0eSBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnIHx8IHVybC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWpheC5jYWxsKCkgcmVxdWlyZXMgYSBub24tZW1wdHkgc3RyaW5nIFVSTCBvciBhbiBvYmplY3QvZnVuY3Rpb24gd2l0aCBhIC5wYXRoIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHRyYWN0IGNvbnRyb2xsZXIgYW5kIGFjdGlvbiBmcm9tIFVSTFxuICAgICAgICBjb25zdCB7IGNvbnRyb2xsZXIsIGFjdGlvbiB9ID0gQWpheC5hamF4X3VybF90b19jb250cm9sbGVyX2FjdGlvbih1cmwpO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCdBamF4OicsIGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBiYXRjaGluZyBpcyBkaXNhYmxlZCBmb3IgZGVidWdnaW5nXG4gICAgICAgIGxldCBwcm9taXNlO1xuICAgICAgICBpZiAod2luZG93LnJzeGFwcCAmJiB3aW5kb3cucnN4YXBwLmFqYXhfZGlzYWJsZV9iYXRjaGluZykge1xuICAgICAgICAgICAgcHJvbWlzZSA9IEFqYXguX2NhbGxfZGlyZWN0KGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb21pc2UgPSBBamF4Ll9jYWxsX2JhdGNoKGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYWNrIHRoaXMgcHJvbWlzZSBmb3IgdW5oYW5kbGVkIHJlamVjdGlvbiBkZXRlY3Rpb25cbiAgICAgICAgQWpheC5fdHJhY2tlZF9wcm9taXNlcy5hZGQocHJvbWlzZSk7XG5cbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZSBhIGJhdGNoZWQgQWpheCBjYWxsXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2NhbGxfYmF0Y2goY29udHJvbGxlciwgYWN0aW9uLCBwYXJhbXMgPSB7fSkge1xuICAgICAgICBjb25zb2xlLmxvZygnQWpheCBCYXRjaDonLCBjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIC8vIEdlbmVyYXRlIGNhbGwga2V5IGZvciBkZWR1cGxpY2F0aW9uXG4gICAgICAgICAgICBjb25zdCBjYWxsX2tleSA9IEFqYXguX2dlbmVyYXRlX2NhbGxfa2V5KGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zKTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBleGFjdCBjYWxsIGlzIGFscmVhZHkgcGVuZGluZ1xuICAgICAgICAgICAgaWYgKEFqYXguX3BlbmRpbmdfY2FsbHNbY2FsbF9rZXldKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdfY2FsbCA9IEFqYXguX3BlbmRpbmdfY2FsbHNbY2FsbF9rZXldO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgY2FsbCBhbHJlYWR5IGNvbXBsZXRlZCAoY2FjaGVkKSwgcmV0dXJuIGltbWVkaWF0ZWx5XG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nX2NhbGwuaXNfY29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nX2NhbGwuaXNfZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChleGlzdGluZ19jYWxsLmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZXhpc3RpbmdfY2FsbC5yZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBDYWxsIGlzIHBlbmRpbmcsIGFkZCB0aGlzIHByb21pc2UgdG8gY2FsbGJhY2tzXG4gICAgICAgICAgICAgICAgZXhpc3RpbmdfY2FsbC5jYWxsYmFja3MucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgcGVuZGluZyBjYWxsXG4gICAgICAgICAgICBjb25zdCBjYWxsX2lkID0gQWpheC5fY2FsbF9jb3VudGVyKys7XG4gICAgICAgICAgICBjb25zdCBwZW5kaW5nX2NhbGwgPSB7XG4gICAgICAgICAgICAgICAgY2FsbF9pZDogY2FsbF9pZCxcbiAgICAgICAgICAgICAgICBjYWxsX2tleTogY2FsbF9rZXksXG4gICAgICAgICAgICAgICAgY29udHJvbGxlcjogY29udHJvbGxlcixcbiAgICAgICAgICAgICAgICBhY3Rpb246IGFjdGlvbixcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgICAgICAgICAgICBjYWxsYmFja3M6IFt7IHJlc29sdmUsIHJlamVjdCB9XSxcbiAgICAgICAgICAgICAgICBpc19jb21wbGV0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgaXNfZXJyb3I6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHJlc3VsdDogbnVsbCxcbiAgICAgICAgICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIEFkZCB0byBwZW5kaW5nIHF1ZXVlXG4gICAgICAgICAgICBBamF4Ll9wZW5kaW5nX2NhbGxzW2NhbGxfa2V5XSA9IHBlbmRpbmdfY2FsbDtcblxuICAgICAgICAgICAgLy8gQ291bnQgcGVuZGluZyBjYWxsc1xuICAgICAgICAgICAgY29uc3QgcGVuZGluZ19jb3VudCA9IE9iamVjdC5rZXlzKEFqYXguX3BlbmRpbmdfY2FsbHMpLmZpbHRlcigoa2V5KSA9PiAhQWpheC5fcGVuZGluZ19jYWxsc1trZXldLmlzX2NvbXBsZXRlKS5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIGhpdCB0aGUgYmF0Y2ggc2l6ZSBsaW1pdCwgZmx1c2ggaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIGlmIChwZW5kaW5nX2NvdW50ID49IEFqYXguTUFYX0JBVENIX1NJWkUpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoQWpheC5fZmx1c2hfdGltZW91dCk7XG4gICAgICAgICAgICAgICAgQWpheC5fZmx1c2hfdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICAgICAgQWpheC5fZmx1c2hfcGVuZGluZ19jYWxscygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTY2hlZHVsZSBiYXRjaCBmbHVzaCB3aXRoIGRlYm91bmNlXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KEFqYXguX2ZsdXNoX3RpbWVvdXQpO1xuICAgICAgICAgICAgICAgIEFqYXguX2ZsdXNoX3RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgQWpheC5fZmx1c2hfcGVuZGluZ19jYWxscygpO1xuICAgICAgICAgICAgICAgIH0sIEFqYXguREVCT1VOQ0VfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlIGEgZGlyZWN0IChub24tYmF0Y2hlZCkgQWpheCBjYWxsXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX2NhbGxfZGlyZWN0KGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zID0ge30pIHtcbiAgICAgICAgLy8gQ29uc3RydWN0IFVSTCBmcm9tIGNvbnRyb2xsZXIgYW5kIGFjdGlvblxuICAgICAgICBjb25zdCB1cmwgPSBgL19hamF4LyR7Y29udHJvbGxlcn0vJHthY3Rpb259YDtcblxuICAgICAgICAvLyBMb2cgdGhlIEFKQVggY2FsbCB1c2luZyBjb25zb2xlX2RlYnVnXG4gICAgICAgIGlmICh0eXBlb2YgRGVidWdnZXIgIT09ICd1bmRlZmluZWQnICYmIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcpIHtcbiAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoJ0FKQVgnLCBgQ2FsbGluZyAke2NvbnRyb2xsZXJ9LiR7YWN0aW9ufSAodW5iYXRjaGVkKWAsIHBhcmFtcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiBwYXJhbXMsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgICAgICAgICBfX2xvY2FsX2ludGVncmF0aW9uOiB0cnVlLCAvLyBCeXBhc3MgJC5hamF4IG92ZXJyaWRlXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBjb25zb2xlX2RlYnVnIG1lc3NhZ2VzXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5jb25zb2xlX2RlYnVnICYmIEFycmF5LmlzQXJyYXkocmVzcG9uc2UuY29uc29sZV9kZWJ1ZykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmNvbnNvbGVfZGVidWcuZm9yRWFjaCgobXNnKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1zZykgfHwgbXNnLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29uc29sZV9kZWJ1ZyBtZXNzYWdlIGZvcm1hdCAtIGV4cGVjdGVkIFtjaGFubmVsLCBbYXJndW1lbnRzXV0nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgW2NoYW5uZWwsIGFyZ3NdID0gbXNnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGNoYW5uZWwsIC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgcmVzcG9uc2Ugd2FzIHN1Y2Nlc3NmdWxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLl9zdWNjZXNzID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBASlMtQUpBWC0wMi1FWENFUFRJT04gLSBVbndyYXAgc2VydmVyIHJlc3BvbnNlcyB3aXRoIF9hamF4X3JldHVybl92YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkX3ZhbHVlID0gUnN4X0pzX01vZGVsLl9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKHJlc3BvbnNlLl9hamF4X3JldHVybl92YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHByb2Nlc3NlZF92YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgZXJyb3IgcmVzcG9uc2VzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcl90eXBlID0gcmVzcG9uc2UuZXJyb3JfdHlwZSB8fCAndW5rbm93bl9lcnJvcic7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFzb24gPSByZXNwb25zZS5yZWFzb24gfHwgJ1Vua25vd24gZXJyb3Igb2NjdXJyZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV0YWlscyA9IHJlc3BvbnNlLmRldGFpbHMgfHwge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBzcGVjaWZpYyBlcnJvciB0eXBlc1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvcl90eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmF0YWwnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGYXRhbCBQSFAgZXJyb3Igd2l0aCBmdWxsIGVycm9yIGRldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmF0YWxfZXJyb3JfZGF0YSA9IHJlc3BvbnNlLmVycm9yIHx8IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcl9tZXNzYWdlID0gZmF0YWxfZXJyb3JfZGF0YS5lcnJvciB8fCAnRmF0YWwgZXJyb3Igb2NjdXJyZWQnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FqYXggZXJyb3IgcmVzcG9uc2UgZnJvbSBzZXJ2ZXI6JywgcmVzcG9uc2UuZXJyb3IpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZhdGFsX2Vycm9yID0gbmV3IEVycm9yKGVycm9yX21lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXRhbF9lcnJvci50eXBlID0gJ2ZhdGFsJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxfZXJyb3IuZGV0YWlscyA9IHJlc3BvbnNlLmVycm9yO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExvZyB0byBzZXJ2ZXIgaWYgYnJvd3NlciBlcnJvciBsb2dnaW5nIGlzIGVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVidWdnZXIubG9nX2Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBBamF4IEZhdGFsIEVycm9yOiAke2Vycm9yX21lc3NhZ2V9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdhamF4X2ZhdGFsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZHBvaW50OiB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhaWxzOiByZXNwb25zZS5lcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGZhdGFsX2Vycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXNwb25zZV9hdXRoX3JlcXVpcmVkJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgdXNlciBpcyBubyBsb25nZXIgYXV0aGVudGljYXRlZCwgdGhpcyBpcyBhIHBsYWNlaG9sZGVyIGZvciBmdXR1cmUgY29kZSB3aGljaCBoYW5kbGVzIHRoaXMgc2NlbmFyaW8uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhdXRoX2Vycm9yID0gbmV3IEVycm9yKHJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhfZXJyb3IudHlwZSA9ICdhdXRoX3JlcXVpcmVkJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0aF9lcnJvci5kZXRhaWxzID0gZGV0YWlscztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGF1dGhfZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Jlc3BvbnNlX3VuYXV0aG9yaXplZCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHVzZXIgaXMgdW5hdXRob3JpemVkIHRvIHBlcmZvcm0gdGhpcyBhY3Rpb24sIHRoaXMgaXMgYSBwbGFjZWhvbGRlciBmb3IgZnV0dXJlIGNvZGUgd2hpY2ggaGFuZGxlcyB0aGlzIHNjZW5hcmlvLidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5hdXRoX2Vycm9yID0gbmV3IEVycm9yKHJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuYXV0aF9lcnJvci50eXBlID0gJ3VuYXV0aG9yaXplZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuYXV0aF9lcnJvci5kZXRhaWxzID0gZGV0YWlscztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHVuYXV0aF9lcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVzcG9uc2VfZm9ybV9lcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1fZXJyb3IgPSBuZXcgRXJyb3IocmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybV9lcnJvci50eXBlID0gJ2Zvcm1fZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtX2Vycm9yLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZm9ybV9lcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuZXJpY19lcnJvciA9IG5ldyBFcnJvcihyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmljX2Vycm9yLnR5cGUgPSBlcnJvcl90eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmljX2Vycm9yLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZ2VuZXJpY19lcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogKHhociwgc3RhdHVzLCBlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcl9tZXNzYWdlID0gQWpheC5fZXh0cmFjdF9lcnJvcl9tZXNzYWdlKHhocik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmtfZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIG5ldHdvcmtfZXJyb3IudHlwZSA9ICduZXR3b3JrX2Vycm9yJztcbiAgICAgICAgICAgICAgICAgICAgbmV0d29ya19lcnJvci5zdGF0dXMgPSB4aHIuc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICBuZXR3b3JrX2Vycm9yLnN0YXR1c1RleHQgPSBzdGF0dXM7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTG9nIHNlcnZlciBlcnJvcnMgKDUwMCspIHRvIHRoZSBzZXJ2ZXIgaWYgYnJvd3NlciBlcnJvciBsb2dnaW5nIGlzIGVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPj0gNTAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBEZWJ1Z2dlci5sb2dfZXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBBamF4IFNlcnZlciBFcnJvciAke3hoci5zdGF0dXN9OiAke2Vycm9yX21lc3NhZ2V9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYWpheF9zZXJ2ZXJfZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZHBvaW50OiB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiB4aHIuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c1RleHQ6IHN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldHdvcmtfZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmx1c2ggYWxsIHBlbmRpbmcgY2FsbHMgYnkgc2VuZGluZyBiYXRjaCByZXF1ZXN0XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX2ZsdXNoX3BlbmRpbmdfY2FsbHMoKSB7XG4gICAgICAgIC8vIENvbGxlY3QgYWxsIHBlbmRpbmcgY2FsbHNcbiAgICAgICAgY29uc3QgY2FsbHNfdG9fc2VuZCA9IFtdO1xuICAgICAgICBjb25zdCBjYWxsX21hcCA9IHt9OyAvLyBNYXAgY2FsbF9pZCB0byBwZW5kaW5nX2NhbGwgb2JqZWN0XG5cbiAgICAgICAgZm9yIChjb25zdCBjYWxsX2tleSBpbiBBamF4Ll9wZW5kaW5nX2NhbGxzKSB7XG4gICAgICAgICAgICBjb25zdCBwZW5kaW5nX2NhbGwgPSBBamF4Ll9wZW5kaW5nX2NhbGxzW2NhbGxfa2V5XTtcblxuICAgICAgICAgICAgaWYgKCFwZW5kaW5nX2NhbGwuaXNfY29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICBjYWxsc190b19zZW5kLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBjYWxsX2lkOiBwZW5kaW5nX2NhbGwuY2FsbF9pZCxcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlcjogcGVuZGluZ19jYWxsLmNvbnRyb2xsZXIsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogcGVuZGluZ19jYWxsLmFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiBwZW5kaW5nX2NhbGwucGFyYW1zLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgY2FsbF9tYXBbcGVuZGluZ19jYWxsLmNhbGxfaWRdID0gcGVuZGluZ19jYWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm90aGluZyB0byBzZW5kXG4gICAgICAgIGlmIChjYWxsc190b19zZW5kLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9nIGJhdGNoIGZvciBkZWJ1Z2dpbmdcbiAgICAgICAgaWYgKHR5cGVvZiBEZWJ1Z2dlciAhPT0gJ3VuZGVmaW5lZCcgJiYgRGVidWdnZXIuY29uc29sZV9kZWJ1Zykge1xuICAgICAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcbiAgICAgICAgICAgICAgICAnQUpBWF9CQVRDSCcsXG4gICAgICAgICAgICAgICAgYFNlbmRpbmcgYmF0Y2ggb2YgJHtjYWxsc190b19zZW5kLmxlbmd0aH0gY2FsbHNgLFxuICAgICAgICAgICAgICAgIGNhbGxzX3RvX3NlbmQubWFwKChjKSA9PiBgJHtjLmNvbnRyb2xsZXJ9LiR7Yy5hY3Rpb259YClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gU2VuZCBiYXRjaCByZXF1ZXN0XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiAnL19hamF4L19iYXRjaCcsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YTogeyBiYXRjaF9jYWxsczogSlNPTi5zdHJpbmdpZnkoY2FsbHNfdG9fc2VuZCkgfSxcbiAgICAgICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICAgICAgICAgIF9fbG9jYWxfaW50ZWdyYXRpb246IHRydWUsIC8vIEJ5cGFzcyAkLmFqYXggb3ZlcnJpZGVcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBQcm9jZXNzIGJhdGNoIHJlc3BvbnNlXG4gICAgICAgICAgICAvLyBSZXNwb25zZSBmb3JtYXQ6IHsgQ18wOiB7c3VjY2VzcywgX2FqYXhfcmV0dXJuX3ZhbHVlfSwgQ18xOiB7Li4ufSwgLi4uIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2Vfa2V5IGluIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZV9rZXkuc3RhcnRzV2l0aCgnQ18nKSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjYWxsX2lkID0gcGFyc2VJbnQocmVzcG9uc2Vfa2V5LnN1YnN0cmluZygyKSwgMTApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxfcmVzcG9uc2UgPSByZXNwb25zZVtyZXNwb25zZV9rZXldO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBlbmRpbmdfY2FsbCA9IGNhbGxfbWFwW2NhbGxfaWRdO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFwZW5kaW5nX2NhbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignUmVjZWl2ZWQgcmVzcG9uc2UgZm9yIHVua25vd24gY2FsbF9pZDonLCBjYWxsX2lkKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGNvbnNvbGVfZGVidWcgbWVzc2FnZXMgaWYgcHJlc2VudFxuICAgICAgICAgICAgICAgIGlmIChjYWxsX3Jlc3BvbnNlLmNvbnNvbGVfZGVidWcgJiYgQXJyYXkuaXNBcnJheShjYWxsX3Jlc3BvbnNlLmNvbnNvbGVfZGVidWcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxfcmVzcG9uc2UuY29uc29sZV9kZWJ1Zy5mb3JFYWNoKChtc2cpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtc2cpIHx8IG1zZy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29uc29sZV9kZWJ1ZyBtZXNzYWdlIGZvcm1hdCAtIGV4cGVjdGVkIFtjaGFubmVsLCBbYXJndW1lbnRzXV0nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFtjaGFubmVsLCBhcmdzXSA9IG1zZztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGNoYW5uZWwsIC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBNYXJrIGNhbGwgYXMgY29tcGxldGVcbiAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuaXNfY29tcGxldGUgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgc3VjY2Vzc2Z1bFxuICAgICAgICAgICAgICAgIGlmIChjYWxsX3Jlc3BvbnNlLl9zdWNjZXNzID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEBKUy1BSkFYLTAyLUVYQ0VQVElPTiAtIEJhdGNoIHN5c3RlbSB1bndyYXBzIHNlcnZlciByZXNwb25zZXMgd2l0aCBfYWpheF9yZXR1cm5fdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkX3ZhbHVlID0gUnN4X0pzX01vZGVsLl9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKGNhbGxfcmVzcG9uc2UuX2FqYXhfcmV0dXJuX3ZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLnJlc3VsdCA9IHByb2Nlc3NlZF92YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIGFsbCBjYWxsYmFja3NcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmNhbGxiYWNrcy5mb3JFYWNoKCh7IHJlc29sdmUgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwcm9jZXNzZWRfdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JfdHlwZSA9IGNhbGxfcmVzcG9uc2UuZXJyb3JfdHlwZSB8fCAndW5rbm93bl9lcnJvcic7XG4gICAgICAgICAgICAgICAgICAgIGxldCBlcnJvcl9tZXNzYWdlO1xuICAgICAgICAgICAgICAgICAgICBsZXQgZXJyb3JfZGV0YWlscztcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3JfdHlwZSA9PT0gJ2ZhdGFsJyAmJiBjYWxsX3Jlc3BvbnNlLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGYXRhbCBQSFAgZXJyb3Igd2l0aCBmdWxsIGVycm9yIGRldGFpbHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZhdGFsX2Vycm9yX2RhdGEgPSBjYWxsX3Jlc3BvbnNlLmVycm9yO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSA9IGZhdGFsX2Vycm9yX2RhdGEuZXJyb3IgfHwgJ0ZhdGFsIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX2RldGFpbHMgPSBjYWxsX3Jlc3BvbnNlLmVycm9yO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdBamF4IGVycm9yIHJlc3BvbnNlIGZyb20gc2VydmVyOicsIGNhbGxfcmVzcG9uc2UuZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3RoZXIgZXJyb3IgdHlwZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgPSBjYWxsX3Jlc3BvbnNlLnJlYXNvbiB8fCAnVW5rbm93biBlcnJvciBvY2N1cnJlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9kZXRhaWxzID0gY2FsbF9yZXNwb25zZS5kZXRhaWxzIHx8IHt9O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLnR5cGUgPSBlcnJvcl90eXBlO1xuICAgICAgICAgICAgICAgICAgICBlcnJvci5kZXRhaWxzID0gZXJyb3JfZGV0YWlscztcblxuICAgICAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuaXNfZXJyb3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuZXJyb3IgPSBlcnJvcjtcblxuICAgICAgICAgICAgICAgICAgICAvLyBSZWplY3QgYWxsIGNhbGxiYWNrc1xuICAgICAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuY2FsbGJhY2tzLmZvckVhY2goKHsgcmVqZWN0IH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoeGhyX2Vycm9yKSB7XG4gICAgICAgICAgICAvLyBOZXR3b3JrIG9yIHNlcnZlciBlcnJvciAtIHJlamVjdCBhbGwgcGVuZGluZyBjYWxsc1xuICAgICAgICAgICAgY29uc3QgZXJyb3JfbWVzc2FnZSA9IEFqYXguX2V4dHJhY3RfZXJyb3JfbWVzc2FnZSh4aHJfZXJyb3IpO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgICAgICBlcnJvci50eXBlID0gJ25ldHdvcmtfZXJyb3InO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhbGxfaWQgaW4gY2FsbF9tYXApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwZW5kaW5nX2NhbGwgPSBjYWxsX21hcFtjYWxsX2lkXTtcbiAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuaXNfY29tcGxldGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHBlbmRpbmdfY2FsbC5pc19lcnJvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmVycm9yID0gZXJyb3I7XG5cbiAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuY2FsbGJhY2tzLmZvckVhY2goKHsgcmVqZWN0IH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignQmF0Y2ggQWpheCByZXF1ZXN0IGZhaWxlZDonLCBlcnJvcl9tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgdW5pcXVlIGtleSBmb3IgZGVkdXBsaWNhdGluZyBjYWxsc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9nZW5lcmF0ZV9jYWxsX2tleShjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcykge1xuICAgICAgICAvLyBDcmVhdGUgYSBzdGFibGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjYWxsXG4gICAgICAgIC8vIFNvcnQgcGFyYW1zIGtleXMgZm9yIGNvbnNpc3RlbnQgaGFzaGluZ1xuICAgICAgICBjb25zdCBzb3J0ZWRfcGFyYW1zID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKHBhcmFtcylcbiAgICAgICAgICAgIC5zb3J0KClcbiAgICAgICAgICAgIC5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgICAgICBzb3J0ZWRfcGFyYW1zW2tleV0gPSBwYXJhbXNba2V5XTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBgJHtjb250cm9sbGVyfTo6JHthY3Rpb259Ojoke0pTT04uc3RyaW5naWZ5KHNvcnRlZF9wYXJhbXMpfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdCBlcnJvciBtZXNzYWdlIGZyb20galF1ZXJ5IFhIUiBvYmplY3RcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZXh0cmFjdF9lcnJvcl9tZXNzYWdlKHhocikge1xuICAgICAgICBpZiAoeGhyLnJlc3BvbnNlSlNPTiAmJiB4aHIucmVzcG9uc2VKU09OLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiB4aHIucmVzcG9uc2VKU09OLm1lc3NhZ2U7XG4gICAgICAgIH0gZWxzZSBpZiAoeGhyLnJlc3BvbnNlVGV4dCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLm1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIE5vdCBKU09OXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYCR7eGhyLnN0YXR1c306ICR7eGhyLnN0YXR1c1RleHQgfHwgJ1Vua25vd24gZXJyb3InfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIGFuIEFKQVggVVJMIGludG8gY29udHJvbGxlciBhbmQgYWN0aW9uXG4gICAgICogU3VwcG9ydHMgYm90aCAvX2FqYXgvIGFuZCAvXy8gVVJMIHByZWZpeGVzXG4gICAgICogQHBhcmFtIHtzdHJpbmd8b2JqZWN0fGZ1bmN0aW9ufSB1cmwgLSBVUkwgaW4gZm9ybWF0ICcvX2FqYXgvQ29udHJvbGxlcl9OYW1lL2FjdGlvbl9uYW1lJyBvciAnL18vQ29udHJvbGxlcl9OYW1lL2FjdGlvbl9uYW1lJywgb3IgYW4gb2JqZWN0L2Z1bmN0aW9uIHdpdGggYSAucGF0aCBwcm9wZXJ0eVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IE9iamVjdCB3aXRoIHtjb250cm9sbGVyOiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nfVxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBVUkwgZG9lc24ndCBzdGFydCB3aXRoIC9fYWpheCBvciAvXyBvciBoYXMgaW52YWxpZCBzdHJ1Y3R1cmVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24odXJsKSB7XG4gICAgICAgIC8vIElmIHVybCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gd2l0aCBhIC5wYXRoIHByb3BlcnR5LCB1c2UgdGhhdCBhcyB0aGUgVVJMXG4gICAgICAgIGlmICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ29iamVjdCcgJiYgdXJsLnBhdGgpIHtcbiAgICAgICAgICAgIHVybCA9IHVybC5wYXRoO1xuICAgICAgICB9IGVsc2UgaWYgKHVybCAmJiB0eXBlb2YgdXJsID09PSAnZnVuY3Rpb24nICYmIHVybC5wYXRoKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwucGF0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIHVybCBpcyBhIHN0cmluZ1xuICAgICAgICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVVJMIG11c3QgYmUgYSBzdHJpbmcgb3IgaGF2ZSBhIC5wYXRoIHByb3BlcnR5LCBnb3Q6ICR7dHlwZW9mIHVybH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdXJsLnN0YXJ0c1dpdGgoJy9fYWpheCcpICYmICF1cmwuc3RhcnRzV2l0aCgnL18vJykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVVJMIG11c3Qgc3RhcnQgd2l0aCAvX2FqYXggb3IgL18sIGdvdDogJHt1cmx9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJ0cyA9IHVybC5zcGxpdCgnLycpLmZpbHRlcigocGFydCkgPT4gcGFydCAhPT0gJycpO1xuXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgQUpBWCBVUkwgc3RydWN0dXJlOiAke3VybH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFKQVggVVJMIGhhcyB0b28gbWFueSBzZWdtZW50czogJHt1cmx9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250cm9sbGVyID0gcGFydHNbMV07XG4gICAgICAgIGNvbnN0IGFjdGlvbiA9IHBhcnRzWzJdIHx8ICdpbmRleCc7XG5cbiAgICAgICAgcmV0dXJuIHsgY29udHJvbGxlciwgYWN0aW9uIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXV0by1pbml0aWFsaXplIHN0YXRpYyBwcm9wZXJ0aWVzIHdoZW4gY2xhc3MgaXMgZmlyc3QgbG9hZGVkXG4gICAgICovXG4gICAgc3RhdGljIG9uX2NvcmVfZGVmaW5lKCkge1xuICAgICAgICBBamF4Ll9vbl9mcmFtZXdvcmtfY29yZV9pbml0KCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBKcWh0bWxfQ29tcG9uZW50IC0gQmFzZSBjbGFzcyBmb3IgSlFIVE1MIGNvbXBvbmVudHMgaW4gUlNYIGZyYW1ld29ya1xuICpcbiAqIFRoaXMgY2xhc3Mgd3JhcHMgdGhlIGpxaHRtbC5Db21wb25lbnQgZnJvbSB0aGUgbnBtIHBhY2thZ2UgYW5kIHByb3ZpZGVzXG4gKiB0aGUgc3RhbmRhcmQgaW50ZXJmYWNlIGZvciBSU1ggY29tcG9uZW50cyBmb2xsb3dpbmcgdGhlIFVwcGVyX0Nhc2UgbmFtaW5nIGNvbnZlbnRpb24uXG4gKlxuICogX0Jhc2VfSnFodG1sX0NvbXBvbmVudCBpcyBpbXBvcnRlZCBmcm9tIG5wbSB2aWEgSnFodG1sX0J1bmRsZS5cbiAqXG4gKiBASW5zdGFudGlhdGFibGVcbiAqL1xuY2xhc3MgSnFodG1sX0NvbXBvbmVudCBleHRlbmRzIF9CYXNlX0pxaHRtbF9Db21wb25lbnQge31cblxuLy8gUlNYIG1hbmlmZXN0IGF1dG9tYXRpY2FsbHkgbWFrZXMgY2xhc3NlcyBnbG9iYWwgLSBubyBtYW51YWwgYXNzaWdubWVudCBuZWVkZWRcbiIsIi8qKlxuICogSlFIVE1MIEludGVncmF0aW9uIC0gQXV0b21hdGljIGNvbXBvbmVudCByZWdpc3RyYXRpb24gYW5kIGJpbmRpbmdcbiAqXG4gKiBUaGlzIG1vZHVsZSBhdXRvbWF0aWNhbGx5OlxuICogMS4gUmVnaXN0ZXJzIGNvbXBvbmVudCBjbGFzc2VzIHRoYXQgZXh0ZW5kIEpxaHRtbF9Db21wb25lbnRcbiAqIDIuIEJpbmRzIHRlbXBsYXRlcyB0byBjb21wb25lbnQgY2xhc3NlcyB3aGVuIG5hbWVzIG1hdGNoXG4gKiAzLiBFbmFibGVzICQoc2VsZWN0b3IpLmNvbXBvbmVudChcIkNvbXBvbmVudF9OYW1lXCIpIHN5bnRheFxuICovXG5jbGFzcyBKcWh0bWxfSW50ZWdyYXRpb24ge1xuICAgIC8qKlxuICAgICAqIENvbXBpbGVkIEpxaHRtbCB0ZW1wbGF0ZXMgc2VsZi1yZWdpc3Rlci4gIFRoZSBkZXZlbG9wZXIgKHRoZSBmcmFtZXdvcmsgaW4gdGhpcyBjYXNlKSBpcyBzdGlsbFxuICAgICAqIHJlc3BvbnNpYmxlIGZvciByZWdpc3RlcmluZyBlczYgY29tcG9uZW50IGNsYXNzZXMgd2l0aCBqcWh0bWwuICBUaGlzIGRvZXMgc28gYXQgYW4gZWFybHkgc3RhZ2VcbiAgICAgKiBvZiBmcmFtZXdvcmsgaW5pdC5cbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZSgpIHtcbiAgICAgICAgbGV0IGpxaHRtbF9jb21wb25lbnRzID0gTWFuaWZlc3QuZ2V0X2V4dGVuZGluZygnSnFodG1sX0NvbXBvbmVudCcpO1xuXG4gICAgICAgIGNvbnNvbGVfZGVidWcoJ0pRSFRNTF9JTklUJywgJ1JlZ2lzdGVyaW5nICcgKyBqcWh0bWxfY29tcG9uZW50cy5sZW5ndGggKyAnIEpxaHRtbCBDb21wb25lbnRzJyk7XG5cbiAgICAgICAgZm9yIChsZXQgY29tcG9uZW50IG9mIGpxaHRtbF9jb21wb25lbnRzKSB7XG4gICAgICAgICAgICBqcWh0bWwucmVnaXN0ZXJfY29tcG9uZW50KGNvbXBvbmVudC5jbGFzc19uYW1lLCBjb21wb25lbnQuY2xhc3Nfb2JqZWN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZyYW1ld29yayBtb2R1bGVzIGluaXQgcGhhc2UgLSBCaW5kIGNvbXBvbmVudHMgYW5kIGluaXRpYWxpemUgRE9NXG4gICAgICogVGhpcyBydW5zIGFmdGVyIHRlbXBsYXRlcyBhcmUgcmVnaXN0ZXJlZCB0byBiaW5kIGNvbXBvbmVudCBjbGFzc2VzXG4gICAgICogQHBhcmFtIHtqUXVlcnl9IFskc2NvcGVdIE9wdGlvbmFsIHNjb3BlIHRvIHNlYXJjaCB3aXRoaW4gKGRlZmF1bHRzIHRvIGJvZHkpXG4gICAgICogQHJldHVybnMge0FycmF5PFByb21pc2U+fHVuZGVmaW5lZH0gQXJyYXkgb2YgcHJvbWlzZXMgZm9yIHJlY3Vyc2l2ZSBjYWxscywgdW5kZWZpbmVkIGZvciB0b3AtbGV2ZWxcbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQoJHNjb3BlKSB7XG4gICAgICAgIGNvbnN0IGlzX3RvcF9sZXZlbCA9ICEkc2NvcGU7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHNfbmVlZGluZ19pbml0ID0gKCRzY29wZSB8fCAkKCdib2R5JykpLmZpbmQoJy5KcWh0bWxfQ29tcG9uZW50X0luaXQnKTtcbiAgICAgICAgaWYgKGNvbXBvbmVudHNfbmVlZGluZ19pbml0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ0pRSFRNTF9JTklUJywgYEluaXRpYWxpemluZyAke2NvbXBvbmVudHNfbmVlZGluZ19pbml0Lmxlbmd0aH0gRE9NIGNvbXBvbmVudHNgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbXBvbmVudHNfbmVlZGluZ19pbml0LmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuXG4gICAgICAgICAgICAvLyBTa2lwIGlmIGVsZW1lbnQgaXMgbm8gbG9uZ2VyIGF0dGFjaGVkIHRvIHRoZSBkb2N1bWVudFxuICAgICAgICAgICAgLy8gKG1heSBoYXZlIGJlZW4gcmVtb3ZlZCBieSBhIHBhcmVudCBjb21wb25lbnQncyAuZW1wdHkoKSBjYWxsKVxuICAgICAgICAgICAgaWYgKCFkb2N1bWVudC5jb250YWlucygkZWxlbWVudFswXSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGFueSBwYXJlbnQgaGFzIEpxaHRtbF9Db21wb25lbnRfSW5pdCBjbGFzcyAtIHNraXAgbmVzdGVkIGNvbXBvbmVudHNcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSAkZWxlbWVudFswXS5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdKcWh0bWxfQ29tcG9uZW50X0luaXQnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIFNraXAgdGhpcyBlbGVtZW50LCBpdCdzIG5lc3RlZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50X25hbWUgPSAkZWxlbWVudC5hdHRyKCdkYXRhLWNvbXBvbmVudC1pbml0LW5hbWUnKTtcblxuICAgICAgICAgICAgLy8galF1ZXJ5J3MgLmRhdGEoKSBkb2Vzbid0IGF1dG8tcGFyc2UgSlNPTiAtIHdlIG5lZWQgdG8gcGFyc2UgaXQgbWFudWFsbHlcbiAgICAgICAgICAgIGxldCBjb21wb25lbnRfYXJncyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgYXJnc19zdHJpbmcgPSAkZWxlbWVudC5hdHRyKCdkYXRhLWNvbXBvbmVudC1hcmdzJyk7XG5cbiAgICAgICAgICAgIC8vIFVuc2V0IGNvbXBvbmVudC0gcGhwIHNpZGUgaW5pdGlhbGl6YXRpb24gYXJncywgaXQgaXMgbm8gbG9uZ2VyIG5lZWRlZCBhcyBhIGNvbXBpb25lbnQgYXR0cmlidXRlXG4gICAgICAgICAgICAvLyBVbnNldHRpbmcgYWxzbyBwcmV2ZW50cyB1bmRlc2lyZWQgYWNjZXNzIHRvIHRoaXMgY29kZSBpbiBvdGhlciBwYXJ0cyBvZiB0aGUgcHJvZ3JhbSwgcHJldmVuaW5nIGFuXG4gICAgICAgICAgICAvLyB1bndhbnRlZCBmdXR1cmUgZGVwZW5kZW5jeSBvbiB0aGlzIHBhcmFkaWdtXG4gICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVBdHRyKCdkYXRhLWNvbXBvbmVudC1pbml0LW5hbWUnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZUF0dHIoJ2RhdGEtY29tcG9uZW50LWFyZ3MnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZURhdGEoJ2NvbXBvbmVudC1pbml0LW5hbWUnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZURhdGEoJ2NvbXBvbmVudC1hcmdzJyk7XG5cbiAgICAgICAgICAgIGlmIChhcmdzX3N0cmluZykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzID0gSlNPTi5wYXJzZShhcmdzX3N0cmluZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbSlFIVE1MIEludGVncmF0aW9uXSBGYWlsZWQgdG8gcGFyc2UgY29tcG9uZW50IGFyZ3MgZm9yICR7Y29tcG9uZW50X25hbWV9OmAsIGUpO1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJncyA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbXBvbmVudF9uYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJhbnNmb3JtICQgcHJlZml4ZWQga2V5cyB0byBkYXRhLSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29tcG9uZW50X2FyZ3MpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChrZXkuc3RhcnRzV2l0aCgnJCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkW2tleS5zdWJzdHJpbmcoMSldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ2RhdGEtJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkW2tleS5zdWJzdHJpbmcoNSldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJnc19maWx0ZXJlZFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSBpbm5lciBIVE1MIGFzIHN0cmluZyBmb3IgbmVzdGVkIGNvbXBvbmVudCBwcm9jZXNzaW5nXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkLl9pbm5lcl9odG1sID0gJGVsZW1lbnQuaHRtbCgpO1xuICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5lbXB0eSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgaW5pdCBjbGFzcyBiZWZvcmUgaW5zdGFudGlhdGlvbiB0byBwcmV2ZW50IHJlLWluaXRpYWxpemF0aW9uXG4gICAgICAgICAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZUNsYXNzKCdKcWh0bWxfQ29tcG9uZW50X0luaXQnKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgcHJvbWlzZSBmb3IgdGhpcyBjb21wb25lbnQncyBpbml0aWFsaXphdGlvblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wb25lbnRfcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgalF1ZXJ5IGNvbXBvbmVudCBwbHVnaW4gdG8gY3JlYXRlIHRoZSBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsdWdpbiBoYW5kbGVzIGVsZW1lbnQgaW50ZXJuYWxseSwganVzdCBwYXNzIGFyZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgdXBkYXRlZCAkZWxlbWVudCBmcm9tXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJGVsZW1lbnQuY29tcG9uZW50KGNvbXBvbmVudF9uYW1lLCBjb21wb25lbnRfYXJnc19maWx0ZXJlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudC5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbGxlY3QgcHJvbWlzZXMgZnJvbSBuZXN0ZWQgY29tcG9uZW50c1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0dGluZyB0aGUgdXBkYXRlZCBjb21wb25lbnQgaGVyZSAtIGlmIHRoZSB0YWcgbmFtZSB3YXMgbm90IGRpdiwgdGhlIGVsZW1lbnQgd291bGQgaGF2ZSBiZWVuIHJlY3JlYXRlZCwgc28gd2UgbmVlZCB0byBnZXQgdGhlIGVsZW1lbnQgc2V0IG9uIHRoZSBjb21wb25lbnQsIG5vdCBmcm9tIG91ciBlYXJsaWVyIHNlbGVjdG9yXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXN0ZWRfcHJvbWlzZXMgPSBKcWh0bWxfSW50ZWdyYXRpb24uX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQoY29tcG9uZW50LiQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goLi4ubmVzdGVkX3Byb21pc2VzKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgdGhpcyBjb21wb25lbnQncyBwcm9taXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkuJDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjb21wb25lbnRfcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTCBJbnRlZ3JhdGlvbl0gRmFpbGVkIHRvIGluaXRpYWxpemUgY29tcG9uZW50ICR7Y29tcG9uZW50X25hbWV9OmAsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZGV0YWlsczonLCBlcnJvci5zdGFjayB8fCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUb3AtbGV2ZWwgY2FsbDogc3Bhd24gYXN5bmMgaGFuZGxlciB0byB3YWl0IGZvciBhbGwgcHJvbWlzZXMsIHRoZW4gdHJpZ2dlciBldmVudFxuICAgICAgICBpZiAoaXNfdG9wX2xldmVsKSB7XG4gICAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBSc3guX3JzeF9jYWxsX2FsbF9jbGFzc2VzKCdvbl9qcWh0bWxfcmVhZHknKTtcbiAgICAgICAgICAgICAgICBSc3gudHJpZ2dlcignanFodG1sX3JlYWR5Jyk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVjdXJzaXZlIGNhbGw6IHJldHVybiBwcm9taXNlcyBmb3IgcGFyZW50IHRvIGNvbGxlY3RcbiAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgcmVnaXN0ZXJlZCBjb21wb25lbnQgbmFtZXNcbiAgICAgKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gQXJyYXkgb2YgY29tcG9uZW50IG5hbWVzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9jb21wb25lbnRfbmFtZXMoKSB7XG4gICAgICAgIHJldHVybiBqcWh0bWwuZ2V0X2NvbXBvbmVudF9uYW1lcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGEgY29tcG9uZW50IGlzIHJlZ2lzdGVyZWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBDb21wb25lbnQgbmFtZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGNvbXBvbmVudCBpcyByZWdpc3RlcmVkXG4gICAgICovXG4gICAgc3RhdGljIGhhc19jb21wb25lbnQobmFtZSkge1xuICAgICAgICByZXR1cm4ganFodG1sLmhhc19jb21wb25lbnQobmFtZSk7XG4gICAgfVxufVxuXG4vLyBSU1ggbWFuaWZlc3QgYXV0b21hdGljYWxseSBtYWtlcyBjbGFzc2VzIGdsb2JhbCAtIG5vIG1hbnVhbCBhc3NpZ25tZW50IG5lZWRlZFxuIiwiLyoqXG4gKiBUZXN0X01vZGFsX0Zvcm1cbiAqXG4gKiBTaW1wbGUgdGVzdCBmb3JtIGNvbXBvbmVudCBkZW1vbnN0cmF0aW5nIG1vZGFsIGZvcm0gZnVuY3Rpb25hbGl0eS5cbiAqL1xuY2xhc3MgVGVzdF9Nb2RhbF9Gb3JtIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIHdpdGggcHJvdmlkZWQgZGF0YSBvciBlbXB0eSBvYmplY3RcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlcyA9IHRoaXMuYXJncy5kYXRhIHx8IHt9O1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuZGF0YS52YWx1ZXMpIHtcbiAgICAgICAgICAgIHRoaXMudmFscyh0aGlzLmRhdGEudmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgZm9ybSB2YWx1ZXNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gdmFsdWVzIC0gT3B0aW9uYWwgdmFsdWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R8bnVsbH0gUmV0dXJucyB2YWx1ZXMgaWYgZ2V0dGluZywgbnVsbCBpZiBzZXR0aW5nXG4gICAgICovXG4gICAgdmFscyh2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICBpZiAodmFsdWVzLm5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCduYW1lX2lucHV0JykudmFsKHZhbHVlcy5uYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh2YWx1ZXMuZW1haWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdlbWFpbF9pbnB1dCcpLnZhbCh2YWx1ZXMuZW1haWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlcy5yb2xlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgncm9sZV9zZWxlY3QnKS52YWwodmFsdWVzLnJvbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbmFtZTogdGhpcy4kaWQoJ25hbWVfaW5wdXQnKS52YWwoKSxcbiAgICAgICAgICAgICAgICBlbWFpbDogdGhpcy4kaWQoJ2VtYWlsX2lucHV0JykudmFsKCksXG4gICAgICAgICAgICAgICAgcm9sZTogdGhpcy4kaWQoJ3JvbGVfc2VsZWN0JykudmFsKCksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgRGV2X01vZGFscyB7XG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgaWYgKCEkKCcuRGV2X01vZGFscycpLmV4aXN0cygpKSByZXR1cm47XG4gICAgICAgIERldl9Nb2RhbHMuaW5pdCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICAvLyBTaW1wbGUgRGlhbG9nc1xuICAgICAgICAkKCcjdGVzdC1hbGVydCcpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IE1vZGFsLmFsZXJ0KCdUaGlzIGlzIGEgc2ltcGxlIGFsZXJ0IG1lc3NhZ2UnKTtcbiAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ3NpbXBsZScsICdBbGVydCBhY2tub3dsZWRnZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtYWxlcnQtdGl0bGUnKS5vbignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBNb2RhbC5hbGVydCgnQ3VzdG9tIFRpdGxlJywgJ1RoaXMgYWxlcnQgaGFzIGEgY3VzdG9tIHRpdGxlJyk7XG4gICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdzaW1wbGUnLCAnQWxlcnQgd2l0aCB0aXRsZSBhY2tub3dsZWRnZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtY29uZmlybScpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLmNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBwcm9jZWVkPycpO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc2ltcGxlJywgYENvbmZpcm0gcmVzdWx0OiAke3Jlc3VsdH1gKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtY29uZmlybS10aXRsZScpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLmNvbmZpcm0oJ0RlbGV0ZSBJdGVtJywgJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBpdGVtPycpO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc2ltcGxlJywgYENvbmZpcm0gd2l0aCB0aXRsZSByZXN1bHQ6ICR7cmVzdWx0fWApO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1wcm9tcHQnKS5vbignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5wcm9tcHQoJ1doYXQgaXMgeW91ciBuYW1lPycpO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc2ltcGxlJywgYFByb21wdCByZXN1bHQ6ICR7cmVzdWx0ID09PSBmYWxzZSA/ICdDYW5jZWxsZWQnIDogcmVzdWx0fWApO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1wcm9tcHQtZGVmYXVsdCcpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLnByb21wdCgnRW50ZXIgeW91ciBlbWFpbDonLCBudWxsLCAndXNlckBleGFtcGxlLmNvbScpO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc2ltcGxlJywgYFByb21wdCB3aXRoIGRlZmF1bHQgcmVzdWx0OiAke3Jlc3VsdCA9PT0gZmFsc2UgPyAnQ2FuY2VsbGVkJyA6IHJlc3VsdH1gKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtcHJvbXB0LW11bHRpbGluZScpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLnByb21wdCgnRW50ZXIgeW91ciBmZWVkYmFjazonLCBudWxsLCAnVHlwZSB5b3VyIGZlZWRiYWNrIGhlcmUuLi4nLCB0cnVlKTtcbiAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ3NpbXBsZScsIGBNdWx0aWxpbmUgcHJvbXB0IHJlc3VsdDogJHtyZXN1bHQgPT09IGZhbHNlID8gJ0NhbmNlbGxlZCcgOiByZXN1bHR9YCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyN0ZXN0LXByb21wdC1yaWNoJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIHJpY2ggZm9ybWF0dGVkIGNvbnRlbnQgYWJvdmUgdGhlIGlucHV0XG4gICAgICAgICAgICBjb25zdCAkcmljaF9jb250ZW50ID0gJCgnPGRpdj4nKVxuICAgICAgICAgICAgICAgIC5hcHBlbmQoJCgnPGg1IHN0eWxlPVwiY29sb3I6ICMyYzNlNTA7IG1hcmdpbi1ib3R0b206IDE1cHg7XCI+JykudGV4dCgnVXNlciBSZWdpc3RyYXRpb24gRm9ybScpKVxuICAgICAgICAgICAgICAgIC5hcHBlbmQoXG4gICAgICAgICAgICAgICAgICAgICQoJzxwIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMTBweDtcIj4nKS5odG1sKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ1BsZWFzZSBlbnRlciB5b3VyIDxzdHJvbmcgc3R5bGU9XCJjb2xvcjogI2U3NGMzYztcIj5mdWxsIG5hbWU8L3N0cm9uZz4gYXMgaXQgYXBwZWFycyBvbiB5b3VyICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZW0gc3R5bGU9XCJjb2xvcjogIzM0OThkYjtcIj5vZmZpY2lhbCBkb2N1bWVudHM8L2VtPi4nXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgJCgnPHAgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMHB4O1wiPicpLmh0bWwoXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4gc3R5bGU9XCJ0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgY29sb3I6ICMyN2FlNjA7XCI+UmVxdWlyZWQgZmllbGRzPC9zcGFuPiBtdXN0IGJlIGNvbXBsZXRlZCBiZWZvcmUgc3VibWlzc2lvbi4nXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgJCgnPGRpdiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6ICNmZmYzY2Q7IGJvcmRlci1sZWZ0OiA0cHggc29saWQgI2ZmYzEwNzsgcGFkZGluZzogMTBweDsgbWFyZ2luLWJvdHRvbTogMjBweDtcIj4nKS5odG1sKFxuICAgICAgICAgICAgICAgICAgICAgICAgJzxzdHJvbmc+4pqgIE5vdGU6PC9zdHJvbmc+IDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxNHB4O1wiPllvdXIgbmFtZSB3aWxsIGJlIHVzZWQgZm9yIGFsbCBvZmZpY2lhbCBjb3JyZXNwb25kZW5jZS48L3NwYW4+J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5hcHBlbmQoJCgnPHAgc3R5bGU9XCJmb250LXNpemU6IDEzcHg7IGNvbG9yOiAjN2Y4YzhkOyBtYXJnaW4tYm90dG9tOiAyNXB4O1wiPicpLnRleHQoJ0V4YW1wbGU6IEpvaG4gTWljaGFlbCBTbWl0aCcpKTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwucHJvbXB0KCRyaWNoX2NvbnRlbnQsIG51bGwsICcnLCBmYWxzZSk7XG4gICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdzaW1wbGUnLCBgUmljaCB0ZXh0IHByb21wdCByZXN1bHQ6ICR7cmVzdWx0ID09PSBmYWxzZSA/ICdDYW5jZWxsZWQnIDogcmVzdWx0fWApO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1wcm9tcHQtdmFsaWRhdGlvbicpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIC8vIERlbW9uc3RyYXRlIHZhbGlkYXRpb24gcGF0dGVybjoga2VlcCByZW9wZW5pbmcgdW50aWwgdmFsaWQgb3IgY2FuY2VsbGVkXG4gICAgICAgICAgICBsZXQgZW1haWwgPSAnJztcbiAgICAgICAgICAgIGxldCBlcnJvciA9IG51bGw7XG4gICAgICAgICAgICBsZXQgdmFsaWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgd2hpbGUgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgIGVtYWlsID0gYXdhaXQgTW9kYWwucHJvbXB0KCdFbWFpbCBWYWxpZGF0aW9uJywgJ1BsZWFzZSBlbnRlciBhIHZhbGlkIGVtYWlsIGFkZHJlc3M6JywgZW1haWwsIGZhbHNlLCBlcnJvcik7XG5cbiAgICAgICAgICAgICAgICAvLyBVc2VyIGNhbmNlbGxlZFxuICAgICAgICAgICAgICAgIGlmIChlbWFpbCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc2ltcGxlJywgJ1Byb21wdCBjYW5jZWxsZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFZhbGlkYXRlIGVtYWlsIChzaW1wbGUgY2hlY2spXG4gICAgICAgICAgICAgICAgaWYgKCFlbWFpbCB8fCBlbWFpbC50cmltKCkgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gJ0VtYWlsIGFkZHJlc3MgaXMgcmVxdWlyZWQnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWVtYWlsLmluY2x1ZGVzKCdAJykgfHwgIWVtYWlsLmluY2x1ZGVzKCcuJykpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAnUGxlYXNlIGVudGVyIGEgdmFsaWQgZW1haWwgYWRkcmVzcyAobXVzdCBjb250YWluIEAgYW5kIC4pJztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVtYWlsLmxlbmd0aCA8IDUpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAnRW1haWwgYWRkcmVzcyBpcyB0b28gc2hvcnQnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFZhbGlkIVxuICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdzaW1wbGUnLCBgVmFsaWQgZW1haWwgZW50ZXJlZDogJHtlbWFpbH1gKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ3VzdG9tIE1vZGFsc1xuICAgICAgICAkKCcjdGVzdC1jdXN0b20tMmJ0bicpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLnNob3coe1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnQ3VzdG9tIFR3byBCdXR0b24gTW9kYWwnLFxuICAgICAgICAgICAgICAgIGJvZHk6ICdUaGlzIG1vZGFsIGhhcyB0d28gY3VzdG9tIGJ1dHRvbnMgd2l0aCBkaWZmZXJlbnQgdmFsdWVzJyxcbiAgICAgICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdPcHRpb24gQScsIHZhbHVlOiAnb3B0aW9uX2EnLCBjbGFzczogJ2J0bi1zZWNvbmRhcnknIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdPcHRpb24gQicsIHZhbHVlOiAnb3B0aW9uX2InLCBjbGFzczogJ2J0bi1wcmltYXJ5JywgZGVmYXVsdDogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ2N1c3RvbScsIGBUd28gYnV0dG9uIHJlc3VsdDogJHtyZXN1bHR9YCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyN0ZXN0LWN1c3RvbS0zYnRuJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwuc2hvdyh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdUaHJlZSBCdXR0b24gTW9kYWwnLFxuICAgICAgICAgICAgICAgIGJvZHk6ICdDaG9vc2Ugb25lIG9mIHRocmVlIG9wdGlvbnMnLFxuICAgICAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICAgICAgeyBsYWJlbDogJ0NhbmNlbCcsIHZhbHVlOiBmYWxzZSwgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyB9LFxuICAgICAgICAgICAgICAgICAgICB7IGxhYmVsOiAnU2F2ZSBEcmFmdCcsIHZhbHVlOiAnZHJhZnQnLCBjbGFzczogJ2J0bi1pbmZvJyB9LFxuICAgICAgICAgICAgICAgICAgICB7IGxhYmVsOiAnUHVibGlzaCcsIHZhbHVlOiAncHVibGlzaCcsIGNsYXNzOiAnYnRuLXN1Y2Nlc3MnLCBkZWZhdWx0OiB0cnVlIH0sXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnY3VzdG9tJywgYFRocmVlIGJ1dHRvbiByZXN1bHQ6ICR7cmVzdWx0fWApO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1jdXN0b20tZGFuZ2VyJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwuc2hvdyh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdEYW5nZXJvdXMgQWN0aW9uJyxcbiAgICAgICAgICAgICAgICBib2R5OiAnVGhpcyBhY3Rpb24gY2Fubm90IGJlIHVuZG9uZS4gQXJlIHlvdSBhYnNvbHV0ZWx5IHN1cmU/JyxcbiAgICAgICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdDYW5jZWwnLCB2YWx1ZTogZmFsc2UsIGNsYXNzOiAnYnRuLXNlY29uZGFyeScgfSxcbiAgICAgICAgICAgICAgICAgICAgeyBsYWJlbDogJ0RlbGV0ZSBGb3JldmVyJywgdmFsdWU6IHRydWUsIGNsYXNzOiAnYnRuLWRhbmdlcicsIGRlZmF1bHQ6IHRydWUgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdjdXN0b20nLCBgRGFuZ2Vyb3VzIGFjdGlvbiByZXN1bHQ6ICR7cmVzdWx0fWApO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1jdXN0b20tanF1ZXJ5Jykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGNvbnRlbnQgPSAkKCc8ZGl2PicpXG4gICAgICAgICAgICAgICAgLmFwcGVuZCgkKCc8cD4nKS50ZXh0KCdUaGlzIG1vZGFsIGJvZHkgY29udGFpbnMgalF1ZXJ5IGVsZW1lbnRzJykpXG4gICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgJCgnPHVsPicpXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCQoJzxsaT4nKS50ZXh0KCdGaXJzdCBpdGVtJykpXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCQoJzxsaT4nKS50ZXh0KCdTZWNvbmQgaXRlbScpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgkKCc8bGk+JykudGV4dCgnVGhpcmQgaXRlbScpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAuYXBwZW5kKCQoJzxwPicpLmh0bWwoJzxzdHJvbmc+Rm9ybWF0dGVkIHRleHQ8L3N0cm9uZz4gYW5kIDxlbT5zdHlsaW5nPC9lbT4nKSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLnNob3coe1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnalF1ZXJ5IENvbnRlbnQnLFxuICAgICAgICAgICAgICAgIGJvZHk6ICRjb250ZW50LFxuICAgICAgICAgICAgICAgIGJ1dHRvbnM6IFt7IGxhYmVsOiAnQ2xvc2UnLCB2YWx1ZTogdHJ1ZSwgY2xhc3M6ICdidG4tcHJpbWFyeScsIGRlZmF1bHQ6IHRydWUgfV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ2N1c3RvbScsICdqUXVlcnkgY29udGVudCBtb2RhbCBjbG9zZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtY3VzdG9tLXdpZGUnKS5vbignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5zaG93KHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1dpZGUgTW9kYWwgKDEyMDBweCknLFxuICAgICAgICAgICAgICAgIGJvZHk6ICdUaGlzIG1vZGFsIGhhcyBhIG1heCB3aWR0aCBvZiAxMjAwcHgsIHVzZWZ1bCBmb3IgZm9ybXMgb3IgZGF0YSB0YWJsZXMgdGhhdCBuZWVkIG1vcmUgaG9yaXpvbnRhbCBzcGFjZS4nLFxuICAgICAgICAgICAgICAgIG1heF93aWR0aDogMTIwMCxcbiAgICAgICAgICAgICAgICBidXR0b25zOiBbeyBsYWJlbDogJ0Nsb3NlJywgdmFsdWU6IHRydWUsIGNsYXNzOiAnYnRuLXByaW1hcnknLCBkZWZhdWx0OiB0cnVlIH1dLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdjdXN0b20nLCAnV2lkZSBtb2RhbCBjbG9zZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3BlY2lhbCBCZWhhdmlvcnNcbiAgICAgICAgJCgnI3Rlc3QtdW5jbG9zYWJsZScpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIE1vZGFsLnVuY2xvc2FibGUoJ1Byb2Nlc3NpbmcnLCAnUGxlYXNlIHdhaXQgd2hpbGUgd2UgcHJvY2VzcyB5b3VyIHJlcXVlc3QuLi4nKTtcblxuICAgICAgICAgICAgLy8gU2ltdWxhdGUgcHJvY2Vzc2luZ1xuICAgICAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgTW9kYWwuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdzcGVjaWFsJywgJ1VuY2xvc2FibGUgbW9kYWwgd2FzIGNsb3NlZCBwcm9ncmFtbWF0aWNhbGx5IGFmdGVyIDMgc2Vjb25kcycpO1xuICAgICAgICAgICAgfSwgMzAwMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyN0ZXN0LXF1ZXVlJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gUXVldWUgMyBtb2RhbHNcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UxID0gTW9kYWwuYWxlcnQoJ0ZpcnN0IE1vZGFsJywgJ1RoaXMgaXMgdGhlIGZpcnN0IG1vZGFsIGluIHRoZSBxdWV1ZScpO1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZTIgPSBNb2RhbC5hbGVydCgnU2Vjb25kIE1vZGFsJywgJ1RoaXMgaXMgdGhlIHNlY29uZCBtb2RhbCBpbiB0aGUgcXVldWUnKTtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UzID0gTW9kYWwuYWxlcnQoJ1RoaXJkIE1vZGFsJywgJ1RoaXMgaXMgdGhlIHRoaXJkIGFuZCBmaW5hbCBtb2RhbCcpO1xuXG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbcHJvbWlzZTEsIHByb21pc2UyLCBwcm9taXNlM10pO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc3BlY2lhbCcsICdBbGwgMyBxdWV1ZWQgbW9kYWxzIGNvbXBsZXRlZCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICAkKCcjdGVzdC1lcnJvcicpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX29iaiA9IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyB5b3VyIHJlcXVlc3QnLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoZXJyb3Jfb2JqLCAnRXJyb3InKTtcbiAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ3NwZWNpYWwnLCAnRXJyb3IgbW9kYWwgc2hvd24nKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtdGFsbCcpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGxldCB0YWxsX2NvbnRlbnQgPSAnPGg2PlNjcm9sbGFibGUgQ29udGVudDwvaDY+JztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IDUwOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0YWxsX2NvbnRlbnQgKz0gYDxwPlBhcmFncmFwaCAke2l9OiBUaGlzIGlzIGEgbG9uZyBwYXJhZ3JhcGggdGhhdCBoZWxwcyBkZW1vbnN0cmF0ZSBzY3JvbGxpbmcgYmVoYXZpb3Igd2hlbiBjb250ZW50IGV4Y2VlZHMgdGhlIDgwJSB2aWV3cG9ydCBoZWlnaHQgdGhyZXNob2xkLjwvcD5gO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5zaG93KHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1RhbGwgQ29udGVudCAoU2Nyb2xsaW5nIFRlc3QpJyxcbiAgICAgICAgICAgICAgICBib2R5OiB0YWxsX2NvbnRlbnQsXG4gICAgICAgICAgICAgICAgYnV0dG9uczogW3sgbGFiZWw6ICdDbG9zZScsIHZhbHVlOiB0cnVlLCBjbGFzczogJ2J0bi1wcmltYXJ5JywgZGVmYXVsdDogdHJ1ZSB9XSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnc3BlY2lhbCcsICdUYWxsIGNvbnRlbnQgbW9kYWwgY2xvc2VkJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZvcm0gTW9kYWxzXG4gICAgICAgICQoJyN0ZXN0LWZvcm0tc2ltcGxlJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwuZm9ybSh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdVc2VyIFJlZ2lzdHJhdGlvbicsXG4gICAgICAgICAgICAgICAgY29tcG9uZW50OiAnVGVzdF9Nb2RhbF9Gb3JtJyxcbiAgICAgICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEdldCBmb3JtIHZhbHVlc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmb3JtLnZhbHMoKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTaW1wbGUgdmFsaWRhdGlvbiAtIGp1c3QgY2hlY2sgcmVxdWlyZWQgZmllbGRzXG4gICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzLm5hbWUgfHwgIXZhbHVlcy5lbWFpbCB8fCAhdmFsdWVzLnJvbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnMoZm9ybS4kLCAnUGxlYXNlIGZpbGwgaW4gYWxsIHJlcXVpcmVkIGZpZWxkcycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBLZWVwIG1vZGFsIG9wZW5cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFNpbXVsYXRlIHNhdmluZ1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJldHVybiBkYXRhIHRvIGNsb3NlIG1vZGFsXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnZm9ybScsIGBGb3JtIHN1Ym1pdHRlZDogJHtqc29uX2VuY29kZShyZXN1bHQpfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgJ0Zvcm0gY2FuY2VsbGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyN0ZXN0LWZvcm0tdmFsaWRhdGlvbicpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLmZvcm0oe1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnVXNlciBSZWdpc3RyYXRpb24gKFdpdGggU2VydmVyIFZhbGlkYXRpb24pJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnQ6ICdUZXN0X01vZGFsX0Zvcm0nLFxuICAgICAgICAgICAgICAgIG9uX3N1Ym1pdDogYXN5bmMgKGZvcm0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IGZvcm0gdmFsdWVzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IGZvcm0udmFscygpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFNpbXVsYXRlIHNlcnZlci1zaWRlIHZhbGlkYXRpb25cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTaW11bGF0ZSB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcnMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZXMubmFtZSB8fCB2YWx1ZXMubmFtZS5sZW5ndGggPCAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMubmFtZSA9ICdOYW1lIG11c3QgYmUgYXQgbGVhc3QgMyBjaGFyYWN0ZXJzJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlcy5lbWFpbCB8fCAhdmFsdWVzLmVtYWlsLmluY2x1ZGVzKCdAJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycy5lbWFpbCA9ICdQbGVhc2UgZW50ZXIgYSB2YWxpZCBlbWFpbCBhZGRyZXNzJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlcy5yb2xlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMucm9sZSA9ICdQbGVhc2Ugc2VsZWN0IGEgcm9sZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgZXJyb3JzLCBzaG93IHRoZW0gYW5kIGtlZXAgbW9kYWwgb3BlblxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoZXJyb3JzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBGb3JtX1V0aWxzLmFwcGx5X2Zvcm1fZXJyb3JzKGZvcm0uJCwgZXJyb3JzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gS2VlcCBtb2RhbCBvcGVuXG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIC0gcmV0dXJuIGRhdGFcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgYEZvcm0gc3VibWl0dGVkIHN1Y2Nlc3NmdWxseTogJHtqc29uX2VuY29kZShyZXN1bHQpfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgJ0Zvcm0gY2FuY2VsbGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyN0ZXN0LWZvcm0tcHJlZmlsbGVkJykub24oJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwuZm9ybSh7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdFZGl0IFVzZXIgUHJvZmlsZScsXG4gICAgICAgICAgICAgICAgY29tcG9uZW50OiAnVGVzdF9Nb2RhbF9Gb3JtJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJnczoge1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnSm9obiBTbWl0aCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBlbWFpbDogJ2pvaG4uc21pdGhAZXhhbXBsZS5jb20nLFxuICAgICAgICAgICAgICAgICAgICAgICAgcm9sZTogJ21hbmFnZXInLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VibWl0X2xhYmVsOiAnVXBkYXRlJyxcbiAgICAgICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IGZvcm0udmFscygpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFNpbXBsZSB2YWxpZGF0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzLm5hbWUgfHwgIXZhbHVlcy5lbWFpbCB8fCAhdmFsdWVzLnJvbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IE1vZGFsLmFsZXJ0KCdQbGVhc2UgZmlsbCBpbiBhbGwgcmVxdWlyZWQgZmllbGRzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBTaW11bGF0ZSB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgYFByb2ZpbGUgdXBkYXRlZDogJHtqc29uX2VuY29kZShyZXN1bHQpfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgJ1VwZGF0ZSBjYW5jZWxsZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgJCgnI3Rlc3QtZm9ybS1waW4nKS5vbignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0VudGVyIFZlcmlmaWNhdGlvbiBDb2RlJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnQ6ICdQaW5fVmVyaWZpY2F0aW9uX0Zvcm0nLFxuICAgICAgICAgICAgICAgIHN1Ym1pdF9sYWJlbDogJ1ZlcmlmeScsXG4gICAgICAgICAgICAgICAgbWF4X3dpZHRoOiA0NTAsXG4gICAgICAgICAgICAgICAgb25fc3VibWl0OiBhc3luYyAoZm9ybSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwaW4gPSBmb3JtLnZhbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFZhbGlkYXRlIFBJTiBpcyBjb21wbGV0ZVxuICAgICAgICAgICAgICAgICAgICBpZiAocGluLmxlbmd0aCAhPT0gNikge1xuICAgICAgICAgICAgICAgICAgICAgICAgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyhmb3JtLiQsICdQbGVhc2UgZW50ZXIgYWxsIDYgZGlnaXRzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBTaW11bGF0ZSBQSU4gdmVyaWZpY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsZWVwKDgwMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gU2ltdWxhdGUgY2hlY2tpbmcgYWdhaW5zdCBjb3JyZWN0IFBJTlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3JyZWN0X3BpbiA9ICcxMjM0NTYnO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGluICE9PSBjb3JyZWN0X3Bpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyhmb3JtLiQsIGBJbmNvcnJlY3QgUElOLiAoSGludDogdHJ5ICR7Y29ycmVjdF9waW59KWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIFBJTiBhbmQgcmVmb2N1cyBmaXJzdCBpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS52YWwoJycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzc1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBwaW46IHBpbiwgdmVyaWZpZWQ6IHRydWUgfTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdmb3JtJywgYFBJTiB2ZXJpZmllZCBzdWNjZXNzZnVsbHk6ICR7cmVzdWx0LnBpbn1gKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgRGV2X01vZGFscy5zaG93X3Jlc3VsdCgnZm9ybScsICdQSU4gdmVyaWZpY2F0aW9uIGNhbmNlbGxlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2RhbCBTdGF0ZVxuICAgICAgICAkKCcjY2hlY2stc3RhdGUnKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICBpc19vcGVuOiBNb2RhbC5pc19vcGVuKCksXG4gICAgICAgICAgICAgICAgY3VycmVudF9tb2RhbDogTW9kYWwuZ2V0X2N1cnJlbnQoKSAhPT0gbnVsbCA/ICdNb2RhbCBpbnN0YW5jZSBleGlzdHMnIDogbnVsbCxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IGpzb25fZW5jb2RlKHN0YXRlLCBudWxsLCAyKTtcbiAgICAgICAgICAgICQoJyNzdGF0ZS1yZXN1bHQnKS5zaG93KCk7XG4gICAgICAgICAgICAkKCcjc3RhdGUtcmVzdWx0LXRleHQnKS50ZXh0KGZvcm1hdHRlZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICQoJyNmb3JjZS1jbG9zZScpLm9uKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmIChNb2RhbC5pc19vcGVuKCkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBNb2RhbC5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIERldl9Nb2RhbHMuc2hvd19yZXN1bHQoJ3NwZWNpYWwnLCAnTW9kYWwgd2FzIGZvcmNlIGNsb3NlZCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBEZXZfTW9kYWxzLnNob3dfcmVzdWx0KCdzcGVjaWFsJywgJ05vIG1vZGFsIGlzIGN1cnJlbnRseSBvcGVuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBzaG93X3Jlc3VsdChzZWN0aW9uLCBtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0ICRyZXN1bHQgPSAkKGAjJHtzZWN0aW9ufS1yZXN1bHRgKTtcbiAgICAgICAgY29uc3QgJHRleHQgPSAkKGAjJHtzZWN0aW9ufS1yZXN1bHQtdGV4dGApO1xuXG4gICAgICAgICR0ZXh0LnRleHQobWVzc2FnZSk7XG4gICAgICAgICRyZXN1bHQuc2hvdygpO1xuXG4gICAgICAgIC8vIEhpZGUgYWZ0ZXIgNSBzZWNvbmRzXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgJHJlc3VsdC5mYWRlT3V0KCk7XG4gICAgICAgIH0sIDUwMDApO1xuICAgIH1cbn1cbiIsImNsYXNzIERldl9BdHRhY2htZW50cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5EZXZfQXR0YWNobWVudHNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICBjb25zb2xlLmxvZygnRGV2X0F0dGFjaG1lbnRzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gSGFuZGxlIHVwbG9hZCBidXR0b24gY2xpY2sgLSB0cmlnZ2VyIGhpZGRlbiBmaWxlIGlucHV0XG4gICAgICAgICQoJyNiYXNpYy11cGxvYWQtYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAkKCcjYmFzaWMtdXBsb2FkLWlucHV0JykuY2xpY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGZpbGUgc2VsZWN0aW9uXG4gICAgICAgICQoJyNiYXNpYy11cGxvYWQtaW5wdXQnKS5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBlLnRhcmdldC5maWxlc1swXTtcbiAgICAgICAgICAgIGlmICghZmlsZSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAvLyBVcGRhdGUgc3RhdHVzXG4gICAgICAgICAgICAkKCcjdXBsb2FkLXN0YXR1cycpLnRleHQoZmlsZS5uYW1lKTtcblxuICAgICAgICAgICAgLy8gVXBsb2FkIHRoZSBmaWxlXG4gICAgICAgICAgICBEZXZfQXR0YWNobWVudHMudXBsb2FkX2ltYWdlKGZpbGUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgdXBsb2FkX2ltYWdlKGZpbGUpIHtcbiAgICAgICAgLy8gU2hvdyBzcGlubmVyIG9uIHByb2ZpbGUgaW1hZ2Ugb25seVxuICAgICAgICAkKCcjc3Bpbm5lci1wcm9maWxlJykucmVtb3ZlQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAkKCcjdGh1bWItcHJvZmlsZScpLmNzcygnb3BhY2l0eScsICcwLjMnKTtcblxuICAgICAgICAvLyBDcmVhdGUgRm9ybURhdGEgZm9yIGZpbGUgdXBsb2FkXG4gICAgICAgIGNvbnN0IGZvcm1fZGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtX2RhdGEuYXBwZW5kKCdmaWxlJywgZmlsZSk7XG4gICAgICAgIGZvcm1fZGF0YS5hcHBlbmQoJ3NpdGVfaWQnLCAnMScpO1xuICAgICAgICBmb3JtX2RhdGEuYXBwZW5kKCdmaWxlYWJsZV90eXBlJywgJ2Rldl90ZXN0Jyk7XG4gICAgICAgIGZvcm1fZGF0YS5hcHBlbmQoJ2ZpbGVhYmxlX2NhdGVnb3J5JywgJ2F0dGFjaG1lbnRfZGVtbycpO1xuXG4gICAgICAgIC8vIFVwbG9hZCBmaWxlIHZpYSBBSkFYXG4gICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6ICcvX3VwbG9hZCcsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBmb3JtX2RhdGEsXG4gICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogZmFsc2UsXG4gICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdVcGxvYWQgc3VjY2Vzc2Z1bCEnKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnUmVzcG9uc2U6JywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdGaWxlIGtleTonLCByZXNwb25zZS5hdHRhY2htZW50LmtleSk7XG5cbiAgICAgICAgICAgICAgICAvLyBTaG93IHRodW1ibmFpbHMgY29udGFpbmVyXG4gICAgICAgICAgICAgICAgJCgnI3RodW1ibmFpbHMtY29udGFpbmVyJykucmVtb3ZlQ2xhc3MoJ2Qtbm9uZScpO1xuXG4gICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGh1bWJuYWlsIFVSTHNcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSByZXNwb25zZS5hdHRhY2htZW50LmtleTtcbiAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSByZXNwb25zZS5hdHRhY2htZW50LmZpbGVfZXh0ZW5zaW9uO1xuXG4gICAgICAgICAgICAgICAgJCgnI3RodW1iLXByb2ZpbGUnKS5hdHRyKCdzcmMnLCBgL190aHVtYm5haWwvJHtrZXl9L2NvdmVyLzk2Lzk2YCk7XG4gICAgICAgICAgICAgICAgJCgnI3RodW1iLTIwMCcpLmF0dHIoJ3NyYycsIGAvX3RodW1ibmFpbC8ke2tleX0vY292ZXIvMjAwLzIwMGApO1xuICAgICAgICAgICAgICAgICQoJyN0aHVtYi0yNDB4MTgwJykuYXR0cignc3JjJywgYC9fdGh1bWJuYWlsLyR7a2V5fS9jb3Zlci8yNDAvMTgwYCk7XG5cbiAgICAgICAgICAgICAgICAvLyBVc2UgaWNvbiBlbmRwb2ludCBmb3IgZmlsZSB0eXBlIGljb25cbiAgICAgICAgICAgICAgICAkKCcjdGh1bWItaWNvbicpLmF0dHIoJ3NyYycsIGAvX2ljb25fYnlfZXh0ZW5zaW9uLyR7ZXh0ZW5zaW9ufT93aWR0aD0xMDAmaGVpZ2h0PTEwMGApO1xuXG4gICAgICAgICAgICAgICAgLy8gU2V0IGRvd25sb2FkL2lubGluZSBVUkxzXG4gICAgICAgICAgICAgICAgJCgnI2J0bi12aWV3LWlubGluZScpLmF0dHIoJ2hyZWYnLCBgL19pbmxpbmUvJHtrZXl9YCk7XG4gICAgICAgICAgICAgICAgJCgnI2J0bi12aWV3LWRvd25sb2FkJykuYXR0cignaHJlZicsIGAvX2Rvd25sb2FkLyR7a2V5fWApO1xuXG4gICAgICAgICAgICAgICAgLy8gSGlkZSBzcGlubmVyLCByZXN0b3JlIG9wYWNpdHlcbiAgICAgICAgICAgICAgICAkKCcjc3Bpbm5lci1wcm9maWxlJykuYWRkQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgICAgICQoJyN0aHVtYi1wcm9maWxlJykuY3NzKCdvcGFjaXR5JywgJzEnKTtcblxuICAgICAgICAgICAgICAgIC8vIENsZWFyIGZpbGUgaW5wdXQgZm9yIGZ1dHVyZSB1cGxvYWRzXG4gICAgICAgICAgICAgICAgJCgnI2Jhc2ljLXVwbG9hZC1pbnB1dCcpLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgJCgnI3VwbG9hZC1zdGF0dXMnKS5odG1sKGA8c3BhbiBjbGFzcz1cInRleHQtc3VjY2Vzc1wiPjxpIGNsYXNzPVwiYmkgYmktY2hlY2stY2lyY2xlXCI+PC9pPiBVcGxvYWQgY29tcGxldGUhPC9zcGFuPmApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbih4aHIsIHN0YXR1cywgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdVcGxvYWQgZmFpbGVkOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSZXNwb25zZTonLCB4aHIucmVzcG9uc2VKU09OKTtcblxuICAgICAgICAgICAgICAgIC8vIEhpZGUgc3Bpbm5lciwgcmVzdG9yZSBvcGFjaXR5XG4gICAgICAgICAgICAgICAgJCgnI3NwaW5uZXItcHJvZmlsZScpLmFkZENsYXNzKCdkLW5vbmUnKTtcbiAgICAgICAgICAgICAgICAkKCcjdGh1bWItcHJvZmlsZScpLmNzcygnb3BhY2l0eScsICcxJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBDbGVhciBmaWxlIGlucHV0XG4gICAgICAgICAgICAgICAgJCgnI2Jhc2ljLXVwbG9hZC1pbnB1dCcpLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgJCgnI3VwbG9hZC1zdGF0dXMnKS5odG1sKGA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+PGkgY2xhc3M9XCJiaSBiaS14LWNpcmNsZVwiPjwvaT4gVXBsb2FkIGZhaWxlZDwvc3Bhbj5gKTtcblxuICAgICAgICAgICAgICAgIC8vIFNob3cgZXJyb3IgdG8gdXNlclxuICAgICAgICAgICAgICAgIGFsZXJ0KCdVcGxvYWQgZmFpbGVkOiAnICsgKHhoci5yZXNwb25zZUpTT04/LmVycm9yIHx8IGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIERldl9BdHRhY2htZW50cy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBEZXZfSW5kZXgge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRGV2X0luZGV4XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdEZXZfSW5kZXggaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRGV2X0luZGV4LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsIi8qKlxuICogRGF0YUdyaWQgQ29tcG9uZW50IChQaGFzZSAxKVxuICpcbiAqIER1ZSB0byB0aGUgbW9yZSBkeW5hbWljIG5hdHVyZSBvZiB0aGlzIGNvbXBvbmVudCwgd2UgYXJlIGhhbmRsaW5nIGxvYWQgLyByZW5kZXIgbGlmZWN5Y2xlc1xuICogZGlyZWN0bHkgaW4gdGhpcyBjbGFzcyByYXRoZXIgdGhhbiB1c2luZyB0aGUgb25fbG9hZCBsaWZlY3ljbGUgZXZlbnRcbiAqXG4gKiAqKkZlYXR1cmVzKio6XG4gKiAtIEFqYXggZGF0YSBmZXRjaGluZ1xuICogLSBTb3J0aW5nIChjbGljayBoZWFkZXJzKVxuICogLSBQYWdpbmF0aW9uIChuZXh0L3ByZXYvcGFnZSBzZWxlY3QpXG4gKiAtIFJvdyBzZWxlY3Rpb24gKGNoZWNrYm94ZXMpXG4gKiAtIENTViBleHBvcnQgKHNlbGVjdGVkIHJvd3MsIGN1cnJlbnQgcGFnZSlcbiAqIC0gVVJMIHN0YXRlIHN5bmNocm9uaXphdGlvblxuICpcbiAqICoqVXNhZ2UqKjpcbiAqIGBgYGh0bWxcbiAqIDxDb250YWN0c19EYXRhR3JpZCAkYXBpPVwiRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclwiIC8+XG4gKiBgYGBcbiAqXG4gKiAqKlJlcXVpcmVkIEFyZ3MqKjpcbiAqIC0gYGFwaWAgLSBDb250cm9sbGVyIGNsYXNzIG5hbWUgd2l0aCBkYXRhZ3JpZF9mZXRjaCgpIEFqYXggZW5kcG9pbnRcbiAqXG4gKiAqKk9wdGlvbmFsIEFyZ3MqKjpcbiAqIC0gYHBlcl9wYWdlYCAtIERlZmF1bHQgcm93cyBwZXIgcGFnZSAoZGVmYXVsdDogMjUpXG4gKiAtIGBzb3J0YCAtIERlZmF1bHQgc29ydCBjb2x1bW4gKGRlZmF1bHQ6IGZpcnN0IGNvbHVtbilcbiAqIC0gYG9yZGVyYCAtIERlZmF1bHQgc29ydCBvcmRlciAoZGVmYXVsdDogJ2FzYycpXG4gKi9cbmNsYXNzIERhdGFHcmlkX0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gSW5pdGlhbGl6ZSBkYXRhIGJlZm9yZSBmaXJzdCByZW5kZXJcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBJbml0aWFsaXplIGRhdGEgc3RhdGUgaW1tZWRpYXRlbHkgc28gdGVtcGxhdGUgY2FuIHJlbmRlclxuICAgICAgICB0aGF0LmRhdGEucm93cyA9IFtdO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoYXQuZGF0YS50b3RhbF9wYWdlcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gQ2FsbHMgd2hlbiBkYXRhZ3JpZCBmaXJzdCBpbml0aWFsaXplZFxuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF0aGF0LmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0RhdGFncmlkICcgKyB0aGF0LmNvbXBvbmVudF9uYW1lKCkgKyAnIHJlcXVpcmVzIGFyZ3MuZGF0YV9zb3VyY2Ugc2V0IHRvIGEgQWpheF9FbmRwb2ludCBvYmplY3QnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGRlZmF1bHRzIGZvciBsYXRlciBjb21wYXJpc29uXG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X3BhZ2UgPSAxO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9wZXJfcGFnZSA9IHRoYXQuYXJncy5wZXJfcGFnZSA/PyAxNTtcbiAgICAgICAgdGhhdC5kYXRhLmRlZmF1bHRfc29ydCA9IHRoYXQuYXJncy5zb3J0ID8/IG51bGw7XG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID0gdGhhdC5hcmdzLm9yZGVyID8/ICdhc2MnO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBTZXQgY29uZmlndXJlZCB2YWx1ZXNcbiAgICAgICAgdGhhdC5kYXRhLnBlcl9wYWdlID0gdGhhdC5kYXRhLmRlZmF1bHRfcGVyX3BhZ2U7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBzdGF0ZSBmcm9tIFVSTCBoYXNoIGlmIHByZXNlbnQsIG90aGVyd2lzZSB1c2UgZGVmYXVsdHNcbiAgICAgICAgY29uc3QgaGFzaF9wYWdlID0gUnN4LmdldF9wYWdlX3N0YXRlKHRoYXQuX2NpZCArICdfcGFnZScpO1xuICAgICAgICBjb25zdCBoYXNoX3NvcnQgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19zb3J0Jyk7XG4gICAgICAgIGNvbnN0IGhhc2hfb3JkZXIgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19vcmRlcicpO1xuICAgICAgICBjb25zdCBoYXNoX2ZpbHRlciA9IFJzeC5nZXRfcGFnZV9zdGF0ZSh0aGF0Ll9jaWQgKyAnX2ZpbHRlcicpO1xuXG4gICAgICAgIHRoYXQuZGF0YS5wYWdlID0gaGFzaF9wYWdlID8gaW50KGhhc2hfcGFnZSkgOiB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEuc29ydCA9IGhhc2hfc29ydCB8fCB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0O1xuICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSBoYXNoX29yZGVyIHx8IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyO1xuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gaGFzaF9maWx0ZXIgfHwgdGhhdC5kYXRhLmRlZmF1bHRfZmlsdGVyO1xuXG4gICAgICAgIHRoYXQucmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpO1xuICAgICAgICB0aGF0LnJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpO1xuXG4gICAgICAgIC8vIElmIGhhc2ggaGFkIGEgZmlsdGVyIHZhbHVlLCBwb3B1bGF0ZSB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGlmICh0aGF0LmRhdGEuZmlsdGVyKSB7XG4gICAgICAgICAgICBjb25zdCAkZmlsdGVyID0gdGhhdC4kaWQoJ2ZpbHRlcl9pbnB1dCcpO1xuICAgICAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgJGZpbHRlci52YWwodGhhdC5kYXRhLmZpbHRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNZWFzdXJlIHJvdyBoZWlnaHQgYW5kIHNldCBmaXhlZCB0Ym9keSBoZWlnaHQgKGFsbCBpbiBvbmUgZnJhbWUpXG4gICAgICAgIGF3YWl0IHRoYXQubWVhc3VyZV9hbmRfc2V0X2ZpeGVkX2hlaWdodCgpO1xuXG4gICAgICAgIC8vIEZldGNoIHRoZSBpbml0aWFsIHBhZ2UgKHJlc3BlY3RzIGhhc2ggc3RhdGUpXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKHRoYXQuZGF0YS5wYWdlKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgaGVhZGVyIG9ubHkgaWYgc29ydC9vcmRlciBjaGFuZ2VkXG4gICAgdXBkYXRlX2hlYWRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRyYWNrIGxhc3QgcmVuZGVyZWQgc3RhdGVcbiAgICAgICAgaWYgKCF0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZSkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBzb3J0OiB0aGF0LmRhdGEuc29ydCxcbiAgICAgICAgICAgIG9yZGVyOiB0aGF0LmRhdGEub3JkZXIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgaWYgdmFsdWVzIGNoYW5nZWRcbiAgICAgICAgaWYgKHRoYXQuX2xhc3RfaGVhZGVyX3N0YXRlLnNvcnQgIT09IGN1cnJlbnQuc29ydCB8fCB0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZS5vcmRlciAhPT0gY3VycmVudC5vcmRlcikge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSBjdXJyZW50O1xuICAgICAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfaGVhZGVyJykucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgcGFnaW5hdGlvbiBvbmx5IGlmIHZhbHVlcyBjaGFuZ2VkXG4gICAgdXBkYXRlX3BhZ2luYXRpb24oKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUcmFjayBsYXN0IHJlbmRlcmVkIHN0YXRlXG4gICAgICAgIGlmICghdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBwYWdlOiB0aGF0LmRhdGEucGFnZSxcbiAgICAgICAgICAgIHBlcl9wYWdlOiB0aGF0LmRhdGEucGVyX3BhZ2UsXG4gICAgICAgICAgICB0b3RhbDogdGhhdC5kYXRhLnRvdGFsLFxuICAgICAgICAgICAgdG90YWxfcGFnZXM6IHRoYXQuZGF0YS50b3RhbF9wYWdlcyxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBPbmx5IHJlbmRlciBpZiB2YWx1ZXMgY2hhbmdlZFxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGFnZSAhPT0gY3VycmVudC5wYWdlIHx8XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGVyX3BhZ2UgIT09IGN1cnJlbnQucGVyX3BhZ2UgfHxcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZS50b3RhbCAhPT0gY3VycmVudC50b3RhbCB8fFxuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlLnRvdGFsX3BhZ2VzICE9PSBjdXJyZW50LnRvdGFsX3BhZ2VzXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlID0gY3VycmVudDtcbiAgICAgICAgICAgIHRoYXQuaWQoJ3BhZ2luYXRpb25faW5mbycpLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTG9hZCBkYXRhIGZvciBzcGVjaWZpZWQgcGFnZSBhbmQgcmUtcmVuZGVyIGRhdGFcbiAgICBhc3luYyBsb2FkX3BhZ2UocGFnZSkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IGxvYWRpbmcgc3RhdGVcbiAgICAgICAgdGhhdC5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHBhZ2U7XG5cbiAgICAgICAgLy8gVXBkYXRlIFVJIHdpdGggcmVxdWVzdGVkIHZhbHVlcyAob3B0aW1pc3RpYyB1cGRhdGUpXG4gICAgICAgIHRoYXQudXBkYXRlX2hlYWRlcigpO1xuICAgICAgICB0aGF0LnVwZGF0ZV9wYWdpbmF0aW9uKCk7XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgbG9hZGluZyBzdGF0ZSBpZiBubyBkYXRhIHlldCAoaW5pdGlhbCBsb2FkKVxuICAgICAgICBpZiAodGhhdC5kYXRhLnJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IEFqYXguY2FsbCh0aGF0LmFyZ3MuZGF0YV9zb3VyY2UsIHtcbiAgICAgICAgICAgIHBhZ2U6IHBhZ2UsXG4gICAgICAgICAgICBwZXJfcGFnZTogdGhhdC5kYXRhLnBlcl9wYWdlLFxuICAgICAgICAgICAgc29ydDogdGhhdC5kYXRhLnNvcnQsXG4gICAgICAgICAgICBvcmRlcjogdGhhdC5kYXRhLm9yZGVyLFxuICAgICAgICAgICAgZmlsdGVyOiB0aGF0LmRhdGEuZmlsdGVyLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgZGF0YVxuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgdGhhdC5kYXRhLnJvd3MgPSByZXNwb25zZS5yZWNvcmRzO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHJlc3BvbnNlLnBhZ2U7XG4gICAgICAgIHRoYXQuZGF0YS5wZXJfcGFnZSA9IHJlc3BvbnNlLnBlcl9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEudG90YWwgPSByZXNwb25zZS50b3RhbDtcbiAgICAgICAgdGhhdC5kYXRhLnRvdGFsX3BhZ2VzID0gcmVzcG9uc2UudG90YWxfcGFnZXM7XG4gICAgICAgIHRoYXQuZGF0YS5zb3J0ID0gcmVzcG9uc2Uuc29ydDtcbiAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gcmVzcG9uc2Uub3JkZXI7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IHJlc3BvbnNlLnJlY29yZHMubGVuZ3RoID09PSAwO1xuXG4gICAgICAgIC8vIFBlcnNpc3Qgc3RhdGUgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nL3NoYXJpbmdcbiAgICAgICAgLy8gT25seSBzZXQgdmFsdWVzIHRoYXQgZGlmZmVyIGZyb20gZGVmYXVsdHMgKG51bGwgcmVtb3ZlcyB0aGUga2V5KVxuICAgICAgICBjb25zdCBzdGF0ZSA9IHt9O1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3BhZ2UnXSA9IHRoYXQuZGF0YS5wYWdlICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlID8gdGhhdC5kYXRhLnBhZ2UgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3NvcnQnXSA9IHRoYXQuZGF0YS5zb3J0ICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0ID8gdGhhdC5kYXRhLnNvcnQgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX29yZGVyJ10gPSB0aGF0LmRhdGEub3JkZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID8gdGhhdC5kYXRhLm9yZGVyIDogbnVsbDtcbiAgICAgICAgc3RhdGVbdGhhdC5fY2lkICsgJ19maWx0ZXInXSA9IHRoYXQuZGF0YS5maWx0ZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X2ZpbHRlciA/IHRoYXQuZGF0YS5maWx0ZXIgOiBudWxsO1xuXG4gICAgICAgIFJzeC5zZXRfYWxsX3BhZ2Vfc3RhdGUoc3RhdGUpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBVSSB3aXRoIHNlcnZlciByZXNwb25zZSAob25seSByZW5kZXJzIGlmIGNoYW5nZWQpXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC51cGRhdGVfaGVhZGVyKCk7XG4gICAgICAgIHRoYXQudXBkYXRlX3BhZ2luYXRpb24oKTtcblxuICAgICAgICAvLyBTY3JvbGwgdG8gdG9wIG9mIGRhdGFncmlkIGlmIGl0J3Mgbm90IGN1cnJlbnRseSB2aXNpYmxlXG4gICAgICAgIHRoYXQuc2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQoKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgY2FsbGJhY2tzIGluIHRoaXMgZnVuY3Rpb24gZmlyZSBhZnRlciBlYWNoIHRhcmdldGVkIGNvbXBvbmVudCByZS1yZW5kZXJzXG4gICAgcmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEF0dGFjaCByb3cgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9ib2R5IHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfYm9keScpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnREdUQl9SJyk7XG4gICAgICAgICAgICAvLyBTdGVwIDE6IFdyYXAgY2VsbHMgaW4gZGF0YS1ocmVmIHJvd3Mgd2l0aCBhbmNob3IgdGFnc1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0cltkYXRhLWhyZWZdJylcbiAgICAgICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCAkcm93ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhyZWYgPSAkcm93LmF0dHIoJ2RhdGEtaHJlZicpO1xuXG4gICAgICAgICAgICAgICAgICAgICRyb3cuZmluZCgndGQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxldCAkY29sID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFNraXAgaWYgY2VsbCBhbHJlYWR5IGNvbnRhaW5zIGludGVyYWN0aXZlIGVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiAoJGNvbC5maW5kKCdhLCBidXR0b24sIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFdyYXAgZW50aXJlIGNlbGwgY29udGVudHMgaW4gYW4gYW5jaG9yIChwcmVzZXJ2ZSBET00gbm9kZXMgZm9yIGNvbXBvbmVudCBsaWZlY3ljbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBsZXQgJGFuY2hvciA9ICQoJzxhPicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBocmVmOiBocmVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGNsYXNzOiAnZGF0YWdyaWQtcm93LWxpbmsnXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIE1vdmUgZXhpc3RpbmcgY2hpbGQgbm9kZXMgaW50byBhbmNob3IgKHByZXNlcnZlcyBjb21wb25lbnRzIGFuZCB0aGVpciBzdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICRjb2wuY29udGVudHMoKS5hcHBlbmRUbygkYW5jaG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIEFkZCBhbmNob3IgdG8gY2VsbFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gJGNvbC5hcHBlbmQoJGFuY2hvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTdGVwIDI6IEZpbmQgYWxsIGNlbGxzIHdpdGggc2luZ2xlIGFuY2hvciBhcyBvbmx5IGNoaWxkIGFuZCBhcHBseSBmdWxsLXdpZHRoIHN0eWxpbmdcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgndGQnKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICRjb2wgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGNoaWxkcmVuID0gJGNvbC5jaGlsZHJlbigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNlbGwgY29udGFpbnMgZXhhY3RseSBvbmUgZGlyZWN0IGNoaWxkIHRoYXQgaXMgYW4gYW5jaG9yXG4gICAgICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmICRjaGlsZHJlbi5maXJzdCgpLmlzKCdhJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byB0cmFuc2ZlciBwYWRkaW5nIGZyb20gY2VsbCB0byBhbmNob3JcbiAgICAgICAgICAgICAgICAgICAgICAgICRjb2wuYWRkQ2xhc3MoJ2hhcy1mdWxsLWxpbmsnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjZWxsIGNvbnRhaW5zIG9ubHkgdGV4dCAobm8gY2hpbGQgZWxlbWVudHMpXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCRjaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byBhcHBseSB2ZXJ0aWNhbCBwYWRkaW5nIHRvIHRleHQtb25seSBjZWxsc1xuICAgICAgICAgICAgICAgICAgICAgICAgJGNvbC5hZGRDbGFzcygnaGFzLW9ubHktdGV4dCcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBzb3J0YWJsZSBoZWFkZXIgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9oZWFkZXIgcmVuZGVyc1xuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gVHJhbnNmb3JtIHRoW2RhdGEtc29ydGJ5XSBlbGVtZW50cyBieSB3cmFwcGluZyBjb250ZW50cyBpbiBjbGlja2FibGUgbGlua1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0aFtkYXRhLXNvcnRieV0nKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICR0aCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzb3J0YnkgPSAkdGguYXR0cignZGF0YS1zb3J0YnknKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBGaW5kIG91dCB3aHkgdGhpcyBvbigncmVuZGVyJykgY2FsbGJhY2sgaXMgYmVpbmcgY2FsbGVkIHR3aWNlL29uIGFscmVhZHktcHJvY2Vzc2VkIEhUTUxcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB1bndyYXAgbG9naWMgc2hvdWxkbid0IGJlIG5lY2Vzc2FyeSAtIHRlbXBsYXRlIHNob3VsZCByZW5kZXIgZnJlc2ggZWFjaCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIC8vIEZvciBub3csIHVud3JhcCBhbHJlYWR5LXdyYXBwZWQgY29udGVudCB0byBwcmV2ZW50IGRvdWJsZS13cmFwcGluZ1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGV4aXN0aW5nX2xpbmsgPSAkdGguZmluZCgnYS5zb3J0YWJsZS1oZWFkZXInKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRlbnRzO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJGV4aXN0aW5nX2xpbmsubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW53cmFwIC0gZ2V0IHRoZSB0ZXh0IGNvbnRlbnQgd2l0aG91dCB0aGUgd3JhcHBlciBhbmQgYXJyb3dzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cyA9ICRleGlzdGluZ19saW5rLmNsb25lKCkuZmluZCgnaS5iaScpLnJlbW92ZSgpLmVuZCgpLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gJHRoLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1aWxkIHRoZSBhcnJvdyBpY29uIEhUTUwgaWYgdGhpcyBjb2x1bW4gaXMgY3VycmVudGx5IHNvcnRlZFxuICAgICAgICAgICAgICAgICAgICBsZXQgYXJyb3cgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5zb3J0ID09PSBzb3J0YnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycm93ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPT09ICdkZXNjJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICc8aSBjbGFzcz1cImJpIGJpLWNoZXZyb24tdXAgbXMtMVwiPjwvaT4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1kb3duIG1zLTFcIj48L2k+JztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgY29udGVudHMgd2l0aCB3cmFwcGVkIGxpbmsgKGZyZXNoIHdyYXBwZXIgZXZlcnkgdGltZSlcbiAgICAgICAgICAgICAgICAgICAgJHRoLmh0bWwoYDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzb3J0YWJsZS1oZWFkZXJcIiBkYXRhLXNvcnRieT1cIiR7c29ydGJ5fVwiPiR7Y29udGVudHN9JHthcnJvd308L2E+YCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEF0dGFjaCBjbGljayBoYW5kbGVycyB0byB0aGUgc29ydGFibGUgbGlua3Mgd2UganVzdCBjcmVhdGVkXG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2Euc29ydGFibGUtaGVhZGVyW2RhdGEtc29ydGJ5XScpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc29ydGJ5ID0gJCh0aGlzKS5hdHRyKCdkYXRhLXNvcnRieScpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LnNvcnRfYnkoc29ydGJ5KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXR0YWNoIHBhZ2luYXRpb24gY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBwYWdpbmF0aW9uX2NvbnRyb2xzIHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5wYWdlLWxpbmsnKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWdlID0gaW50KCRsaW5rLmF0dHIoJ2RhdGEtcGFnZScpKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZGlzYWJsZWQvZWxsaXBzaXMgY2xpY2tzXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFnZSB8fCBpc05hTihwYWdlKSB8fCAkbGluay5wYXJlbnQoKS5oYXNDbGFzcygnZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTG9hZCB0aGUgcmVxdWVzdGVkIHBhZ2VcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5sb2FkX3BhZ2UocGFnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBjbGVhciBmaWx0ZXIgYnV0dG9uIGhhbmRsZXIgLSByZS1ydW5zIGV2ZXJ5IHRpbWUgZGF0YWdyaWRfdGFibGVfYm9keSByZW5kZXJzXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgJGNsZWFyX2J0biA9IHRoYXQuJGlkKCdjbGVhcl9maWx0ZXJfYnRuJyk7XG4gICAgICAgICAgICBpZiAoJGNsZWFyX2J0biAmJiAkY2xlYXJfYnRuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAkY2xlYXJfYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5jbGVhcl9maWx0ZXIoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gU29ydCBieSBzcGVjaWZpZWQgY29sdW1uLCB0b2dnbGluZyBvcmRlciBpZiBhbHJlYWR5IHNvcnRlZCBieSB0aGF0IGNvbHVtblxuICAgIHNvcnRfYnkoY29sdW1uKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUb2dnbGUgb3JkZXIgaWYgY2xpY2tpbmcgc2FtZSBjb2x1bW4sIG90aGVyd2lzZSBkZWZhdWx0IHRvIGFzY1xuICAgICAgICBpZiAodGhhdC5kYXRhLnNvcnQgPT09IGNvbHVtbikge1xuICAgICAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gdGhhdC5kYXRhLm9yZGVyID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhhdC5kYXRhLnNvcnQgPSBjb2x1bW47XG4gICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSAnYXNjJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbG9hZCBjdXJyZW50IHBhZ2Ugd2l0aCBuZXcgc29ydFxuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC5sb2FkX3BhZ2UodGhhdC5kYXRhLnBhZ2UpO1xuICAgIH1cblxuICAgIC8vIFJlZ2lzdGVyIGZpbHRlciBpbnB1dCBoYW5kbGVyc1xuICAgIHJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEZpbmQgZmlsdGVyIGlucHV0IGJ5IGNvbW1vbiBpZGVudGlmaWVyc1xuICAgICAgICBsZXQgJGZpbHRlciA9IHRoYXQuJGlkKCdmaWx0ZXJfaW5wdXQnKTtcbiAgICAgICAgaWYgKCEkZmlsdGVyIHx8ICRmaWx0ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyID0gdGhhdC4kLmZpbmQoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLmZpbHRlci1pbnB1dCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyLm9uKCdpbnB1dCBrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJfdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuICAgICAgICAgICAgICAgIHRoYXQuZmlsdGVyX2NoYW5nZWQoZmlsdGVyX3ZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZmlsdGVyX2NoYW5nZWQoZmlsdGVyKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gZmlsdGVyO1xuICAgICAgICB0aGF0LmxvYWRfcGFnZSgxKTtcbiAgICB9XG5cbiAgICAvLyBTY3JvbGwgdG8gZGF0YWdyaWQgdG9wIGlmIHRoZSB0b3AgZWRnZSBpcyBub3QgY3VycmVudGx5IHZpc2libGUgaW4gdmlld3BvcnRcbiAgICBzY3JvbGxfdG9fdG9wX2lmX25lZWRlZCgpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0ICRkYXRhZ3JpZCA9IHRoYXQuJDtcbiAgICAgICAgY29uc3QgZGF0YWdyaWRUb3AgPSAkZGF0YWdyaWQub2Zmc2V0KCkudG9wO1xuICAgICAgICBjb25zdCBzY3JvbGxUb3AgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG5cbiAgICAgICAgLy8gSWYgZGF0YWdyaWQgdG9wIGlzIGFib3ZlIHRoZSBjdXJyZW50IHZpZXdwb3J0LCBzY3JvbGwgdG8gc2hvdyBpdFxuICAgICAgICBpZiAoZGF0YWdyaWRUb3AgPCBzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIC8vIElmIGRhdGFncmlkIGlzIHdpdGhpbiAzMDBweCBvZiBwYWdlIHRvcCwgc2Nyb2xsIHRvIDBcbiAgICAgICAgICAgIGlmIChkYXRhZ3JpZFRvcCA8PSAzMDApIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnaW5zdGFudCcgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNjcm9sbCB0byAyMHB4IGFib3ZlIGRhdGFncmlkXG4gICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKHsgdG9wOiBkYXRhZ3JpZFRvcCAtIDIwLCBiZWhhdmlvcjogJ2luc3RhbnQnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWVhc3VyZSBhY3R1YWwgcm93IGhlaWdodCBhbmQgc2V0IGZpeGVkIHRib2R5IG1pbi1oZWlnaHRcbiAgICAvLyBBbGwgaGFwcGVucyBpbiBvbmUgYW5pbWF0aW9uIGZyYW1lIHNvIHVzZXIgZG9lc24ndCBzZWUgaXRcbiAgICBhc3luYyBtZWFzdXJlX2FuZF9zZXRfZml4ZWRfaGVpZ2h0KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgbmV4dCBhbmltYXRpb24gZnJhbWUgdG8gZW5zdXJlIERPTSBpcyByZWFkeVxuICAgICAgICBhd2FpdCBzbGVlcCgwKTtcblxuICAgICAgICBjb25zdCAkdGJvZHkgPSB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykuJDtcblxuICAgICAgICAvLyBUZW1wb3JhcmlseSByZW5kZXIgYSBzaW5nbGUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgIGNvbnN0ICRtZWFzdXJlbWVudF9yb3cgPSAkKCc8dHI+JykuY3NzKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpLmh0bWwoJzx0ZD5NZWFzdXJpbmcuLi48L3RkPicpO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCRtZWFzdXJlbWVudF9yb3cpO1xuXG4gICAgICAgIC8vIE1lYXN1cmUgdGhlIHJvdyBoZWlnaHRcbiAgICAgICAgY29uc3Qgcm93X2hlaWdodCA9ICRtZWFzdXJlbWVudF9yb3cub3V0ZXJIZWlnaHQoKTtcblxuICAgICAgICAvLyBSZW1vdmUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgICRtZWFzdXJlbWVudF9yb3cucmVtb3ZlKCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIGFuZCBzZXQgbWluLWhlaWdodCBiYXNlZCBvbiBwZXJfcGFnZVxuICAgICAgICBjb25zdCBtaW5faGVpZ2h0ID0gcm93X2hlaWdodCAqIHRoYXQuZGF0YS5wZXJfcGFnZTtcbiAgICAgICAgJHRib2R5LmNzcygnbWluLWhlaWdodCcsIG1pbl9oZWlnaHQgKyAncHgnKTtcblxuICAgICAgICAvLyBTdG9yZSBmb3IgZnV0dXJlIHJlZmVyZW5jZVxuICAgICAgICB0aGF0LmRhdGEucm93X2hlaWdodCA9IHJvd19oZWlnaHQ7XG4gICAgICAgIHRoYXQuZGF0YS50Ym9keV9taW5faGVpZ2h0ID0gbWluX2hlaWdodDtcbiAgICB9XG5cbiAgICAvLyBDbGVhciBmaWx0ZXIgYW5kIHJlc2V0IHRvIHBhZ2UgMVxuICAgIGNsZWFyX2ZpbHRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIHRoYXQuZGF0YS5maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBDbGVhciB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGNvbnN0ICRmaWx0ZXIgPSB0aGF0LiRpZCgnZmlsdGVyX2lucHV0Jyk7XG4gICAgICAgIGlmICgkZmlsdGVyICYmICRmaWx0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJGZpbHRlci52YWwoJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVsb2FkIGZyb20gcGFnZSAxXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKDEpO1xuICAgIH1cbn1cbiIsImNsYXNzIEFjdGl2aXR5X0ZlZWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuYWN0aXZpdGllcyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuYWN0aXZpdGllcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLmFjdGl2aXRpZXMgPSB0aGlzLmFyZ3MuYWN0aXZpdGllcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBPcHRpb25hbDogQXV0by1yZWZyZXNoXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYXV0b19yZWZyZXNoKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0X2F1dG9fcmVmcmVzaCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhcnRfYXV0b19yZWZyZXNoKCkge1xuICAgICAgICBjb25zdCBpbnRlcnZhbCA9IHRoaXMuYXJncy5yZWZyZXNoX2ludGVydmFsIHx8IDMwMDAwOyAvLyBEZWZhdWx0IDMwIHNlY29uZHNcblxuICAgICAgICB0aGlzLnJlZnJlc2hfdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgIH0sIGludGVydmFsKTtcbiAgICB9XG5cbiAgICBzdG9wX2F1dG9fcmVmcmVzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaF90aW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnJlZnJlc2hfdGltZXIpO1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoX3RpbWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHJlbG9hZF9kYXRhKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuYWN0aXZpdGllcyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBY3Rvcl9SZWZlcmVuY2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBzdHlsaW5nIC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsImNsYXNzIEFkdmFuY2VkX1NlYXJjaF9QYW5lbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBQb3B1bGF0ZSBkcm9wZG93bnMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jYXRlZ29yaWVzKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2F0ZWdvcnknKS5zZXRfb3B0aW9ucyh0aGlzLmFyZ3MuY2F0ZWdvcmllcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnRhZ3MpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCd0YWdzJykuc2V0X29wdGlvbnModGhpcy5hcmdzLnRhZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VhcmNoIGJ1dHRvblxuICAgICAgICB0aGlzLiRpZCgnc2VhcmNoX2J0bicpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnBlcmZvcm1fc2VhcmNoKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlc2V0IGJ1dHRvblxuICAgICAgICB0aGlzLiRpZCgncmVzZXRfYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2xvc2UgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdjbG9zZV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2Nsb3NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2Nsb3NlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuJC5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZvcm0gc3VibWl0XG4gICAgICAgIHRoaXMuJGlkKCdzZWFyY2hfZm9ybScpLm9uKCdzdWJtaXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5wZXJmb3JtX3NlYXJjaCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwZXJmb3JtX3NlYXJjaCgpIHtcbiAgICAgICAgY29uc3QgY3JpdGVyaWEgPSB7XG4gICAgICAgICAgICBrZXl3b3JkczogdGhpcy4kaWQoJ2tleXdvcmRzJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICBjYXRlZ29yeTogdGhpcy4kaWQoJ2NhdGVnb3J5JykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICB0YWdzOiB0aGlzLiRpZCgndGFncycpLmdldF92YWx1ZSgpLFxuICAgICAgICAgICAgZnJvbV9kYXRlOiB0aGlzLiRpZCgnZnJvbV9kYXRlJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICB0b19kYXRlOiB0aGlzLiRpZCgndG9fZGF0ZScpLmdldF92YWx1ZSgpLFxuICAgICAgICAgICAgc29ydF9ieTogdGhpcy4kaWQoJ3NvcnRfYnknKS52YWwoKSxcbiAgICAgICAgICAgIGV4YWN0X21hdGNoOiB0aGlzLiRpZCgnZXhhY3RfbWF0Y2gnKS5pcygnOmNoZWNrZWQnKVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJlbW92ZSBlbXB0eSB2YWx1ZXNcbiAgICAgICAgT2JqZWN0LmtleXMoY3JpdGVyaWEpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmICghY3JpdGVyaWFba2V5XSB8fCAoaXNfYXJyYXkoY3JpdGVyaWFba2V5XSkgJiYgY3JpdGVyaWFba2V5XS5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNyaXRlcmlhW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc2VhcmNoKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fc2VhcmNoKGNyaXRlcmlhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLiRpZCgna2V5d29yZHMnKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgnY2F0ZWdvcnknKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgndGFncycpLnNldF92YWx1ZShbXSk7XG4gICAgICAgIHRoaXMuJGlkKCdmcm9tX2RhdGUnKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgndG9fZGF0ZScpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdzb3J0X2J5JykudmFsKCdyZWxldmFuY2UnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2V4YWN0X21hdGNoJykucHJvcCgnY2hlY2tlZCcsIGZhbHNlKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3Jlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fcmVzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEFsZXJ0X0Jhbm5lciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBcHBseSB0eXBlIGZyb20gYXJncyAoc3VjY2VzcywgZGFuZ2VyLCB3YXJuaW5nLCBpbmZvKVxuICAgICAgICBpZiAodGhpcy5hcmdzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYWxlcnQtaW5mbycpLmFkZENsYXNzKGBhbGVydC0ke3RoaXMuYXJncy50eXBlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpc21pc3NpYmxlIGlmIG5vdCBuZWVkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNtaXNzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYWxlcnQtZGlzbWlzc2libGUnKTtcbiAgICAgICAgICAgIHRoaXMuJC5maW5kKCcuYnRuLWNsb3NlJykucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBdmF0YXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHNyYyBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zcmMpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdzcmMnLCB0aGlzLmFyZ3Muc3JjKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBzaXplICh4cywgc20sIG1kLCBsZywgeGwpXG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmFyZ3Muc2l6ZSB8fCAnbWQnO1xuICAgICAgICBjb25zdCBzaXplX21hcCA9IHtcbiAgICAgICAgICAgICd4cyc6ICcyNHB4JyxcbiAgICAgICAgICAgICdzbSc6ICczMnB4JyxcbiAgICAgICAgICAgICdtZCc6ICc0OHB4JyxcbiAgICAgICAgICAgICdsZyc6ICc2NHB4JyxcbiAgICAgICAgICAgICd4bCc6ICc5NnB4J1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuJC5jc3Moe1xuICAgICAgICAgICAgJ3dpZHRoJzogc2l6ZV9tYXBbc2l6ZV0sXG4gICAgICAgICAgICAnaGVpZ2h0Jzogc2l6ZV9tYXBbc2l6ZV0sXG4gICAgICAgICAgICAnb2JqZWN0LWZpdCc6ICdjb3ZlcidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQWx0ZXJuYXRpdmUgcmVuZGVyaW5nOiBzaG93IGluaXRpYWxzIHdoZW4gbm8gaW1hZ2Ugc291cmNlIHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLnNyYyAmJiB0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5zaG93X2luaXRpYWxzKHRoaXMuYXJncy5uYW1lKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNob3dfaW5pdGlhbHMobmFtZSkge1xuICAgICAgICAvLyBDb252ZXJ0IGltZyB0byBkaXYgd2l0aCBpbml0aWFsc1xuICAgICAgICBjb25zdCBpbml0aWFscyA9IG5hbWUuc3BsaXQoJyAnKS5tYXAobiA9PiBuWzBdKS5qb2luKCcnKS50b1VwcGVyQ2FzZSgpLnNsaWNlKDAsIDIpO1xuICAgICAgICBjb25zdCAkZGl2ID0gJCgnPGRpdj4nKVxuICAgICAgICAgICAgLmFkZENsYXNzKCdyb3VuZGVkLWNpcmNsZSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgYmctcHJpbWFyeSB0ZXh0LXdoaXRlIGZ3LWJvbGQnKVxuICAgICAgICAgICAgLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3dpZHRoJzogdGhpcy4kLmNzcygnd2lkdGgnKSxcbiAgICAgICAgICAgICAgICAnaGVpZ2h0JzogdGhpcy4kLmNzcygnaGVpZ2h0JylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGV4dChpbml0aWFscyk7XG5cbiAgICAgICAgdGhpcy4kLnJlcGxhY2VXaXRoKCRkaXYpO1xuICAgICAgICB0aGlzLiQgPSAkZGl2O1xuICAgIH1cbn1cbiIsImNsYXNzIEJsb2NrcXVvdGUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIEJyZWFkY3J1bWJzIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUGxhY2Vob2xkZXIgY29tcG9uZW50IC0gY3VycmVudGx5IGVtcHR5IGluIGRhc2hib2FyZCB1c2FnZVxufVxuIiwiY2xhc3MgQnVsa19BY3Rpb25fQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENsZWFyIHNlbGVjdGlvbiBvbiBjbG9zZVxuICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy4kLmhpZGUoKTtcbiAgICAgICAgICAgIC8vIFVuY2hlY2sgYWxsIGJveGVzXG4gICAgICAgICAgICBjb25zdCAkdGFibGUgPSB0aGlzLiQuY2xvc2VzdCgnLmNhcmQnKS5maW5kKCd0YWJsZScpO1xuICAgICAgICAgICAgJHRhYmxlLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNldF9jb3VudChjb3VudCkge1xuICAgICAgICB0aGlzLiQuZmluZCgnLmNvdW50JykudGV4dChjb3VudCk7XG4gICAgfVxufVxuIiwiY2xhc3MgQnVsa19TZWxlY3Rpb24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGNoZWNrYm94ID0gdGhpcy4kaWQoJ2NoZWNrYm94Jyk7XG5cbiAgICAgICAgLy8gVG9nZ2xlIGFsbCBjaGVja2JveGVzIGluIHRhYmxlIGJvZHlcbiAgICAgICAgJGNoZWNrYm94Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IGUudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgICAgICBjb25zdCAkdGFibGUgPSB0aGlzLiQuY2xvc2VzdCgndGFibGUnKTtcbiAgICAgICAgICAgICR0YWJsZS5maW5kKCd0Ym9keSBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5wcm9wKCdjaGVja2VkJywgY2hlY2tlZCk7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgdXBkYXRlIGV2ZW50XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UoY2hlY2tlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIEJ1dHRvbl9Hcm91cCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIENvbnRhaW5lciBmb3IgZ3JvdXBlZCBidXR0b25zIHdpdGggY29ubmVjdGVkIGJvcmRlcnNcbiAgICAvLyBCb290c3RyYXAgYnRuLWdyb3VwIGhhbmRsZXMgYWxsIHZpc3VhbCBncm91cGluZ1xufVxuIiwiY2xhc3MgQnV0dG9uX1ByaW1hcnkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQcmltYXJ5IGFjdGlvbiBidXR0b24gLSBoaWdoZXN0IHZpc3VhbCBoaWVyYXJjaHlcbiAgICAvLyBCb290c3RyYXAgYnRuLXByaW1hcnkgcHJvdmlkZXMgYWxsIHN0eWxpbmdcbn1cbiIsImNsYXNzIEJ1dHRvbl9TZWNvbmRhcnkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBTZWNvbmRhcnkgYWN0aW9uIGJ1dHRvbiAtIGxvd2VyIHByb21pbmVuY2UgdGhhbiBwcmltYXJ5XG4gICAgLy8gQm9vdHN0cmFwIGJ0bi1zZWNvbmRhcnkgcHJvdmlkZXMgZ3JheSBjb2xvciBzY2hlbWVcbn1cbiIsImNsYXNzIEJ1dHRvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIEJhc2UgYnV0dG9uIGNvbXBvbmVudCAtIG5vIHNwZWNpYWwgYmVoYXZpb3IgbmVlZGVkXG4gICAgLy8gQm9vdHN0cmFwIGhhbmRsZXMgYWxsIHN0YXRlcyAoaG92ZXIsIGFjdGl2ZSwgZm9jdXMsIGRpc2FibGVkKVxufVxuIiwiY2xhc3MgQ2FsZW5kYXJfRXZlbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGljaykge1xuICAgICAgICAgICAgdGhpcy4kLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2xpY2sodGhpcy5hcmdzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSG92ZXIgZWZmZWN0XG4gICAgICAgIHRoaXMuJC5vbignbW91c2VlbnRlcicsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygnc2hhZG93LXNtJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJC5vbignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnc2hhZG93LXNtJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIENhbGVuZGFyX0dyaWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50X2RhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICB0aGlzLnJlbmRlcl9jYWxlbmRhcigpO1xuXG4gICAgICAgIHRoaXMuJGlkKCdwcmV2X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudF9kYXRlLnNldE1vbnRoKHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCkgLSAxKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCduZXh0X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudF9kYXRlLnNldE1vbnRoKHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCkgKyAxKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCd0b2RheV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRfZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcl9jYWxlbmRhcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZW5kZXJfY2FsZW5kYXIoKSB7XG4gICAgICAgIGNvbnN0IHllYXIgPSB0aGlzLmN1cnJlbnRfZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIHRpdGxlXG4gICAgICAgIGNvbnN0IG1vbnRoX25hbWVzID0gWydKYW51YXJ5JywgJ0ZlYnJ1YXJ5JywgJ01hcmNoJywgJ0FwcmlsJywgJ01heScsICdKdW5lJyxcbiAgICAgICAgICAgICdKdWx5JywgJ0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlciddO1xuICAgICAgICB0aGlzLiRpZCgnbW9udGhfdGl0bGUnKS50ZXh0KGAke21vbnRoX25hbWVzW21vbnRoXX0gJHt5ZWFyfWApO1xuXG4gICAgICAgIC8vIEdldCBmaXJzdCBkYXkgb2YgbW9udGggYW5kIHRvdGFsIGRheXNcbiAgICAgICAgY29uc3QgZmlyc3RfZGF5ID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpLmdldERheSgpO1xuICAgICAgICBjb25zdCBkYXlzX2luX21vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKS5nZXREYXRlKCk7XG5cbiAgICAgICAgY29uc3QgJHRib2R5ID0gdGhpcy4kaWQoJ2NhbGVuZGFyX2JvZHknKTtcbiAgICAgICAgJHRib2R5LmVtcHR5KCk7XG5cbiAgICAgICAgbGV0IGRheSA9IDE7XG4gICAgICAgIGxldCAkdHIgPSBudWxsO1xuXG4gICAgICAgIC8vIEJ1aWxkIGNhbGVuZGFyIGdyaWRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgICAgICAgICR0ciA9ICQoJzx0cj4nKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCA3OyBqKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkdGQgPSAkKCc8dGQ+JykuY3NzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCc6ICcxMDBweCcsXG4gICAgICAgICAgICAgICAgICAgICd2ZXJ0aWNhbC1hbGlnbic6ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICAncGFkZGluZyc6ICc4cHgnXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMCAmJiBqIDwgZmlyc3RfZGF5KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEVtcHR5IGNlbGwgYmVmb3JlIG1vbnRoIHN0YXJ0c1xuICAgICAgICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkYXkgPiBkYXlzX2luX21vbnRoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEVtcHR5IGNlbGwgYWZ0ZXIgbW9udGggZW5kc1xuICAgICAgICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRGF5IGNlbGxcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGRheV9udW0gPSAkKCc8ZGl2PicpLmFkZENsYXNzKCdmdy1ib2xkIG1iLTInKS50ZXh0KGRheSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSGlnaGxpZ2h0IHRvZGF5XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRheSA9PT0gdG9kYXkuZ2V0RGF0ZSgpICYmIG1vbnRoID09PSB0b2RheS5nZXRNb250aCgpICYmIHllYXIgPT09IHRvZGF5LmdldEZ1bGxZZWFyKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICRkYXlfbnVtLmFkZENsYXNzKCd0ZXh0LXByaW1hcnknKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnYm9yZGVyLXByaW1hcnknKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICR0ZC5hcHBlbmQoJGRheV9udW0pO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCBldmVudHMgZm9yIHRoaXMgZGF5IGlmIHByb3ZpZGVkXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3MuZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmdldF9ldmVudHNfZm9yX2RhdGUoeWVhciwgbW9udGgsIGRheSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgJGV2ZW50ID0gJCgnPGRpdj4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2JhZGdlIGJnLXByaW1hcnkgdGV4dC10cnVuY2F0ZSB3LTEwMCBtYi0xIHRleHQtc3RhcnQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3NzKCdjdXJzb3InLCAncG9pbnRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50ZXh0KGV2ZW50LnRpdGxlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRldmVudC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZXZlbnRfY2xpY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9ldmVudF9jbGljayhldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0ZC5hcHBlbmQoJGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgJHRkLmF0dHIoJ2RhdGEtZGF0ZScsIGAke3llYXJ9LSR7c3RyKG1vbnRoICsgMSkucGFkU3RhcnQoMiwgJzAnKX0tJHtzdHIoZGF5KS5wYWRTdGFydCgyLCAnMCcpfWApO1xuICAgICAgICAgICAgICAgICAgICAkdGQuY3NzKCdjdXJzb3InLCAncG9pbnRlcicpO1xuXG4gICAgICAgICAgICAgICAgICAgICR0ZC5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9kYXRlX2NsaWNrICYmICEkKGUudGFyZ2V0KS5oYXNDbGFzcygnYmFkZ2UnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9kYXRlX2NsaWNrKCR0ZC5hdHRyKCdkYXRhLWRhdGUnKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGRheSsrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuXG4gICAgICAgICAgICBpZiAoZGF5ID4gZGF5c19pbl9tb250aCkgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZXZlbnRzX2Zvcl9kYXRlKHllYXIsIG1vbnRoLCBkYXkpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuZXZlbnRzKSByZXR1cm4gW107XG5cbiAgICAgICAgY29uc3QgZGF0ZV9zdHIgPSBgJHt5ZWFyfS0ke3N0cihtb250aCArIDEpLnBhZFN0YXJ0KDIsICcwJyl9LSR7c3RyKGRheSkucGFkU3RhcnQoMiwgJzAnKX1gO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3MuZXZlbnRzLmZpbHRlcihldmVudCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuZGF0ZSA9PT0gZGF0ZV9zdHI7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qKlxuICogQ2FyZCAtIEJvb3RzdHJhcCA1IENvbnRlbnQgQ29udGFpbmVyIENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFByaW1hcnkgY29udGVudCBjb250YWluZXIgdXNpbmcgQm9vdHN0cmFwIC5jYXJkIGNsYXNzXG4gKiBEZXNpZ246IFB1cmUgQm9vdHN0cmFwIC0gYm9yZGVyLTAgd2l0aCBzaGFkb3cgZm9yIG1vZGVybiBWb2x0IGFlc3RoZXRpY1xuICovXG5jbGFzcyBDYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gQ2FyZCBpcyBhIHB1cmUgY29udGFpbmVyIGNvbXBvbmVudCAtIG5vIGxpZmVjeWNsZSBtZXRob2RzIG5lZWRlZFxuICAgIC8vIEFsbCBzdHlsaW5nIGNvbWVzIGZyb20gQm9vdHN0cmFwIGNsYXNzZXM6IGNhcmQsIGJvcmRlci0wLCBzaGFkb3dcbn1cbiIsImNsYXNzIENoYXJ0X0NvbXBvbmVudCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFBsYWNlaG9sZGVyIGNvbXBvbmVudCAtIG5vIGZ1bmN0aW9uYWxpdHkgeWV0XG59XG4iLCIvKipcbiAqIENoZWNrYm94IC0gQm9vdHN0cmFwIDUgQ2hlY2tib3ggSW5wdXQgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogU2luZ2xlIGNoZWNrYm94IGZvciB5ZXMvbm8sIHRydWUvZmFsc2Ugc2VsZWN0aW9uc1xuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY2hlY2staW5wdXQgc3R5bGluZ1xuICogV3JhcHBlcjogVHlwaWNhbGx5IHVzZWQgd2l0aGluIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+IGZvciBwcm9wZXIgbGF5b3V0XG4gKi9cbmNsYXNzIENoZWNrYm94IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCBjaGVja2VkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2hlY2tlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgQ29kZV9CbG9jayBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yIChzeW50YXggaGlnaGxpZ2h0aW5nIGNvdWxkIGJlIGFkZGVkIGxhdGVyKVxuICAgIH1cbn1cbiIsImNsYXNzIENvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBCdWlsZCBjb2x1bW4gY2hlY2tib3hlc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRfbWVudSh0aGlzLmFyZ3MuY29sdW1ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBidWlsZF9tZW51KGNvbHVtbnMpIHtcbiAgICAgICAgY29uc3QgJG1lbnUgPSB0aGlzLiRpZCgnbWVudScpO1xuICAgICAgICAkbWVudS5lbXB0eSgpO1xuXG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sdW1uLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpO1xuICAgICAgICAgICAgY29uc3QgJGxhYmVsID0gJCgnPGxhYmVsPicpLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJyk7XG4gICAgICAgICAgICBjb25zdCAkY2hlY2tib3ggPSAkKCc8aW5wdXQ+JylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2Zvcm0tY2hlY2staW5wdXQgbWUtMicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3R5cGUnLCAnY2hlY2tib3gnKVxuICAgICAgICAgICAgICAgIC5wcm9wKCdjaGVja2VkJywgY29sdW1uLnZpc2libGUgIT09IGZhbHNlKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLWNvbHVtbi1pbmRleCcsIGluZGV4KTtcblxuICAgICAgICAgICAgJGxhYmVsLmFwcGVuZCgkY2hlY2tib3gpLmFwcGVuZChjb2x1bW4ubGFiZWwgfHwgY29sdW1uLm5hbWUpO1xuICAgICAgICAgICAgJGxpLmFwcGVuZCgkbGFiZWwpO1xuICAgICAgICAgICAgJG1lbnUuYXBwZW5kKCRsaSk7XG5cbiAgICAgICAgICAgICRjaGVja2JveC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZV9jb2x1bW4oaW5kZXgsIGUudGFyZ2V0LmNoZWNrZWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHRvZ2dsZV9jb2x1bW4oaW5kZXgsIHZpc2libGUpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl90b2dnbGUpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl90b2dnbGUoaW5kZXgsIHZpc2libGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluZCB0YWJsZSBhbmQgdG9nZ2xlIGNvbHVtbiB2aXNpYmlsaXR5XG4gICAgICAgIGNvbnN0ICR0YWJsZSA9IHRoaXMuYXJncy50YWJsZSA/ICQodGhpcy5hcmdzLnRhYmxlKSA6IHRoaXMuJC5jbG9zZXN0KCcuY2FyZCcpLmZpbmQoJ3RhYmxlJyk7XG4gICAgICAgIGNvbnN0IHNlbGVjdG9yID0gYHRoOm50aC1jaGlsZCgke2luZGV4ICsgMX0pLCB0ZDpudGgtY2hpbGQoJHtpbmRleCArIDF9KWA7XG5cbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgICR0YWJsZS5maW5kKHNlbGVjdG9yKS5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkdGFibGUuZmluZChzZWxlY3RvcikuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X2NvbHVtbnMoY29sdW1ucykge1xuICAgICAgICB0aGlzLmJ1aWxkX21lbnUoY29sdW1ucyk7XG4gICAgfVxufVxuIiwiY2xhc3MgQ29tbWVudF9UaHJlYWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29tbWVudHMgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcmdzLmNvbW1lbnRzKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29tbWVudHMgPSB0aGlzLmFyZ3MuY29tbWVudHM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU3VibWl0IG5ldyBjb21tZW50XG4gICAgICAgIHRoaXMuJGlkKCdzdWJtaXRfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdWJtaXRfY29tbWVudCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZXBseSBidXR0b25zXG4gICAgICAgIHRoaXMuJC5maW5kKCcucmVwbHktYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRjb21tZW50ID0gJChlLnRhcmdldCkuY2xvc2VzdCgnW2RhdGEtY29tbWVudC1pZF0nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRfaWQgPSAkY29tbWVudC5hdHRyKCdkYXRhLWNvbW1lbnQtaWQnKTtcbiAgICAgICAgICAgIHRoaXMuc2hvd19yZXBseV9mb3JtKGNvbW1lbnRfaWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFZGl0IGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5lZGl0LWJ0bicpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCAkY29tbWVudCA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoJ1tkYXRhLWNvbW1lbnQtaWRdJyk7XG4gICAgICAgICAgICBjb25zdCBjb21tZW50X2lkID0gJGNvbW1lbnQuYXR0cignZGF0YS1jb21tZW50LWlkJyk7XG4gICAgICAgICAgICB0aGlzLmVkaXRfY29tbWVudChjb21tZW50X2lkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRGVsZXRlIGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5kZWxldGUtYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRjb21tZW50ID0gJChlLnRhcmdldCkuY2xvc2VzdCgnW2RhdGEtY29tbWVudC1pZF0nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRfaWQgPSAkY29tbWVudC5hdHRyKCdkYXRhLWNvbW1lbnQtaWQnKTtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlX2NvbW1lbnQoY29tbWVudF9pZCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHN1Ym1pdF9jb21tZW50KCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gdGhpcy4kaWQoJ2NvbW1lbnRfaW5wdXQnKS52YWwoKS50cmltKCk7XG4gICAgICAgIGlmICghdGV4dCkgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc3VibWl0KSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmFyZ3Mub25fc3VibWl0KHRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjb21tZW50X2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG93X3JlcGx5X2Zvcm0oY29tbWVudF9pZCkge1xuICAgICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgcmVwbHkgZm9ybSBVSVxuICAgICAgICBjb25zb2xlLmxvZygnUmVwbHkgdG8gY29tbWVudDonLCBjb21tZW50X2lkKTtcbiAgICB9XG5cbiAgICBlZGl0X2NvbW1lbnQoY29tbWVudF9pZCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2VkaXQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9lZGl0KGNvbW1lbnRfaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZGVsZXRlX2NvbW1lbnQoY29tbWVudF9pZCkge1xuICAgICAgICBpZiAoIWNvbmZpcm0oJ0RlbGV0ZSB0aGlzIGNvbW1lbnQ/JykpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2RlbGV0ZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hcmdzLm9uX2RlbGV0ZShjb21tZW50X2lkKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyByZWxvYWRfZGF0YSgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kYXRhX3NvdXJjZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNvbW1lbnRzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIERhdGVfUGlja2VyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgICRpbnB1dC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm1pbikge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ21pbicsIHRoaXMuYXJncy5taW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5tYXgpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdtYXgnLCB0aGlzLmFyZ3MubWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZWFkb25seSkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlYWRvbmx5JywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsImNsYXNzIERyb3Bkb3duX01lbnUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBiYXJlIHRleHQgY2hpbGRyZW4gaW4gPGxpPjxhPiBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgJG1lbnUgPSB0aGlzLiRpZCgnbWVudScpO1xuICAgICAgICAkbWVudS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gJGNoaWxkLnRleHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBocmVmID0gJGNoaWxkLmF0dHIoJ2hyZWYnKSB8fCAnIyc7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgJCgnPGE+JykuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWl0ZW0nKS5hdHRyKCdocmVmJywgaHJlZikudGV4dCh0ZXh0KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLnJlcGxhY2VXaXRoKCRsaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIEVtcHR5X1N0YXRlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBFeHBvcnRfQnV0dG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICB0aGlzLiQuZmluZCgnW2RhdGEtZm9ybWF0XScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXQgPSAkKGUuY3VycmVudFRhcmdldCkuYXR0cignZGF0YS1mb3JtYXQnKTtcbiAgICAgICAgICAgIHRoYXQuZXhwb3J0X2RhdGEoZm9ybWF0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZXhwb3J0X2RhdGEoZm9ybWF0KSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZXhwb3J0KSB7XG4gICAgICAgICAgICAvLyBDdXN0b20gZXhwb3J0IGhhbmRsZXJcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9leHBvcnQoZm9ybWF0KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuZGF0YSkge1xuICAgICAgICAgICAgLy8gQXV0by1leHBvcnQgcHJvdmlkZWQgZGF0YVxuICAgICAgICAgICAgdGhpcy5hdXRvX2V4cG9ydChmb3JtYXQsIHRoaXMuYXJncy5kYXRhKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuZXhwb3J0X3VybCkge1xuICAgICAgICAgICAgLy8gRmV0Y2ggZXhwb3J0IGZyb20gVVJMXG4gICAgICAgICAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmFyZ3MuZXhwb3J0X3VybH0/Zm9ybWF0PSR7Zm9ybWF0fWA7XG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGF1dG9fZXhwb3J0KGZvcm1hdCwgZGF0YSkge1xuICAgICAgICBpZiAoZm9ybWF0ID09PSAnY3N2Jykge1xuICAgICAgICAgICAgdGhpcy5leHBvcnRfY3N2KGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2pzb24nKSB7XG4gICAgICAgICAgICB0aGlzLmV4cG9ydF9qc29uKGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdBdXRvLWV4cG9ydCBvbmx5IHN1cHBvcnRzIENTViBhbmQgSlNPTi4gSW1wbGVtZW50IGN1c3RvbSBoYW5kbGVyIGZvciBvdGhlciBmb3JtYXRzLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwb3J0X2NzdihkYXRhKSB7XG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEdlbmVyYXRlIENTVlxuICAgICAgICBjb25zdCBoZWFkZXJzID0gT2JqZWN0LmtleXMoZGF0YVswXSk7XG4gICAgICAgIGxldCBjc3YgPSBoZWFkZXJzLmpvaW4oJywnKSArICdcXG4nO1xuXG4gICAgICAgIGRhdGEuZm9yRWFjaChyb3cgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gaGVhZGVycy5tYXAoaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHJvd1toZWFkZXJdIHx8ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXCIke3N0cih2YWx1ZSkucmVwbGFjZSgvXCIvZywgJ1wiXCInKX1cImA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNzdiArPSB2YWx1ZXMuam9pbignLCcpICsgJ1xcbic7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERvd25sb2FkXG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbY3N2XSwgeyB0eXBlOiAndGV4dC9jc3YnIH0pO1xuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3QgJGEgPSAkKCc8YT4nKTtcbiAgICAgICAgJGEuYXR0cignaHJlZicsIHVybCk7XG4gICAgICAgICRhLmF0dHIoJ2Rvd25sb2FkJywgYGV4cG9ydF8ke0RhdGUubm93KCl9LmNzdmApO1xuICAgICAgICAkYVswXS5jbGljaygpO1xuICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgIH1cblxuICAgIGV4cG9ydF9qc29uKGRhdGEpIHtcbiAgICAgICAgY29uc3QganNvbiA9IGpzb25fZW5jb2RlKGRhdGEpO1xuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2pzb25dLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgY29uc3QgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0ICRhID0gJCgnPGE+Jyk7XG4gICAgICAgICRhLmF0dHIoJ2hyZWYnLCB1cmwpO1xuICAgICAgICAkYS5hdHRyKCdkb3dubG9hZCcsIGBleHBvcnRfJHtEYXRlLm5vdygpfS5qc29uYCk7XG4gICAgICAgICRhWzBdLmNsaWNrKCk7XG4gICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRmlsZV9VcGxvYWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKTtcbiAgICAgICAgY29uc3QgJGRyb3Bfem9uZSA9IHRoaXMuJGlkKCdkcm9wX3pvbmUnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLmFjY2VwdCkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ2FjY2VwdCcsIHRoaXMuYXJncy5hY2NlcHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5tdWx0aXBsZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ211bHRpcGxlJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGljayB0byB1cGxvYWRcbiAgICAgICAgJGRyb3Bfem9uZS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAkaW5wdXQuY2xpY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRmlsZSBzZWxlY3RlZFxuICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWxlcyA9IGUudGFyZ2V0LmZpbGVzO1xuICAgICAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZV9maWxlcyhmaWxlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERyYWcgYW5kIGRyb3BcbiAgICAgICAgJGRyb3Bfem9uZS5vbignZHJhZ292ZXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICRkcm9wX3pvbmUuYWRkQ2xhc3MoJ2JvcmRlci1wcmltYXJ5IGJnLWxpZ2h0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICRkcm9wX3pvbmUub24oJ2RyYWdsZWF2ZScsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGRyb3Bfem9uZS5yZW1vdmVDbGFzcygnYm9yZGVyLXByaW1hcnkgYmctbGlnaHQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJGRyb3Bfem9uZS5vbignZHJvcCcsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGRyb3Bfem9uZS5yZW1vdmVDbGFzcygnYm9yZGVyLXByaW1hcnkgYmctbGlnaHQnKTtcblxuICAgICAgICAgICAgY29uc3QgZmlsZXMgPSBlLm9yaWdpbmFsRXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzO1xuICAgICAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZV9maWxlcyhmaWxlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlbW92ZSBidXR0b25cbiAgICAgICAgdGhpcy4kaWQoJ3JlbW92ZV9idG4nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaGFuZGxlX2ZpbGVzKGZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBmaWxlc1swXTsgLy8gU2luZ2xlIGZpbGUgZm9yIG5vd1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgc2l6ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLm1heF9zaXplX2J5dGVzICYmIGZpbGUuc2l6ZSA+IHRoaXMuYXJncy5tYXhfc2l6ZV9ieXRlcykge1xuICAgICAgICAgICAgYWxlcnQoYEZpbGUgaXMgdG9vIGxhcmdlLiBNYXggc2l6ZSBpcyAke3RoaXMuZm9ybWF0X3NpemUodGhpcy5hcmdzLm1heF9zaXplX2J5dGVzKX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfZmlsZSA9IGZpbGU7XG5cbiAgICAgICAgLy8gU2hvdyBmaWxlIGluZm9cbiAgICAgICAgdGhpcy4kaWQoJ3BsYWNlaG9sZGVyJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbmZvJykuc2hvdygpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9uYW1lJykudGV4dChmaWxlLm5hbWUpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9zaXplJykudGV4dCh0aGlzLmZvcm1hdF9zaXplKGZpbGUuc2l6ZSkpO1xuXG4gICAgICAgIC8vIEF1dG8tdXBsb2FkIGlmIGVuZHBvaW50IHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudXBsb2FkX3VybCkge1xuICAgICAgICAgICAgdGhpcy51cGxvYWQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaWdnZXIgY2FsbGJhY2tcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9zZWxlY3QoZmlsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyB1cGxvYWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RlZF9maWxlIHx8ICF0aGlzLmFyZ3MudXBsb2FkX3VybCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFNob3cgcHJvZ3Jlc3NcbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuc2hvdygpO1xuXG4gICAgICAgIGNvbnN0IGZvcm1fZGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtX2RhdGEuYXBwZW5kKCdmaWxlJywgdGhpcy5zZWxlY3RlZF9maWxlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MudXBsb2FkX3VybCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IGZvcm1fZGF0YVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICAgICAgLy8gSGlkZSBwcm9ncmVzc1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLnNob3coKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl91cGxvYWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fdXBsb2FkKHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBhbGVydCgnVXBsb2FkIGZhaWxlZDogJyArIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3BsYWNlaG9sZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfZmlsZSA9IG51bGw7XG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgncGxhY2Vob2xkZXInKS5zaG93KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGVhcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZmlsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRfZmlsZTtcbiAgICB9XG5cbiAgICBmb3JtYXRfc2l6ZShieXRlcykge1xuICAgICAgICBpZiAoYnl0ZXMgPCAxMDI0KSByZXR1cm4gYnl0ZXMgKyAnIEInO1xuICAgICAgICBpZiAoYnl0ZXMgPCAxMDI0ICogMTAyNCkgcmV0dXJuIChieXRlcyAvIDEwMjQpLnRvRml4ZWQoMSkgKyAnIEtCJztcbiAgICAgICAgcmV0dXJuIChieXRlcyAvICgxMDI0ICogMTAyNCkpLnRvRml4ZWQoMSkgKyAnIE1CJztcbiAgICB9XG59XG4iLCJjbGFzcyBGaWx0ZXJfQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlX2ZpbHRlcnMgPSB7fTtcblxuICAgICAgICAvLyBQb3B1bGF0ZSBzdGF0dXMgb3B0aW9ucyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnN0YXR1c19vcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCAkc3RhdHVzID0gdGhpcy4kaWQoJ3N0YXR1cycpO1xuICAgICAgICAgICAgdGhpcy5hcmdzLnN0YXR1c19vcHRpb25zLmZvckVhY2gob3B0ID0+IHtcbiAgICAgICAgICAgICAgICAkc3RhdHVzLmFwcGVuZCgkKCc8b3B0aW9uPicpLnZhbChvcHQudmFsdWUpLnRleHQob3B0LmxhYmVsKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERhdGUgcmFuZ2UgY2hhbmdlIGhhbmRsZXJcbiAgICAgICAgdGhpcy4kaWQoJ2RhdGVfcmFuZ2UnKS5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLnRhcmdldC52YWx1ZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnY3VzdG9tX2RhdGVzJykuc2hvdygpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuc2hvdygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnY3VzdG9tX2RhdGVzJykuaGlkZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZWFyY2ggd2l0aCBkZWJvdW5jZVxuICAgICAgICBsZXQgc2VhcmNoX3RpbWVvdXQ7XG4gICAgICAgIHRoaXMuJGlkKCdzZWFyY2gnKS4kLmZpbmQoJ2lucHV0Jykub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChzZWFyY2hfdGltZW91dCk7XG4gICAgICAgICAgICBzZWFyY2hfdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkX2ZpbHRlcignc2VhcmNoJywgZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXBwbHkgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdhcHBseV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5X2ZpbHRlcnMoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2xlYXIgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdjbGVhcl9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyX2ZpbHRlcnMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX2ZpbHRlcihrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG4gICAgfVxuXG4gICAgYXBwbHlfZmlsdGVycygpIHtcbiAgICAgICAgLy8gQ29sbGVjdCBhbGwgZmlsdGVyIHZhbHVlc1xuICAgICAgICBjb25zdCBzZWFyY2ggPSB0aGlzLiRpZCgnc2VhcmNoJykuZ2V0X3ZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuJGlkKCdzdGF0dXMnKS52YWwoKTtcbiAgICAgICAgY29uc3QgZGF0ZV9yYW5nZSA9IHRoaXMuJGlkKCdkYXRlX3JhbmdlJykudmFsKCk7XG5cbiAgICAgICAgdGhpcy5hY3RpdmVfZmlsdGVycyA9IHt9O1xuXG4gICAgICAgIGlmIChzZWFyY2gpIHRoaXMuYWN0aXZlX2ZpbHRlcnMuc2VhcmNoID0gc2VhcmNoO1xuICAgICAgICBpZiAoc3RhdHVzKSB0aGlzLmFjdGl2ZV9maWx0ZXJzLnN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgaWYgKGRhdGVfcmFuZ2UpIHRoaXMuYWN0aXZlX2ZpbHRlcnMuZGF0ZV9yYW5nZSA9IGRhdGVfcmFuZ2U7XG5cbiAgICAgICAgaWYgKGRhdGVfcmFuZ2UgPT09ICdjdXN0b20nKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydF9kYXRlID0gdGhpcy4kaWQoJ3N0YXJ0X2RhdGUnKS5nZXRfdmFsdWUoKTtcbiAgICAgICAgICAgIGNvbnN0IGVuZF9kYXRlID0gdGhpcy4kaWQoJ2VuZF9kYXRlJykuZ2V0X3ZhbHVlKCk7XG4gICAgICAgICAgICBpZiAoc3RhcnRfZGF0ZSkgdGhpcy5hY3RpdmVfZmlsdGVycy5zdGFydF9kYXRlID0gc3RhcnRfZGF0ZTtcbiAgICAgICAgICAgIGlmIChlbmRfZGF0ZSkgdGhpcy5hY3RpdmVfZmlsdGVycy5lbmRfZGF0ZSA9IGVuZF9kYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy51cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2FwcGx5KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fYXBwbHkodGhpcy5hY3RpdmVfZmlsdGVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcl9maWx0ZXJzKCkge1xuICAgICAgICB0aGlzLmFjdGl2ZV9maWx0ZXJzID0ge307XG5cbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaCcpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdzdGF0dXMnKS52YWwoJycpO1xuICAgICAgICB0aGlzLiRpZCgnZGF0ZV9yYW5nZScpLnZhbCgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXMnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuaGlkZSgpO1xuXG4gICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGVhcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKSB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gT2JqZWN0LmtleXModGhpcy5hY3RpdmVfZmlsdGVycykubGVuZ3RoO1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kaWQoJ2FjdGl2ZV9maWx0ZXJzJyk7XG4gICAgICAgIGNvbnN0ICR0YWdzID0gdGhpcy4kaWQoJ2ZpbHRlcl90YWdzJyk7XG5cbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAkY29udGFpbmVyLmhpZGUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgICRjb250YWluZXIuc2hvdygpO1xuICAgICAgICAkdGFncy5lbXB0eSgpO1xuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiB0aGlzLmFjdGl2ZV9maWx0ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCAkdGFnID0gJCgnPHNwYW4+JykuYWRkQ2xhc3MoJ2JhZGdlIGJnLXByaW1hcnkgbWUtMScpO1xuICAgICAgICAgICAgJHRhZy50ZXh0KGAke2tleX06ICR7dGhpcy5hY3RpdmVfZmlsdGVyc1trZXldfWApO1xuXG4gICAgICAgICAgICBjb25zdCAkcmVtb3ZlID0gJCgnPGk+JykuYWRkQ2xhc3MoJ2JpIGJpLXgtY2lyY2xlIG1zLTEnKS5jc3MoJ2N1cnNvcicsICdwb2ludGVyJyk7XG4gICAgICAgICAgICAkcmVtb3ZlLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseV9maWx0ZXJzKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHRhZy5hcHBlbmQoJHJlbW92ZSk7XG4gICAgICAgICAgICAkdGFncy5hcHBlbmQoJHRhZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZmlsdGVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlX2ZpbHRlcnM7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBGb3JtX0FjdGlvbnNfQ29tcG9uZW50IC0gSlFIVE1MIENvbXBvbmVudFxuICpcbiAqIExpZmVjeWNsZSBtZXRob2RzIGFyZSBjYWxsZWQgaW4gdGhpcyBvcmRlcjpcbiAqIDEuIG9uX2NyZWF0ZSgpIC0gUXVpY2sgVUkgc2V0dXAsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqIDIuIG9uX2xvYWQoKSAtIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCBleGVjdXRpb24sIG5vIERPTSBtb2RpZmljYXRpb25zKVxuICogMy4gb25fcmVhZHkoKSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICovXG5jbGFzcyBGb3JtX0FjdGlvbnNfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlciwgcXVpY2sgVUkgc2V0dXAgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBJbml0aWFsIHN0YXRlLCBldmVudCBiaW5kaW5ncywgc2hvd2luZyBsb2FkaW5nIGluZGljYXRvcnNcbiAgICAgKi9cbiAgICBhc3luYyBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuc2hvdygpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiQuYWRkQ2xhc3MoJ2luaXRpYWxpemluZycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCwgTk8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gICAgICogVXNlIGZvcjogTG9hZGluZyBkYXRhIGZyb20gc2VydmVyLCBmZXRjaGluZyBjb25maWd1cmF0aW9uc1xuICAgICAqIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgICAqL1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS51c2VycyA9IGF3YWl0IFVzZXJzX0NvbnRyb2xsZXIuZ2V0X3VzZXJzX2FwaSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLmRhdGEuY29uZmlnID0gYXdhaXQgdGhpcy5sb2FkX2NvbmZpZygpO1xuICAgICAgICAvLyBXQVJOSU5HOiBEbyBOT1QgbW9kaWZ5IERPTSBoZXJlIC0gb25seSBsb2FkIGRhdGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBGaW5hbCBVSSBzZXR1cCwgaGlkaW5nIGxvYWRpbmcgaW5kaWNhdG9ycywgc3RhcnRpbmcgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiRpZCgnbG9hZGluZycpLmhpZGUoKTtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5zZXR1cF9ldmVudF9saXN0ZW5lcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBoYW5kbGVyIGZvciB0aGUgaGVsbG8gYnV0dG9uXG4gICAgICogUmVmZXJlbmNlZCBpbiB0ZW1wbGF0ZSB2aWEgQGNsaWNrPXRoaXMub25fY2xpY2tfaGVsbG9cbiAgICAgKi9cbiAgICBvbl9jbGlja19oZWxsbygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lubmVyX2h0bWwnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdoZWxsb193b3JsZCcpLnNob3coKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbjogcGhwIGFydGlzYW4gcnN4Om1hbiBqcWh0bWxcbn0iLCJjbGFzcyBGb3JtX0ZpZWxkX0dyb3VwIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE9wdGlvbmFsOiBBZGQgY29sbGFwc2libGUgZnVuY3Rpb25hbGl0eVxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbGxhcHNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLm1ha2VfY29sbGFwc2libGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG1ha2VfY29sbGFwc2libGUoKSB7XG4gICAgICAgIGNvbnN0ICRoZWFkZXIgPSB0aGlzLiQuZmluZCgnLmNhcmQtaGVhZGVyJyk7XG4gICAgICAgIGNvbnN0ICRib2R5ID0gdGhpcy4kLmZpbmQoJy5jYXJkLWJvZHknKTtcbiAgICAgICAgY29uc3QgY29sbGFwc2VfaWQgPSAnY29sbGFwc2VfJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KTtcblxuICAgICAgICAkYm9keS5hdHRyKCdpZCcsIGNvbGxhcHNlX2lkKS5hZGRDbGFzcygnY29sbGFwc2Ugc2hvdycpO1xuXG4gICAgICAgIGNvbnN0ICR0b2dnbGUgPSAkKCc8YnV0dG9uPicpXG4gICAgICAgICAgICAuYXR0cigndHlwZScsICdidXR0b24nKVxuICAgICAgICAgICAgLmFkZENsYXNzKCdidG4gYnRuLWxpbmsgYnRuLXNtIGZsb2F0LWVuZCB0ZXh0LWRlY29yYXRpb24tbm9uZScpXG4gICAgICAgICAgICAuYXR0cignZGF0YS1icy10b2dnbGUnLCAnY29sbGFwc2UnKVxuICAgICAgICAgICAgLmF0dHIoJ2RhdGEtYnMtdGFyZ2V0JywgJyMnICsgY29sbGFwc2VfaWQpXG4gICAgICAgICAgICAuaHRtbCgnPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLXVwXCI+PC9pPicpO1xuXG4gICAgICAgICRoZWFkZXIuZmluZCgnaDUnKS5hcHBlbmQoJHRvZ2dsZSk7XG5cbiAgICAgICAgJGJvZHkub24oJ3Nob3cuYnMuY29sbGFwc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAkdG9nZ2xlLmh0bWwoJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi11cFwiPjwvaT4nKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJGJvZHkub24oJ2hpZGUuYnMuY29sbGFwc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAkdG9nZ2xlLmh0bWwoJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1kb3duXCI+PC9pPicpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fR3JvdXBfQ29tcG9uZW50IC0gSlFIVE1MIENvbXBvbmVudFxuICpcbiAqIExpZmVjeWNsZSBtZXRob2RzIGFyZSBjYWxsZWQgaW4gdGhpcyBvcmRlcjpcbiAqIDEuIG9uX2NyZWF0ZSgpIC0gUXVpY2sgVUkgc2V0dXAsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqIDIuIG9uX2xvYWQoKSAtIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCBleGVjdXRpb24sIG5vIERPTSBtb2RpZmljYXRpb25zKVxuICogMy4gb25fcmVhZHkoKSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICovXG5jbGFzcyBGb3JtX0dyb3VwX0NvbXBvbmVudCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8qKlxuICAgICAqIENhbGxlZCBhZnRlciByZW5kZXIsIHF1aWNrIFVJIHNldHVwIChib3R0b20tdXApXG4gICAgICogVXNlIGZvcjogSW5pdGlhbCBzdGF0ZSwgZXZlbnQgYmluZGluZ3MsIHNob3dpbmcgbG9hZGluZyBpbmRpY2F0b3JzXG4gICAgICovXG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBBcHBseSByZXNwb25zaXZlIGNvbHVtbiBjbGFzc2VzXG4gICAgICAgIGNvbnN0IGNvbF9jbGFzcyA9IHRoaXMuYXJncy5jb2xfY2xhc3MgfHwgJ2NvbC0xMiBjb2wtbWQtNiBjb2wteGwtNCc7XG4gICAgICAgIHRoaXMuJC5hZGRDbGFzcyhjb2xfY2xhc3MgKyAnIG1iLTMnKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fUm93X0NvbXBvbmVudCAtIEpRSFRNTCBDb21wb25lbnRcbiAqXG4gKiBMaWZlY3ljbGUgbWV0aG9kcyBhcmUgY2FsbGVkIGluIHRoaXMgb3JkZXI6XG4gKiAxLiBvbl9jcmVhdGUoKSAtIFF1aWNrIFVJIHNldHVwLCBydW5zIGJvdHRvbS11cCB0aHJvdWdoIGNvbXBvbmVudCB0cmVlXG4gKiAyLiBvbl9sb2FkKCkgLSBGZXRjaCBkYXRhIGZyb20gQVBJcyAocGFyYWxsZWwgZXhlY3V0aW9uLCBubyBET00gbW9kaWZpY2F0aW9ucylcbiAqIDMuIG9uX3JlYWR5KCkgLSBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqL1xuY2xhc3MgRm9ybV9Sb3dfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlciwgcXVpY2sgVUkgc2V0dXAgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBJbml0aWFsIHN0YXRlLCBldmVudCBiaW5kaW5ncywgc2hvd2luZyBsb2FkaW5nIGluZGljYXRvcnNcbiAgICAgKi9cbiAgICBhc3luYyBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuc2hvdygpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiQuYWRkQ2xhc3MoJ2luaXRpYWxpemluZycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCwgTk8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gICAgICogVXNlIGZvcjogTG9hZGluZyBkYXRhIGZyb20gc2VydmVyLCBmZXRjaGluZyBjb25maWd1cmF0aW9uc1xuICAgICAqIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgICAqL1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS51c2VycyA9IGF3YWl0IFVzZXJzX0NvbnRyb2xsZXIuZ2V0X3VzZXJzX2FwaSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLmRhdGEuY29uZmlnID0gYXdhaXQgdGhpcy5sb2FkX2NvbmZpZygpO1xuICAgICAgICAvLyBXQVJOSU5HOiBEbyBOT1QgbW9kaWZ5IERPTSBoZXJlIC0gb25seSBsb2FkIGRhdGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBGaW5hbCBVSSBzZXR1cCwgaGlkaW5nIGxvYWRpbmcgaW5kaWNhdG9ycywgc3RhcnRpbmcgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiRpZCgnbG9hZGluZycpLmhpZGUoKTtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5zZXR1cF9ldmVudF9saXN0ZW5lcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBoYW5kbGVyIGZvciB0aGUgaGVsbG8gYnV0dG9uXG4gICAgICogUmVmZXJlbmNlZCBpbiB0ZW1wbGF0ZSB2aWEgQGNsaWNrPXRoaXMub25fY2xpY2tfaGVsbG9cbiAgICAgKi9cbiAgICBvbl9jbGlja19oZWxsbygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lubmVyX2h0bWwnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdoZWxsb193b3JsZCcpLnNob3coKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbjogcGhwIGFydGlzYW4gcnN4Om1hbiBqcWh0bWxcbn0iLCIvKipcbiAqIEZvcm1fVmFsaWRhdGlvbl9NZXNzYWdlIC0gQm9vdHN0cmFwIDUgVmFsaWRhdGlvbiBGZWVkYmFjayBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBEaXNwbGF5IHZhbGlkYXRpb24gZmVlZGJhY2sgbWVzc2FnZXMgKHN1Y2Nlc3MvZXJyb3IpIGJlbG93IGZvcm0gaW5wdXRzXG4gKiBEZXNpZ246IEJvb3RzdHJhcCAuaW52YWxpZC1mZWVkYmFjayAoZGVmYXVsdCkgb3IgLnZhbGlkLWZlZWRiYWNrIHN0eWxpbmdcbiAqIFZpc2liaWxpdHk6IE9ubHkgc2hvd3Mgd2hlbiBzaWJsaW5nIGlucHV0IGhhcyAuaXMtdmFsaWQgb3IgLmlzLWludmFsaWQgY2xhc3NcbiAqL1xuY2xhc3MgRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkIChlLmcuLCBzd2l0Y2hpbmcgdG8gdmFsaWQtZmVlZGJhY2spXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIC8vIFJlcGxhY2UgZGVmYXVsdCBpbnZhbGlkLWZlZWRiYWNrIHdpdGggcHJvdmlkZWQgY2xhc3NcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnaW52YWxpZC1mZWVkYmFjaycpO1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBHYW50dF9DaGFydCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICB0aGlzLmRhdGEudGFza3MgPSBkYXRhLnRhc2tzO1xuICAgICAgICAgICAgdGhpcy5kYXRhLm1vbnRocyA9IGRhdGEubW9udGhzO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy50YXNrcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnRhc2tzID0gdGhpcy5hcmdzLnRhc2tzO1xuICAgICAgICAgICAgdGhpcy5kYXRhLm1vbnRocyA9IHRoaXMuYXJncy5tb250aHMgfHwgdGhpcy5nZW5lcmF0ZV9tb250aHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdlbmVyYXRlX21vbnRocygpIHtcbiAgICAgICAgY29uc3QgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgICAgICByZXR1cm4gbW9udGhzO1xuICAgIH1cbn1cbiIsImNsYXNzIEljb25fQnV0dG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFkZCBhcmlhLWxhYmVsIGZvciBhY2Nlc3NpYmlsaXR5IChpY29uLW9ubHkgYnV0dG9ucyBuZWVkIGxhYmVscylcbiAgICAgICAgaWYgKHRoaXMuYXJncy5sYWJlbCkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2FyaWEtbGFiZWwnLCB0aGlzLmFyZ3MubGFiZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHRpdGxlIGZvciB0b29sdGlwIG9uIGhvdmVyXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCd0aXRsZScsIHRoaXMuYXJncy50aXRsZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdXBwb3J0IGN1c3RvbSBidXR0b24gY2xhc3NlcyAoYnRuLXByaW1hcnksIGJ0bi1kYW5nZXIsIGV0Yy4pXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgSWNvbl9XaXRoX0xhYmVsIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBJY29uX1dpdGhfVGV4dCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgQm9vdHN0cmFwIHN0eWxpbmcgLSBubyBKYXZhU2NyaXB0IG5lZWRlZFxufVxuIiwiY2xhc3MgSWNvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFNWRyBpY29uIGNvbnRhaW5lciB3aXRoIHNpemUgdmFyaWFudHNcbn1cbiIsImNsYXNzIEluZm9fQm94IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IGNvbG9yIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbG9yKSB7XG4gICAgICAgICAgICB0aGlzLiQucmVtb3ZlQ2xhc3MoJ2JvcmRlci1wcmltYXJ5JykuYWRkQ2xhc3MoYGJvcmRlci0ke3RoaXMuYXJncy5jb2xvcn1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIElubGluZV9FZGl0X0ZpZWxkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuY3VycmVudF92YWx1ZSA9IHRoaXMuYXJncy52YWx1ZSB8fCAnJztcblxuICAgICAgICAvLyBFbnRlciBlZGl0IG1vZGVcbiAgICAgICAgdGhpcy4kaWQoJ2Rpc3BsYXlfbW9kZScpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW50ZXJfZWRpdF9tb2RlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNhdmVcbiAgICAgICAgdGhpcy4kaWQoJ3NhdmVfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENhbmNlbFxuICAgICAgICB0aGlzLiRpZCgnY2FuY2VsX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNhdmUgb24gRW50ZXIsIGNhbmNlbCBvbiBFc2NhcGVcbiAgICAgICAgdGhpcy4kaWQoJ2lucHV0Jykub24oJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZW50ZXJfZWRpdF9tb2RlKCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgJGlucHV0LnZhbCh0aGlzLmN1cnJlbnRfdmFsdWUpO1xuXG4gICAgICAgIHRoaXMuJGlkKCdkaXNwbGF5X21vZGUnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdlZGl0X21vZGUnKS5zaG93KCk7XG5cbiAgICAgICAgJGlucHV0LmZvY3VzKCk7XG4gICAgICAgICRpbnB1dC5zZWxlY3QoKTtcbiAgICB9XG5cbiAgICBleGl0X2VkaXRfbW9kZSgpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRfbW9kZScpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Rpc3BsYXlfbW9kZScpLnNob3coKTtcbiAgICB9XG5cbiAgICBzYXZlKCkge1xuICAgICAgICBjb25zdCBuZXdfdmFsdWUgPSB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcblxuICAgICAgICBpZiAobmV3X3ZhbHVlID09PSB0aGlzLmN1cnJlbnRfdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaWdnZXIgY2FsbGJhY2tcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zYXZlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmFyZ3Mub25fc2F2ZShuZXdfdmFsdWUsIHRoaXMuY3VycmVudF92YWx1ZSk7XG5cbiAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybnMgZmFsc2UsIGRvbid0IHNhdmVcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5zIGEgcHJvbWlzZSwgd2FpdCBmb3IgaXRcbiAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93X3NhdmluZygpO1xuICAgICAgICAgICAgICAgIHJlc3VsdC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50X3ZhbHVlID0gbmV3X3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN1cnJlbnRfdmFsdWUgPSBuZXdfdmFsdWU7XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcbiAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgIH1cblxuICAgIGNhbmNlbCgpIHtcbiAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgIH1cblxuICAgIHVwZGF0ZV9kaXNwbGF5KCkge1xuICAgICAgICBjb25zdCBkaXNwbGF5ID0gdGhpcy5jdXJyZW50X3ZhbHVlIHx8IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnQ2xpY2sgdG8gZWRpdCc7XG4gICAgICAgIHRoaXMuJGlkKCd2YWx1ZV9kaXNwbGF5JykudGV4dChkaXNwbGF5KTtcbiAgICB9XG5cbiAgICBzaG93X3NhdmluZygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ3NhdmVfYnRuJykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKS5odG1sKCc8c3BhbiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHNwaW5uZXItYm9yZGVyLXNtXCI+PC9zcGFuPicpO1xuICAgICAgICB0aGlzLiRpZCgnY2FuY2VsX2J0bicpLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50X3ZhbHVlO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRfdmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgIH1cbn1cbiIsImNsYXNzIElucHV0X1dpdGhfSWNvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVhZG9ubHknLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25faW5wdXQpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9pbnB1dChlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsImNsYXNzIElucHV0X1dpdGhfVmFsaWRhdGlvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVhZG9ubHkpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZWFkb25seScsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVhbC10aW1lIHZhbGlkYXRpb25cbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWxpZGF0ZSkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdibHVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiQuaGFzQ2xhc3MoJ3dhcy12YWxpZGF0ZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YWxpZGF0ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG5cbiAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd3YXMtdmFsaWRhdGVkJyk7XG5cbiAgICAgICAgLy8gUnVuIHZhbGlkYXRpb24gZnVuY3Rpb25cbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWxpZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5hcmdzLnZhbGlkYXRlKHZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdHJ1ZSB8fCByZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldF92YWxpZCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldF9lcnJvcihyZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJhc2ljIHJlcXVpcmVkIGNoZWNrXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQgJiYgIXZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnNldF9lcnJvcignVGhpcyBmaWVsZCBpcyByZXF1aXJlZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRfdmFsaWQoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2V0X2Vycm9yKG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgIGNvbnN0ICRlcnJvciA9IHRoaXMuJGlkKCdlcnJvcicpO1xuXG4gICAgICAgICRpbnB1dC5yZW1vdmVDbGFzcygnaXMtdmFsaWQnKS5hZGRDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICAkZXJyb3IudGV4dChtZXNzYWdlKS5jc3MoJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgICAgICAgdGhpcy4kaWQoJ3N1Y2Nlc3MnKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgIH1cblxuICAgIHNldF92YWxpZChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICBjb25zdCAkc3VjY2VzcyA9IHRoaXMuJGlkKCdzdWNjZXNzJyk7XG5cbiAgICAgICAgJGlucHV0LnJlbW92ZUNsYXNzKCdpcy1pbnZhbGlkJykuYWRkQ2xhc3MoJ2lzLXZhbGlkJyk7XG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcicpLmNzcygnZGlzcGxheScsICdub25lJyk7XG5cbiAgICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICRzdWNjZXNzLnRleHQobWVzc2FnZSkuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkc3VjY2Vzcy5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXJfdmFsaWRhdGlvbigpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgICRpbnB1dC5yZW1vdmVDbGFzcygnaXMtdmFsaWQgaXMtaW52YWxpZCcpO1xuICAgICAgICB0aGlzLiRpZCgnZXJyb3InKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgICAgICB0aGlzLiRpZCgnc3VjY2VzcycpLmNzcygnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnd2FzLXZhbGlkYXRlZCcpO1xuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgICAgICBpZiAodGhpcy4kLmhhc0NsYXNzKCd3YXMtdmFsaWRhdGVkJykpIHtcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogSW5wdXQgLSBCb290c3RyYXAgNSBUZXh0IElucHV0IENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFNpbmdsZS1saW5lIHRleHQgaW5wdXQgZmllbGQgZm9yIHVzZXIgZGF0YSBlbnRyeVxuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY29udHJvbCBzdHlsaW5nXG4gKiBUeXBlczogdGV4dCwgZW1haWwsIHBhc3N3b3JkLCBudW1iZXIsIHRlbCwgdXJsLCBkYXRlLCBldGMuXG4gKi9cbmNsYXNzIElucHV0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB0eXBlIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCd0eXBlJywgdGhpcy5hcmdzLnR5cGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHBsYWNlaG9sZGVyIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdwbGFjZWhvbGRlcicsIHRoaXMuYXJncy5wbGFjZWhvbGRlcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdmFsdWUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy4kLnZhbCh0aGlzLmFyZ3MudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRpc2FibGVkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHJlcXVpcmVkIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEthbmJhbl9Cb2FyZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb2x1bW5zID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5jb2x1bW5zKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29sdW1ucyA9IHRoaXMuYXJncy5jb2x1bW5zO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIERyYWcgYW5kIGRyb3AgZnVuY3Rpb25hbGl0eVxuICAgICAgICB0aGlzLnNldHVwX2RyYWdfYW5kX2Ryb3AoKTtcbiAgICB9XG5cbiAgICBzZXR1cF9kcmFnX2FuZF9kcm9wKCkge1xuICAgICAgICBsZXQgZHJhZ2dlZF9jYXJkID0gbnVsbDtcblxuICAgICAgICAvLyBNYWtlIGNhcmRzIGRyYWdnYWJsZVxuICAgICAgICB0aGlzLiQuZmluZCgnW2RhdGEtY2FyZC1pZF0nKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNhcmQgPSAkKHRoaXMpO1xuXG4gICAgICAgICAgICAkY2FyZC5vbignZHJhZ3N0YXJ0JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGRyYWdnZWRfY2FyZCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5jc3MoJ29wYWNpdHknLCAnMC41Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGNhcmQub24oJ2RyYWdlbmQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1ha2UgY29sdW1ucyBkcm9wcGFibGVcbiAgICAgICAgdGhpcy4kLmZpbmQoJ1tkYXRhLWNvbHVtbi1jYXJkc10nKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNvbHVtbiA9ICQodGhpcyk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2RyYWdvdmVyJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAkY29sdW1uLmFkZENsYXNzKCdiZy1saWdodCcpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2RyYWdsZWF2ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAkY29sdW1uLnJlbW92ZUNsYXNzKCdiZy1saWdodCcpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2Ryb3AnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICRjb2x1bW4ucmVtb3ZlQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZHJhZ2dlZF9jYXJkKSB7XG4gICAgICAgICAgICAgICAgICAgICRjb2x1bW4uYXBwZW5kKGRyYWdnZWRfY2FyZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX21vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhcmRfaWQgPSAkKGRyYWdnZWRfY2FyZCkuYXR0cignZGF0YS1jYXJkLWlkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5faWQgPSAkY29sdW1uLmF0dHIoJ2RhdGEtY29sdW1uLWNhcmRzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fbW92ZShjYXJkX2lkLCBjb2x1bW5faWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9XG59XG4iLCJjbGFzcyBMaW5rIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFN1cHBvcnQgJGhyZWYgYXR0cmlidXRlIGZvciBkeW5hbWljIFVSTHNcbiAgICAgICAgaWYgKHRoaXMuYXJncy5ocmVmKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignaHJlZicsIHRoaXMuYXJncy5ocmVmKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIExpc3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQWRkIGxpc3QtZ3JvdXAtaXRlbSBjbGFzcyB0byBlYWNoIGRpcmVjdCBjaGlsZFxuICAgICAgICB0aGlzLiQuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgJGVsZW1lbnQuYWRkQ2xhc3MoJ2xpc3QtZ3JvdXAtaXRlbScpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBMb2FkaW5nX1NrZWxldG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IGxpbmVzIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmxpbmVzKSB7XG4gICAgICAgICAgICB0aGlzLiQuZW1wdHkoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxpbmVzOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3aWR0aCA9IDEyIC0gKGkgKiAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCAkc3BhbiA9ICQoJzxzcGFuPicpLmFkZENsYXNzKGBwbGFjZWhvbGRlciBjb2wtJHtNYXRoLm1heCh3aWR0aCwgNil9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy4kLmFwcGVuZCgkc3Bhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBNZXRyaWNfQ2FyZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgY29udGFpbmVyIC0gY2hpbGRyZW4gYWxyZWFkeSBzdHlsZWRcbn1cbiIsImNsYXNzIE1vYmlsZV9IZWFkZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIE1vZGFsX0RpYWxvZyBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIEJvb3RzdHJhcCBtb2RhbFxuICAgICAgICB0aGlzLm1vZGFsID0gbmV3IGJvb3RzdHJhcC5Nb2RhbCh0aGlzLiRbMF0pO1xuICAgIH1cblxuICAgIHNob3coKSB7XG4gICAgICAgIHRoaXMubW9kYWwuc2hvdygpO1xuICAgIH1cblxuICAgIGhpZGUoKSB7XG4gICAgICAgIHRoaXMubW9kYWwuaGlkZSgpO1xuICAgIH1cbn1cbiIsImNsYXNzIE11bHRpX1NlbGVjdCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IHRoaXMuYXJncy52YWx1ZSB8fCBbXTtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IHRoaXMuYXJncy5vcHRpb25zIHx8IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmFsbF9vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWFyY2ggZnVuY3Rpb25hbGl0eVxuICAgICAgICBjb25zdCAkc2VhcmNoID0gdGhpcy4kaWQoJ3NlYXJjaCcpO1xuICAgICAgICAkc2VhcmNoLm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcl9vcHRpb25zKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUHJldmVudCBkcm9wZG93biBjbG9zZSB3aGVuIGNsaWNraW5nIGluc2lkZVxuICAgICAgICB0aGlzLiRpZCgnbWVudScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDbGVhci9TZWxlY3QgYWxsIGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kaWQoJ2NsZWFyX2FsbCcpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJfYWxsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCdzZWxlY3RfYWxsJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RfYWxsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBkaXNwbGF5XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcbiAgICB9XG5cbiAgICByZW5kZXJfb3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0ICRjb250YWluZXIgPSB0aGlzLiRpZCgnb3B0aW9ucycpO1xuICAgICAgICAkY29udGFpbmVyLmVtcHR5KCk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkKCc8ZGl2PicpLmFkZENsYXNzKCdweC0zIHB5LTIgdGV4dC1tdXRlZCcpLnRleHQoJ05vIG9wdGlvbnMgZm91bmQnKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zLmZvckVhY2gob3B0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRsYWJlbCA9ICQoJzxsYWJlbD4nKS5hZGRDbGFzcygnZHJvcGRvd24taXRlbSBtYi0wJyk7XG4gICAgICAgICAgICBjb25zdCAkY2hlY2tib3ggPSAkKCc8aW5wdXQ+JylcbiAgICAgICAgICAgICAgICAuYXR0cigndHlwZScsICdjaGVja2JveCcpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdmb3JtLWNoZWNrLWlucHV0IG1lLTInKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXZhbHVlJywgb3B0aW9uLnZhbHVlKVxuICAgICAgICAgICAgICAgIC5wcm9wKCdjaGVja2VkJywgdGhpcy5zZWxlY3RlZF92YWx1ZXMuaW5jbHVkZXMob3B0aW9uLnZhbHVlKSk7XG5cbiAgICAgICAgICAgICRjaGVja2JveC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZV9vcHRpb24ob3B0aW9uLnZhbHVlLCBlLnRhcmdldC5jaGVja2VkKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkbGFiZWwuYXBwZW5kKCRjaGVja2JveCkuYXBwZW5kKG9wdGlvbi5sYWJlbCk7XG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkbGFiZWwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmaWx0ZXJfb3B0aW9ucyhxdWVyeSkge1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuYWxsX29wdGlvbnMuZmlsdGVyKG9wdCA9PlxuICAgICAgICAgICAgb3B0LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyhmaWx0ZXJlZCk7XG4gICAgfVxuXG4gICAgdG9nZ2xlX29wdGlvbih2YWx1ZSwgY2hlY2tlZCkge1xuICAgICAgICBpZiAoY2hlY2tlZCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkX3ZhbHVlcy5pbmNsdWRlcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzID0gdGhpcy5zZWxlY3RlZF92YWx1ZXMuZmlsdGVyKHYgPT4gdiAhPT0gdmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKHRoaXMuc2VsZWN0ZWRfdmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZV9kaXNwbGF5KCkge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuc2VsZWN0ZWRfdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgJHRleHQgPSB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpO1xuXG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgJHRleHQudGV4dCh0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ1NlbGVjdCBvcHRpb25zJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuYWxsX29wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09PSB0aGlzLnNlbGVjdGVkX3ZhbHVlc1swXSk7XG4gICAgICAgICAgICAkdGV4dC50ZXh0KG9wdGlvbiA/IG9wdGlvbi5sYWJlbCA6ICcxIHNlbGVjdGVkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkdGV4dC50ZXh0KGAke2NvdW50fSBzZWxlY3RlZGApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXJfYWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IFtdO1xuICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZSh0aGlzLnNlbGVjdGVkX3ZhbHVlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RfYWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IHRoaXMuYWxsX29wdGlvbnMubWFwKG9wdCA9PiBvcHQudmFsdWUpO1xuICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKHRoaXMuc2VsZWN0ZWRfdmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRfdmFsdWVzO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZXMpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZF92YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykuZWFjaCgoaSwgZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRlbCA9ICQoZWwpO1xuICAgICAgICAgICAgJGVsLnByb3AoJ2NoZWNrZWQnLCB2YWx1ZXMuaW5jbHVkZXMoJGVsLmF0dHIoJ2RhdGEtdmFsdWUnKSkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgIH1cblxuICAgIHNldF9vcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnMob3B0aW9ucyk7XG4gICAgfVxufVxuIiwiY2xhc3MgTm90aWZpY2F0aW9uX0JhZGdlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRjb3VudCA9IHRoaXMuJGlkKCdjb3VudCcpO1xuICAgICAgICAvLyBVcGRhdGUgY291bnQgZHluYW1pY2FsbHlcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb3VudCA9PT0gMCB8fCB0aGlzLmFyZ3MuY291bnQgPT09ICcwJykge1xuICAgICAgICAgICAgJGNvdW50LmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldF9jb3VudChjb3VudCkge1xuICAgICAgICBjb25zdCAkY291bnQgPSB0aGlzLiRpZCgnY291bnQnKTtcbiAgICAgICAgJGNvdW50LnRleHQoY291bnQpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgICAkY291bnQuc2hvdygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGNvdW50LmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIE5vdGlmaWNhdGlvbl9Ecm9wZG93biBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yXG4gICAgfVxufVxuIiwiY2xhc3MgT3ZlcmR1ZV9JbmRpY2F0b3IgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBzdHlsaW5nIC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsIi8qKlxuICogUGFnZV9IZWFkZXIgLSBCb290c3RyYXAgNSBQYWdlIEFjdGlvbiBCYXIgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogVG9wIHNlY3Rpb24gb2YgcGFnZSBjb250YWluaW5nIHRpdGxlLCBicmVhZGNydW1icywgYW5kIGFjdGlvbnNcbiAqIERlc2lnbjogRmxleGJveCBsYXlvdXQgdXNpbmcgQm9vdHN0cmFwIHV0aWxpdHkgY2xhc3Nlc1xuICogTGF5b3V0OiBUaXRsZS9icmVhZGNydW1icyBvbiBsZWZ0LCBhY3Rpb25zL2J1dHRvbnMgb24gcmlnaHRcbiAqL1xuY2xhc3MgUGFnZV9IZWFkZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQYWdlX0hlYWRlciBpcyBhIHB1cmUgY29udGFpbmVyIGNvbXBvbmVudCAtIG5vIGxpZmVjeWNsZSBtZXRob2RzIG5lZWRlZFxuICAgIC8vIEFsbCBsYXlvdXQgZnJvbSBCb290c3RyYXAgdXRpbGl0aWVzOiBkLWZsZXgsIGp1c3RpZnktY29udGVudC1iZXR3ZWVuLCBhbGlnbi1pdGVtcy1jZW50ZXIsIHB5LTRcbn1cbiIsImNsYXNzIFBhZ2VfU2VjdGlvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIENvbnRlbnQgc2VjdGlvbiB3aXRoIHNwYWNpbmcgLSBubyBzcGVjaWFsIGJlaGF2aW9yIG5lZWRlZFxufVxuIiwiY2xhc3MgUGFnZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFNlbWFudGljIHBhZ2UgY29udGFpbmVyIC0gbm8gc3BlY2lhbCBiZWhhdmlvciBuZWVkZWRcbn1cbiIsImNsYXNzIFBvcG92ZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHBvcG92ZXIgY29udGVudCBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy50aXRsZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtYnMtdGl0bGUnLCB0aGlzLmFyZ3MudGl0bGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy1jb250ZW50JywgdGhpcy5hcmdzLmNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHRyaWdnZXIgKGhvdmVyLCBjbGljaywgZm9jdXMpXG4gICAgICAgIHRoaXMuJC5hdHRyKCdkYXRhLWJzLXRyaWdnZXInLCB0aGlzLmFyZ3MudHJpZ2dlciB8fCAnY2xpY2snKTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIEJvb3RzdHJhcCBwb3BvdmVyXG4gICAgICAgIG5ldyBib290c3RyYXAuUG9wb3Zlcih0aGlzLiRbMF0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFByb2dyZXNzX0JhciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkYmFyID0gdGhpcy4kaWQoJ2JhcicpO1xuXG4gICAgICAgIC8vIEFwcGx5IGNvbG9yIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbG9yKSB7XG4gICAgICAgICAgICAkYmFyLmFkZENsYXNzKGBiZy0ke3RoaXMuYXJncy5jb2xvcn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNob3cgdmFsdWUgdGV4dCBpZiByZXF1ZXN0ZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zaG93X3ZhbHVlKSB7XG4gICAgICAgICAgICAkYmFyLnRleHQoYCR7dGhpcy5hcmdzLnZhbHVlIHx8IDB9JWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0ICRiYXIgPSB0aGlzLiRpZCgnYmFyJyk7XG4gICAgICAgICRiYXIuY3NzKCd3aWR0aCcsIGAke3ZhbHVlfSVgKS5hdHRyKCdhcmlhLXZhbHVlbm93JywgdmFsdWUpO1xuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfdmFsdWUpIHtcbiAgICAgICAgICAgICRiYXIudGV4dChgJHt2YWx1ZX0lYCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFJhZGlvX0J1dHRvbiAtIEJvb3RzdHJhcCA1IFJhZGlvIElucHV0IENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFJhZGlvIGJ1dHRvbiBmb3IgbXV0dWFsbHkgZXhjbHVzaXZlIHNlbGVjdGlvbnMgd2l0aGluIGEgZ3JvdXBcbiAqIERlc2lnbjogQm9vdHN0cmFwIC5mb3JtLWNoZWNrLWlucHV0IHN0eWxpbmcgd2l0aCBjaXJjdWxhciBzaGFwZVxuICogQ1JJVElDQUw6IEFsbCByYWRpb3MgaW4gc2FtZSBncm91cCBtdXN0IGhhdmUgc2FtZSBcIm5hbWVcIiBhdHRyaWJ1dGVcbiAqIFdyYXBwZXI6IFR5cGljYWxseSB1c2VkIHdpdGhpbiA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPiBhbmQgPGZpZWxkc2V0PlxuICovXG5jbGFzcyBSYWRpb19CdXR0b24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IG5hbWUgYXR0cmlidXRlIChDUklUSUNBTCBmb3IgZ3JvdXBpbmcpXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgY2hlY2tlZCBzdGF0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNoZWNrZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdjaGVja2VkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdmFsdWUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy4kLnZhbCh0aGlzLmFyZ3MudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRpc2FibGVkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHJlcXVpcmVkIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFJpY2hfVGV4dF9FZGl0b3IgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGVkaXRvciA9IHRoaXMuJGlkKCdlZGl0b3InKTtcblxuICAgICAgICAvLyBUb29sYmFyIGJ1dHRvbiBoYW5kbGVyc1xuICAgICAgICB0aGlzLiRpZCgndG9vbGJhcicpLmZpbmQoJ1tkYXRhLWNvbW1hbmRdJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmQgPSAkKGUuY3VycmVudFRhcmdldCkuYXR0cignZGF0YS1jb21tYW5kJyk7XG5cbiAgICAgICAgICAgIGlmIChjb21tYW5kID09PSAnY3JlYXRlTGluaycpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBwcm9tcHQoJ0VudGVyIFVSTDonKTtcbiAgICAgICAgICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB1cmwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIG51bGwpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkZWRpdG9yLmZvY3VzKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFRyYWNrIGNoYW5nZXNcbiAgICAgICAgJGVkaXRvci5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UodGhpcy5nZXRfdmFsdWUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciBvbiBwYXN0ZSAob3B0aW9uYWwgLSBjYW4gYmUgY3VzdG9taXplZClcbiAgICAgICAgJGVkaXRvci5vbigncGFzdGUnLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5wbGFpbl90ZXh0X3Bhc3RlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBlLm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2luc2VydFRleHQnLCBmYWxzZSwgdGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdlZGl0b3InKS5odG1sKCk7XG4gICAgfVxuXG4gICAgZ2V0X3RleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLiRpZCgnZWRpdG9yJykudGV4dCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZShodG1sKSB7XG4gICAgICAgIHRoaXMuJGlkKCdlZGl0b3InKS5odG1sKGh0bWwpO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLiRpZCgnZWRpdG9yJykuZW1wdHkoKTtcbiAgICB9XG5cbiAgICBmb2N1cygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRvcicpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgUm93X0FjdGlvbl9NZW51IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFdyYXAgY2hpbGRyZW4gaW4gZHJvcGRvd24gc3RydWN0dXJlXG4gICAgICAgIGNvbnN0ICRtZW51ID0gdGhpcy4kaWQoJ21lbnUnKTtcbiAgICAgICAgJG1lbnUuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgPT09ICdIUicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFwcGVuZCgkKCc8aHI+JykuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWRpdmlkZXInKSk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC5yZXBsYWNlV2l0aCgkbGkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC5hZGRDbGFzcygnZHJvcGRvd24taXRlbScpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+Jyk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcbiAqXG4gKiBGdWxsLWZlYXR1cmVkIGRhdGEgdGFibGUgd2l0aDpcbiAqIC0gUm93IHNlbGVjdGlvbiAoY2hlY2tib3hlcylcbiAqIC0gUGFnaW5hdGlvblxuICogLSBSb3cgYWN0aW9ucyAodmlldywgZWRpdCwgZGVsZXRlKVxuICogLSBMb2FkaW5nIHN0YXRlcyB3aXRoIHBsYWNlaG9sZGVyc1xuICogLSBFbXB0eSBzdGF0ZXNcbiAqXG4gKiBVc2FnZTpcbiAqIDxTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50XG4gKiAgICR0aXRsZT1cIkNsaWVudCBMaXN0XCJcbiAqICAgJGVudGl0eV9uYW1lPVwiY2xpZW50c1wiXG4gKiAgICRzZWxlY3RhYmxlPXRydWVcbiAqICAgJHBhZ2luYXRpb249dHJ1ZVxuICogICAkYWxsb3dfZGVsZXRlPXRydWVcbiAqICAgJHZpZXdfdXJsPVwiL2NsaWVudHMve2lkfVwiXG4gKiAgICRlZGl0X3VybD1cIi9jbGllbnRzL3tpZH0vZWRpdFwiXG4gKiAgICRhcGlfdXJsPVwiL2FwaS9jbGllbnRzXCJcbiAqICAgJGNvbHVtbnM9Y29sdW1uc19kZWZpbml0aW9uXG4gKiAvPlxuICovXG5jbGFzcyBTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG5cbiAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyBJZiBBUEkgVVJMIHByb3ZpZGVkLCBmZXRjaCBkYXRhXG4gICAgaWYgKHRoYXQuYXJncy5hcGlfdXJsKSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoYXQuYXJncy5hcGlfdXJsKTtcbiAgICAgIHRoYXQuZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gR2VuZXJhdGUgc2FtcGxlIGRhdGEgZm9yIGRlbW9uc3RyYXRpb25cbiAgICAgIHRoYXQuZGF0YSA9IHRoYXQuZ2VuZXJhdGVfc2FtcGxlX2RhdGEoKTtcbiAgICB9XG4gIH1cblxuICBvbl9yZWFkeSgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyBTZWxlY3QgYWxsIGNoZWNrYm94XG4gICAgaWYgKHRoYXQuYXJncy5zZWxlY3RhYmxlKSB7XG4gICAgICB0aGF0LiRpZCgnc2VsZWN0X2FsbCcpLm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICBjb25zdCBjaGVja2VkID0gZS50YXJnZXQuY2hlY2tlZDtcbiAgICAgICAgdGhhdC4kLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBjaGVja2VkKTtcbiAgICAgICAgdGhhdC51cGRhdGVfc2VsZWN0aW9uX2NvdW50KCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSW5kaXZpZHVhbCByb3cgY2hlY2tib3hlc1xuICAgICAgdGhhdC4kLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgIHRoYXQudXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gRGVsZXRlIGJ1dHRvbnNcbiAgICBpZiAodGhhdC5hcmdzLmFsbG93X2RlbGV0ZSkge1xuICAgICAgdGhhdC4kLmZpbmQoJ2J1dHRvbltkYXRhLWlkXScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGNvbnN0ICRidXR0b24gPSAkKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgIGNvbnN0IGlkID0gJGJ1dHRvbi5kYXRhKCdpZCcpO1xuICAgICAgICB0aGF0LmNvbmZpcm1fZGVsZXRlKGlkKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFBhZ2luYXRpb25cbiAgICBpZiAodGhhdC5hcmdzLnBhZ2luYXRpb24gIT09IGZhbHNlKSB7XG4gICAgICB0aGF0LiRpZCgncHJldl9wYWdlJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGF0LmdvX3RvX3BhZ2UodGhhdC5kYXRhLnBhZ2luYXRpb24uY3VycmVudF9wYWdlIC0gMSk7XG4gICAgICB9KTtcblxuICAgICAgdGhhdC4kaWQoJ25leHRfcGFnZScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhhdC5nb190b19wYWdlKHRoYXQuZGF0YS5wYWdpbmF0aW9uLmN1cnJlbnRfcGFnZSArIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoYXQuJC5maW5kKCcucGFnZS1saW5rW2RhdGEtcGFnZV0nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0ICRsaW5rID0gJChlLmN1cnJlbnRUYXJnZXQpO1xuICAgICAgICBjb25zdCBwYWdlID0gaW50KCRsaW5rLmRhdGEoJ3BhZ2UnKSk7XG4gICAgICAgIHRoYXQuZ29fdG9fcGFnZShwYWdlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgVUkgdG8gc2hvdyBob3cgbWFueSByb3dzIGFyZSBzZWxlY3RlZFxuICAgKi9cbiAgdXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoYXQuJC5maW5kKCd0Ym9keSBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZCcpLmxlbmd0aDtcblxuICAgIGlmIChzZWxlY3RlZCA+IDApIHtcbiAgICAgIC8vIENvdWxkIHNob3cgYSBiYW5uZXI6IFwiMyBpdGVtcyBzZWxlY3RlZFwiXG4gICAgICBjb25zb2xlLmxvZyhgJHtzZWxlY3RlZH0gaXRlbXMgc2VsZWN0ZWRgKTtcblxuICAgICAgLy8gRmlyZSBldmVudCBmb3IgcGFyZW50IGNvbXBvbmVudHMgdG8gbGlzdGVuIHRvXG4gICAgICB0aGF0LiQudHJpZ2dlcignc2VsZWN0aW9uOmNoYW5nZWQnLCB7IGNvdW50OiBzZWxlY3RlZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFycmF5IG9mIHNlbGVjdGVkIElEc1xuICAgKi9cbiAgZ2V0X3NlbGVjdGVkX2lkcygpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCBpZHMgPSBbXTtcbiAgICB0aGF0LiQuZmluZCgndGJvZHkgaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdOmNoZWNrZWQnKS5lYWNoKChpLCBjaGVja2JveCkgPT4ge1xuICAgICAgY29uc3QgJGNoZWNrYm94ID0gJChjaGVja2JveCk7XG4gICAgICBjb25zdCBpZCA9ICRjaGVja2JveC5kYXRhKCdpZCcpO1xuICAgICAgaWYgKGlkKSBpZHMucHVzaChpZCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGlkcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgc2VsZWN0aW9uc1xuICAgKi9cbiAgY2xlYXJfc2VsZWN0aW9uKCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIHRoYXQuJC5maW5kKCdpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5wcm9wKCdjaGVja2VkJywgZmFsc2UpO1xuICAgIHRoYXQudXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpcm0gZGVsZXRpb24gb2YgYSByb3dcbiAgICovXG4gIGNvbmZpcm1fZGVsZXRlKGlkKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgLy8gSW4gYSByZWFsIGFwcCwgc2hvdyBhIEJvb3RzdHJhcCBtb2RhbFxuICAgIGlmIChjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgaXRlbT8nKSkge1xuICAgICAgdGhhdC5kZWxldGVfcm93KGlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgcm93ICh3b3VsZCB0eXBpY2FsbHkgbWFrZSBBUEkgY2FsbClcbiAgICovXG4gIGFzeW5jIGRlbGV0ZV9yb3coaWQpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICB0cnkge1xuICAgICAgLy8gTWFrZSBBUEkgY2FsbFxuICAgICAgLy8gYXdhaXQgZmV0Y2goYCR7dGhhdC5hcmdzLmFwaV91cmx9LyR7aWR9YCwgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuXG4gICAgICAvLyBSZW1vdmUgcm93IGZyb20gZGF0YVxuICAgICAgdGhhdC5kYXRhLnJvd3MgPSB0aGF0LmRhdGEucm93cy5maWx0ZXIocm93ID0+IHJvdy5pZCAhPT0gaWQpO1xuXG4gICAgICAvLyBSZS1yZW5kZXIgY29tcG9uZW50XG4gICAgICB0aGF0LnJlZnJlc2goKTtcblxuICAgICAgLy8gU2hvdyBzdWNjZXNzIG1lc3NhZ2VcbiAgICAgIGNvbnNvbGUubG9nKGBEZWxldGVkIGl0ZW0gJHtpZH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRGVsZXRlIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICBhbGVydCgnRmFpbGVkIHRvIGRlbGV0ZSBpdGVtJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlIHRvIGEgc3BlY2lmaWMgcGFnZVxuICAgKi9cbiAgYXN5bmMgZ29fdG9fcGFnZShwYWdlKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgaWYgKHBhZ2UgPCAxIHx8IHBhZ2UgPiB0aGF0LmRhdGEucGFnaW5hdGlvbi50b3RhbF9wYWdlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNob3cgbG9hZGluZyBzdGF0ZVxuICAgIHRoYXQuJC5maW5kKCd0Ym9keScpLmNzcygnb3BhY2l0eScsICcwLjUnKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBGZXRjaCBuZXcgcGFnZVxuICAgICAgY29uc3QgdXJsID0gYCR7dGhhdC5hcmdzLmFwaV91cmx9P3BhZ2U9JHtwYWdlfWA7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICB0aGF0LmRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIC8vIFJlLXJlbmRlclxuICAgICAgdGhhdC5yZWZyZXNoKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1BhZ2luYXRpb24gZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIHRoYXQuJC5maW5kKCd0Ym9keScpLmNzcygnb3BhY2l0eScsICcxJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2ggdGhlIHRhYmxlIChyZWxvYWQgZGF0YSBhbmQgcmUtcmVuZGVyKVxuICAgKi9cbiAgYXN5bmMgcmVsb2FkX2RhdGEoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgdGhhdC5kYXRhID0ge307IC8vIENsZWFyIGRhdGEgdG8gc2hvdyBsb2FkaW5nIHN0YXRlXG4gICAgdGhhdC5yZWZyZXNoKCk7XG5cbiAgICBhd2FpdCB0aGF0Lm9uX2xvYWQoKTtcbiAgICB0aGF0LnJlZnJlc2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBzYW1wbGUgZGF0YSBmb3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlc1xuICAgKi9cbiAgZ2VuZXJhdGVfc2FtcGxlX2RhdGEoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgY29uc3Qgc3RhdHVzZXMgPSBbXG4gICAgICB7IGxhYmVsOiAnQWN0aXZlJywgY29sb3I6ICdzdWNjZXNzJyB9LFxuICAgICAgeyBsYWJlbDogJ1BlbmRpbmcnLCBjb2xvcjogJ3dhcm5pbmcnIH0sXG4gICAgICB7IGxhYmVsOiAnSW5hY3RpdmUnLCBjb2xvcjogJ3NlY29uZGFyeScgfSxcbiAgICAgIHsgbGFiZWw6ICdTdXNwZW5kZWQnLCBjb2xvcjogJ2RhbmdlcicgfVxuICAgIF07XG5cbiAgICBjb25zdCBmaXJzdF9uYW1lcyA9IFsnSm9obicsICdTYXJhaCcsICdNaWNoYWVsJywgJ0VtaWx5JywgJ0RhdmlkJywgJ0xpc2EnLCAnUm9iZXJ0JywgJ0plbm5pZmVyJywgJ1dpbGxpYW0nLCAnQW1hbmRhJ107XG4gICAgY29uc3QgbGFzdF9uYW1lcyA9IFsnU21pdGgnLCAnSm9obnNvbicsICdCcm93bicsICdHYXJjaWEnLCAnTWFydGluZXonLCAnTGVlJywgJ0FuZGVyc29uJywgJ1Rob21wc29uJywgJ1doaXRlJywgJ0RhdmlzJ107XG4gICAgY29uc3QgY29tcGFuaWVzID0gWydBY21lIENvcnAnLCAnVGVjaCBTb2x1dGlvbnMnLCAnR2xvYmFsIEVudGVycHJpc2VzJywgJ0lubm92YXRpb24gTGFicycsICdEaWdpdGFsIFN5c3RlbXMnLCAnQ2xvdWQgU2VydmljZXMnLCAnU21hcnQgSW5kdXN0cmllcycsICdGdXR1cmUgTmV0d29ya3MnLCAnUHJpbWUgQ29uc3VsdGluZycsICdFbGl0ZSBQYXJ0bmVycyddO1xuXG4gICAgY29uc3Qgcm93cyA9IFtdO1xuICAgIGNvbnN0IGNvdW50ID0gdGhhdC5hcmdzLnNob3dpbmcgfHwgMTA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IGZpcnN0X25hbWUgPSBmaXJzdF9uYW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBmaXJzdF9uYW1lcy5sZW5ndGgpXTtcbiAgICAgIGNvbnN0IGxhc3RfbmFtZSA9IGxhc3RfbmFtZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogbGFzdF9uYW1lcy5sZW5ndGgpXTtcbiAgICAgIGNvbnN0IGNvbXBhbnkgPSBjb21wYW5pZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY29tcGFuaWVzLmxlbmd0aCldO1xuICAgICAgY29uc3Qgc3RhdHVzID0gc3RhdHVzZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogc3RhdHVzZXMubGVuZ3RoKV07XG5cbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGlkOiBgQyR7c3RyKGkgKyAxKS5wYWRTdGFydCgzLCAnMCcpfWAsXG4gICAgICAgIG5hbWU6IGAke2ZpcnN0X25hbWV9ICR7bGFzdF9uYW1lfWAsXG4gICAgICAgIGNvbXBhbnk6IGNvbXBhbnksXG4gICAgICAgIGVtYWlsOiBgJHtmaXJzdF9uYW1lLnRvTG93ZXJDYXNlKCl9LiR7bGFzdF9uYW1lLnRvTG93ZXJDYXNlKCl9QCR7Y29tcGFueS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1xccysvZywgJycpfS5jb21gLFxuICAgICAgICBwaG9uZTogYCg1NTUpICR7c3RyKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDkwMCkgKyAxMDApfS0ke3N0cihNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA5MDAwKSArIDEwMDApfWAsXG4gICAgICAgIHN0YXR1czogc3RhdHVzLmxhYmVsLFxuICAgICAgICBzdGF0dXNfY29sb3I6IHN0YXR1cy5jb2xvcixcbiAgICAgICAgY3JlYXRlZDogdGhhdC5yYW5kb21fZGF0ZSgpXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm93czogcm93cyxcbiAgICAgIHBhZ2luYXRpb246IHtcbiAgICAgICAgY3VycmVudF9wYWdlOiAxLFxuICAgICAgICB0b3RhbF9wYWdlczogTWF0aC5jZWlsKCh0aGF0LmFyZ3MudG90YWwgfHwgMTAwKSAvIGNvdW50KSxcbiAgICAgICAgZnJvbTogMSxcbiAgICAgICAgdG86IGNvdW50LFxuICAgICAgICB0b3RhbDogdGhhdC5hcmdzLnRvdGFsIHx8IDEwMCxcbiAgICAgICAgcGFnZXM6IFsxLCAyLCAzLCAnLi4uJywgTWF0aC5jZWlsKCh0aGF0LmFyZ3MudG90YWwgfHwgMTAwKSAvIGNvdW50KV1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJhbmRvbSBkYXRlIGZvciBzYW1wbGUgZGF0YVxuICAgKi9cbiAgcmFuZG9tX2RhdGUoKSB7XG4gICAgY29uc3QgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgIGNvbnN0IG1vbnRoID0gbW9udGhzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEyKV07XG4gICAgY29uc3QgZGF5ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjgpICsgMTtcbiAgICByZXR1cm4gYCR7bW9udGh9ICR7c3RyKGRheSkucGFkU3RhcnQoMiwgJzAnKX0sIDIwMjRgO1xuICB9XG59XG4iLCJjbGFzcyBTZWFyY2hfQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEJpbmQgc2VhcmNoIGV2ZW50XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc2VhcmNoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX3NlYXJjaChlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFNlYXJjaGFibGVfU2VsZWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWUgPSB0aGlzLmFyZ3MudmFsdWUgfHwgbnVsbDtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IHRoaXMuYXJncy5vcHRpb25zIHx8IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmFsbF9vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWFyY2ggZnVuY3Rpb25hbGl0eVxuICAgICAgICBjb25zdCAkc2VhcmNoID0gdGhpcy4kaWQoJ3NlYXJjaCcpO1xuICAgICAgICAkc2VhcmNoLm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcl9vcHRpb25zKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUHJldmVudCBkcm9wZG93biBjbG9zZSB3aGVuIGNsaWNraW5nIHNlYXJjaCBpbnB1dFxuICAgICAgICAkc2VhcmNoLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgc2VsZWN0ZWQgdGV4dCBpZiBpbml0aWFsIHZhbHVlIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkX3ZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZF9vcHRpb24gPSB0aGlzLmFsbF9vcHRpb25zLmZpbmQob3B0ID0+IG9wdC52YWx1ZSA9PSB0aGlzLnNlbGVjdGVkX3ZhbHVlKTtcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZF9vcHRpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpLnRleHQoc2VsZWN0ZWRfb3B0aW9uLmxhYmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlcl9vcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgJGNvbnRhaW5lciA9IHRoaXMuJGlkKCdvcHRpb25zJyk7XG4gICAgICAgICRjb250YWluZXIuZW1wdHkoKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICRjb250YWluZXIuYXBwZW5kKCQoJzxkaXY+JykuYWRkQ2xhc3MoJ3B4LTMgcHktMiB0ZXh0LW11dGVkJykudGV4dCgnTm8gb3B0aW9ucyBmb3VuZCcpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMuZm9yRWFjaChvcHRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3QgJGl0ZW0gPSAkKCc8YT4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnZHJvcGRvd24taXRlbScpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2hyZWYnLCAnIycpXG4gICAgICAgICAgICAgICAgLnRleHQob3B0aW9uLmxhYmVsKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXZhbHVlJywgb3B0aW9uLnZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSA9PSB0aGlzLnNlbGVjdGVkX3ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgJGl0ZW0uYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkaXRlbS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdF9vcHRpb24ob3B0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkaXRlbSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZpbHRlcl9vcHRpb25zKHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gdGhpcy5hbGxfb3B0aW9ucy5maWx0ZXIob3B0ID0+XG4gICAgICAgICAgICBvcHQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeS50b0xvd2VyQ2FzZSgpKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcl9vcHRpb25zKGZpbHRlcmVkKTtcbiAgICB9XG5cbiAgICBzZWxlY3Rfb3B0aW9uKG9wdGlvbikge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlID0gb3B0aW9uLnZhbHVlO1xuICAgICAgICB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpLnRleHQob3B0aW9uLmxhYmVsKTtcblxuICAgICAgICAvLyBVcGRhdGUgYWN0aXZlIHN0YXRlXG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnLmRyb3Bkb3duLWl0ZW0nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZChgW2RhdGEtdmFsdWU9XCIke29wdGlvbi52YWx1ZX1cIl1gKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cbiAgICAgICAgLy8gQ2xvc2UgZHJvcGRvd25cbiAgICAgICAgY29uc3QgZHJvcGRvd24gPSBib290c3RyYXAuRHJvcGRvd24uZ2V0SW5zdGFuY2UodGhpcy4kaWQoJ2J1dHRvbicpWzBdKTtcbiAgICAgICAgaWYgKGRyb3Bkb3duKSB7XG4gICAgICAgICAgICBkcm9wZG93bi5oaWRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGVhciBzZWFyY2hcbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaCcpLnZhbCgnJyk7XG4gICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShvcHRpb24udmFsdWUsIG9wdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkX3ZhbHVlO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlID0gdmFsdWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuYWxsX29wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09IHZhbHVlKTtcbiAgICAgICAgaWYgKG9wdGlvbikge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3NlbGVjdGVkX3RleHQnKS50ZXh0KG9wdGlvbi5sYWJlbCk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJy5kcm9wZG93bi1pdGVtJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ29wdGlvbnMnKS5maW5kKGBbZGF0YS12YWx1ZT1cIiR7dmFsdWV9XCJdYCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X29wdGlvbnMob3B0aW9ucykge1xuICAgICAgICB0aGlzLmFsbF9vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyhvcHRpb25zKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNlbGVjdF9Ecm9wZG93biAtIEJvb3RzdHJhcCA1IERyb3Bkb3duIFNlbGVjdGlvbiBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBEcm9wZG93biBtZW51IGZvciBzZWxlY3Rpbmcgb25lIG9wdGlvbiBmcm9tIGEgbGlzdFxuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tc2VsZWN0IHN0eWxpbmcgd2l0aCBkcm9wZG93biBhcnJvd1xuICogQ29udGVudDogQ29udGFpbnMgPG9wdGlvbj4gZWxlbWVudHNcbiAqL1xuY2xhc3MgU2VsZWN0X0Ryb3Bkb3duIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgU2lkZWJhcl9OYXYgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXV0by13cmFwIGNoaWxkcmVuIGluIG5hdiBzdHJ1Y3R1cmUgaWYgbmVlZGVkXG4gICAgICAgIGNvbnN0ICRuYXZfaXRlbXMgPSB0aGlzLiRpZCgnbmF2X2l0ZW1zJyk7XG4gICAgICAgICRuYXZfaXRlbXMuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFkZENsYXNzKCduYXYtaXRlbScpO1xuICAgICAgICAgICAgICAgICRjaGlsZC5hZGRDbGFzcygnbmF2LWxpbmsnKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQud3JhcCgkbGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgYWN0aXZlIHN0YXRlIGJhc2VkIG9uIGN1cnJlbnQgVVJMXG4gICAgICAgIGNvbnN0IGN1cnJlbnRfcGF0aCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZTtcbiAgICAgICAgJG5hdl9pdGVtcy5maW5kKCdhLm5hdi1saW5rJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaW5rID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkbGluay5hdHRyKCdocmVmJykgPT09IGN1cnJlbnRfcGF0aCkge1xuICAgICAgICAgICAgICAgICRsaW5rLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgU29ydGFibGVfQ29sdW1uX0hlYWRlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDbGljayB0byB0b2dnbGUgc29ydFxuICAgICAgICB0aGlzLiQub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy50b2dnbGVfc29ydCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgaW5pdGlhbCBzb3J0IHN0YXRlXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc29ydCkge1xuICAgICAgICAgICAgdGhpcy5zZXRfc29ydCh0aGlzLmFyZ3Muc29ydCk7IC8vICdhc2MnIG9yICdkZXNjJ1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG9nZ2xlX3NvcnQoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLiQuYXR0cignZGF0YS1zb3J0JykgfHwgJ25vbmUnO1xuICAgICAgICBjb25zdCBuZXh0ID0gY3VycmVudCA9PT0gJ25vbmUnID8gJ2FzYycgOiBjdXJyZW50ID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB0aGlzLnNldF9zb3J0KG5leHQpO1xuXG4gICAgICAgIC8vIENhbGwgY2FsbGJhY2sgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zb3J0KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fc29ydCh0aGlzLmFyZ3MuY29sdW1uLCBuZXh0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldF9zb3J0KGRpcmVjdGlvbikge1xuICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1zb3J0JywgZGlyZWN0aW9uKTtcbiAgICAgICAgY29uc3QgJGljb24gPSB0aGlzLiRpZCgnc29ydF9pY29uJyk7XG5cbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2FzYycpIHtcbiAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1wcmltYXJ5XCI+4oaRPC9pPicpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgICAkaWNvbi5odG1sKCc8aSBjbGFzcz1cInRleHQtcHJpbWFyeVwiPuKGkzwvaT4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1tdXRlZFwiPuKHhTwvaT4nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFNwaW5uZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgc2l6ZSAoc20pXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2l6ZSA9PT0gJ3NtJykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdzcGlubmVyLWJvcmRlci1zbScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXBwbHkgY29sb3JcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb2xvcikge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKGB0ZXh0LSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgU3RhdF9DYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBTdGF0dXNfQmFkZ2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgYmFzZWQgb24gY29udGVudCBvciBhcmdzXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuYXJncy5zdGF0dXMgfHwgdGhpcy4kLnRleHQoKS50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAvLyBEZWZhdWx0IGNvbG9yIG1hcHBpbmdzXG4gICAgICAgIGNvbnN0IGNvbG9yX21hcCA9IHtcbiAgICAgICAgICAgICdhY3RpdmUnOiAnYmctc3VjY2VzcycsXG4gICAgICAgICAgICAncGVuZGluZyc6ICdiZy13YXJuaW5nJyxcbiAgICAgICAgICAgICdjb21wbGV0ZWQnOiAnYmctcHJpbWFyeScsXG4gICAgICAgICAgICAnY2FuY2VsbGVkJzogJ2JnLWRhbmdlcicsXG4gICAgICAgICAgICAnZHJhZnQnOiAnYmctc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICdhcmNoaXZlZCc6ICdiZy1kYXJrJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJnX2NsYXNzID0gdGhpcy5hcmdzLmJnX2NsYXNzIHx8IGNvbG9yX21hcFtzdGF0dXNdIHx8ICdiZy1zZWNvbmRhcnknO1xuICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoYmdfY2xhc3MpO1xuICAgIH1cbn1cbiIsImNsYXNzIFRhYl9Db250ZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEVuc3VyZSBjaGlsZHJlbiBoYXZlIHRhYi1wYW5lIGNsYXNzXG4gICAgICAgIHRoaXMuJC5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCd0YWItcGFuZSBmYWRlJyk7XG5cbiAgICAgICAgICAgIC8vIFNldCBmaXJzdCBwYW5lIGFzIGFjdGl2ZSBpZiBub25lIGFjdGl2ZVxuICAgICAgICAgICAgaWYgKCRjaGlsZC5wYXJlbnQoKS5maW5kKCcudGFiLXBhbmUuYWN0aXZlJykubGVuZ3RoID09PSAwICYmICRjaGlsZC5pbmRleCgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCdzaG93IGFjdGl2ZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBUYWJsZV9QYWdpbmF0aW9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIHBhZ2luYXRpb24gaWYgcGFnZXMgcHJvdmlkZWQgdmlhIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jdXJyZW50X3BhZ2UgJiYgdGhpcy5hcmdzLnRvdGFsX3BhZ2VzKSB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlX3BhZ2luYXRpb24odGhpcy5hcmdzLmN1cnJlbnRfcGFnZSwgdGhpcy5hcmdzLnRvdGFsX3BhZ2VzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdlbmVyYXRlX3BhZ2luYXRpb24oY3VycmVudCwgdG90YWwpIHtcbiAgICAgICAgY29uc3QgJHBhZ2luYXRpb24gPSB0aGlzLiRpZCgncGFnaW5hdGlvbicpO1xuICAgICAgICAkcGFnaW5hdGlvbi5lbXB0eSgpO1xuXG4gICAgICAgIC8vIFByZXZpb3VzIGJ1dHRvblxuICAgICAgICBjb25zdCAkcHJldiA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChjdXJyZW50ID09PSAxID8gJyBkaXNhYmxlZCcgOiAnJykpO1xuICAgICAgICAkcHJldi5hcHBlbmQoJCgnPGE+JykuYWRkQ2xhc3MoJ3BhZ2UtbGluaycpLmF0dHIoJ2hyZWYnLCAnIycpLnRleHQoJ1ByZXZpb3VzJykpO1xuICAgICAgICAkcGFnaW5hdGlvbi5hcHBlbmQoJHByZXYpO1xuXG4gICAgICAgIC8vIFBhZ2UgbnVtYmVycyAoc2hvdyA1IHBhZ2VzIG1heClcbiAgICAgICAgbGV0IHN0YXJ0ID0gTWF0aC5tYXgoMSwgY3VycmVudCAtIDIpO1xuICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4odG90YWwsIGN1cnJlbnQgKyAyKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChpID09PSBjdXJyZW50ID8gJyBhY3RpdmUnIDogJycpKTtcbiAgICAgICAgICAgICRsaS5hcHBlbmQoJCgnPGE+JykuYWRkQ2xhc3MoJ3BhZ2UtbGluaycpLmF0dHIoJ2hyZWYnLCAnIycpLnRleHQoaSkpO1xuICAgICAgICAgICAgJHBhZ2luYXRpb24uYXBwZW5kKCRsaSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOZXh0IGJ1dHRvblxuICAgICAgICBjb25zdCAkbmV4dCA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChjdXJyZW50ID09PSB0b3RhbCA/ICcgZGlzYWJsZWQnIDogJycpKTtcbiAgICAgICAgJG5leHQuYXBwZW5kKCQoJzxhPicpLmFkZENsYXNzKCdwYWdlLWxpbmsnKS5hdHRyKCdocmVmJywgJyMnKS50ZXh0KCdOZXh0JykpO1xuICAgICAgICAkcGFnaW5hdGlvbi5hcHBlbmQoJG5leHQpO1xuICAgIH1cbn1cbiIsImNsYXNzIFRhYmxlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IHZhcmlhbnQgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFyaWFudCkge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKGB0YWJsZS0ke3RoaXMuYXJncy52YXJpYW50fWApOyAvLyBzdHJpcGVkLCBib3JkZXJlZCwgYm9yZGVybGVzc1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXBwbHkgc2l6ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLnNpemUgPT09ICdzbScpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygndGFibGUtc20nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFRhYnMgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBjaGlsZHJlbiBpbiBuYXYtaXRlbSBzdHJ1Y3R1cmVcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKS5hZGRDbGFzcygnbmF2LWl0ZW0nKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ25hdi1saW5rJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLndyYXAoJGxpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IGZpcnN0IHRhYiBhcyBhY3RpdmUgaWYgbm9uZSBhY3RpdmVcbiAgICAgICAgaWYgKHRoaXMuJC5maW5kKCcubmF2LWxpbmsuYWN0aXZlJykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLiQuZmluZCgnLm5hdi1saW5rJykuZmlyc3QoKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBUYWdfR3JvdXAgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvciBuZWVkZWRcbiAgICB9XG59XG4iLCJjbGFzcyBUYWcgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYmctc2Vjb25kYXJ5JykuYWRkQ2xhc3MoYGJnLSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgVGV4dF9EaXNwbGF5IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gR2VuZXJpYyB0ZXh0IGRpc3BsYXkgLSBpbmhlcml0cyBCb290c3RyYXAgdHlwb2dyYXBoeVxufVxuIiwiLyoqXG4gKiBUZXh0YXJlYSAtIEJvb3RzdHJhcCA1IE11bHRpLWxpbmUgVGV4dCBJbnB1dCBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBNdWx0aS1saW5lIHRleHQgaW5wdXQgZm9yIGxvbmdlciBjb250ZW50IGxpa2UgZGVzY3JpcHRpb25zLCBjb21tZW50cywgbm90ZXNcbiAqIERlc2lnbjogQm9vdHN0cmFwIC5mb3JtLWNvbnRyb2wgc3R5bGluZyAoc2FtZSBhcyBJbnB1dClcbiAqL1xuY2xhc3MgVGV4dGFyZWEgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHJvd3MgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yb3dzKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cigncm93cycsIHRoaXMuYXJncy5yb3dzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBwbGFjZWhvbGRlciBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cigncGxhY2Vob2xkZXInLCB0aGlzLmFyZ3MucGxhY2Vob2xkZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHZhbHVlIGlmIHByb3ZpZGVkIChvdmVycmlkZXMgY29udGVudCgpKVxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgVGhyZWVfQ29sdW1uX0xheW91dCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGVhY2ggZGlyZWN0IGNoaWxkIGluIHJlc3BvbnNpdmUgY29sdW1uIGNsYXNzZXNcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICRlbGVtZW50LmFkZENsYXNzKCdjb2wtMTIgY29sLW1kLTYgY29sLXhsLTQgbWItNCcpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBUaW1lX1BpY2tlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5taW4pIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdtaW4nLCB0aGlzLmFyZ3MubWluKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubWF4KSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbWF4JywgdGhpcy5hcmdzLm1heCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnN0ZXApIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdzdGVwJywgdGhpcy5hcmdzLnN0ZXApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVhZG9ubHknLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgVGltZWxpbmUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBmbGV4Ym94IC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsImNsYXNzIFRpbWVzdGFtcF9EaXNwbGF5IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUHVyZSBCb290c3RyYXAgc3R5bGluZyAtIG5vIEphdmFTY3JpcHQgbmVlZGVkXG59XG4iLCJjbGFzcyBUb29sdGlwIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB0b29sdGlwIHRleHQgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudGV4dCkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtYnMtdGl0bGUnLCB0aGlzLmFyZ3MudGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcGxhY2VtZW50XG4gICAgICAgIGlmICh0aGlzLmFyZ3MucGxhY2VtZW50KSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy1wbGFjZW1lbnQnLCB0aGlzLmFyZ3MucGxhY2VtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEluaXRpYWxpemUgQm9vdHN0cmFwIHRvb2x0aXBcbiAgICAgICAgbmV3IGJvb3RzdHJhcC5Ub29sdGlwKHRoaXMuJFswXSk7XG4gICAgfVxufVxuIiwiY2xhc3MgVG9wX05hdiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGNoaWxkcmVuIGluIG5hdiBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgJG5hdiA9IHRoaXMuJGlkKCduYXZfaXRlbXMnKTtcbiAgICAgICAgJG5hdi5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+JykuYWRkQ2xhc3MoJ25hdi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCduYXYtbGluaycpO1xuICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFRyZW5kX0luZGljYXRvciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gdGhpcy4kLnRleHQoKS50cmltKCk7XG4gICAgICAgIGNvbnN0IGlzX3Bvc2l0aXZlID0gdGV4dC5zdGFydHNXaXRoKCcrJyk7XG4gICAgICAgIGNvbnN0IGlzX25lZ2F0aXZlID0gdGV4dC5zdGFydHNXaXRoKCctJyk7XG5cbiAgICAgICAgaWYgKGlzX3Bvc2l0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ3RleHQtc3VjY2VzcyBmdy1ib2xkJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNfbmVnYXRpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygndGV4dC1kYW5nZXIgZnctYm9sZCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd0ZXh0LW11dGVkIGZ3LWJvbGQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuJC5hZGRDbGFzcygnZC1ibG9jayBtdC0xJyk7XG4gICAgfVxufVxuIiwiY2xhc3MgVHdvX0NvbHVtbl9MYXlvdXQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBlYWNoIGRpcmVjdCBjaGlsZCBpbiByZXNwb25zaXZlIGNvbHVtbiBjbGFzc2VzXG4gICAgICAgIHRoaXMuJC5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkZWxlbWVudCA9ICQodGhpcyk7XG4gICAgICAgICAgICAkZWxlbWVudC5hZGRDbGFzcygnY29sLTEyIGNvbC1sZy02IG1iLTQnKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgVXNlcl9BdmF0YXJfRHJvcGRvd24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRW5zdXJlIHByb3BlciBkcm9wZG93biBpdGVtIHN0cnVjdHVyZVxuICAgICAgICBjb25zdCAkbWVudSA9IHRoaXMuJGlkKCdtZW51Jyk7XG4gICAgICAgICRtZW51LmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKTtcbiAgICAgICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSA9PT0gJ0hSJykge1xuICAgICAgICAgICAgICAgICAgICAkbGkuYXBwZW5kKCQoJzxocj4nKS5hZGRDbGFzcygnZHJvcGRvd24tZGl2aWRlcicpKTtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLnJlcGxhY2VXaXRoKCRsaSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIE1vZGFsX0Fic3RyYWN0IC0gQmFzZSBjbGFzcyBmb3IgbW9kYWwgb3JjaGVzdHJhdGlvbiBjbGFzc2VzXG4gKlxuICogKipQaGlsb3NvcGh5Kio6XG4gKiBNb2RhbCBjbGFzc2VzIGFyZSBvcmNoZXN0cmF0aW9uIGxheWVycyB0aGF0IG1hbmFnZSB0aGUgbGlmZWN5Y2xlIG9mIHNob3dpbmdcbiAqIGEgbW9kYWwsIGNvbGxlY3RpbmcgdXNlciBpbnB1dCwgYW5kIHJldHVybmluZyByZXN1bHRzLiBUaGV5IGRvIE5PVCBjb250YWluXG4gKiBmb3JtIHZhbGlkYXRpb24gb3IgYnVzaW5lc3MgbG9naWMgLSB0aGF0IGJlbG9uZ3MgaW4ganFodG1sIGNvbXBvbmVudHMgYW5kXG4gKiBjb250cm9sbGVyIGVuZHBvaW50cy5cbiAqXG4gKiAqKlB1cnBvc2UqKjpcbiAqIC0gUHJvdmlkZXMgYSBjb21tb24gYmFzZSBjbGFzcyBmb3IgdHlwZSBpZGVudGlmaWNhdGlvblxuICogLSBFbmZvcmNlcyBmaWxlIG5hbWluZyBjb252ZW50aW9ucyAobW9kYWwgY2xhc3NlcyBlbmQgd2l0aCBfTW9kYWwpXG4gKiAtIERvY3VtZW50cyB0aGUgbW9kYWwgY2xhc3MgcGF0dGVyblxuICogLSBFbmFibGVzIGZyYW1ld29yay1sZXZlbCBmZWF0dXJlcyAoZnV0dXJlOiBkaXNjb3ZlcnksIHZhbGlkYXRpb24pXG4gKlxuICogKipSZXNwb25zaWJpbGl0aWVzIG9mIE1vZGFsIENsYXNzZXMqKjpcbiAqIC0gSW52b2tlIE1vZGFsLmZvcm0oKSAvIE1vZGFsLnNob3coKSAvIE1vZGFsLmNvbmZpcm0oKSB3aXRoIGFwcHJvcHJpYXRlIGNvbmZpZ3VyYXRpb25cbiAqIC0gSGFuZGxlIG1vZGFsIGxpZmVjeWNsZSAoc2hvdywgc3VibWl0LCBjYW5jZWwsIGVycm9ycylcbiAqIC0gUmV0dXJuIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGRhdGEgb3IgZmFsc2VcbiAqIC0gRW5jYXBzdWxhdGUgbW9kYWwtc3BlY2lmaWMgVUkgbG9naWNcbiAqXG4gKiAqKkNvbnRyYWN0Kio6XG4gKiBBbGwgbW9kYWwgY2xhc3NlcyBleHRlbmRpbmcgTW9kYWxfQWJzdHJhY3QgbXVzdCBpbXBsZW1lbnQ6XG4gKiAtIGBzdGF0aWMgYXN5bmMgc2hvdyhwYXJhbXMpYDogUHJpbWFyeSBlbnRyeSBwb2ludCwgcmV0dXJucyBQcm9taXNlXG4gKlxuICogKipSZXR1cm4gVmFsdWVzKio6XG4gKiAtIFN1Y2Nlc3M6IFJlc29sdmUgd2l0aCBkYXRhIG9iamVjdCAoZS5nLiwgY3JlYXRlZCB1c2VyIHJlY29yZClcbiAqIC0gQ2FuY2VsL0Nsb3NlOiBSZXNvbHZlIHdpdGggZmFsc2VcbiAqIC0gRXJyb3I6IFNob3cgZXJyb3IgaW4gbW9kYWwsIGtlZXAgb3BlbiwgZG9uJ3QgcmVzb2x2ZSB1bnRpbCB1c2VyIGFjdHNcbiAqXG4gKiAqKkludGVncmF0aW9uKio6XG4gKiBNb2RhbCBjbGFzc2VzIHVzZSBNb2RhbC5qcyBzdGF0aWMgQVBJIChNb2RhbC5mb3JtKCksIE1vZGFsLnNob3coKSwgZXRjLilcbiAqIGFzIGJ1aWxkaW5nIGJsb2Nrcy4gRm9ybSB2YWxpZGF0aW9uIGhhbmRsZWQgYnkgUnN4X0Zvcm0gYW5kIEZvcm1fVXRpbHMuXG4gKiBQYWdlIEpTIG9yY2hlc3RyYXRlcyBtb2RhbCBmbG93IGJ1dCBkb2Vzbid0IGNvbnRhaW4gbW9kYWwgVUkgbG9naWMuXG4gKlxuICogKipQYXR0ZXJuIEV4YW1wbGVzKio6XG4gKlxuICogU2ltcGxlIGZvcm0gbW9kYWw6XG4gKiBgYGBcbiAqIGNsYXNzIEFkZF9Vc2VyX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICogICAgIHN0YXRpYyBhc3luYyBzaG93KCkge1xuICogICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAqICAgICAgICAgICAgIHRpdGxlOiAnQWRkIFVzZXInLFxuICogICAgICAgICAgICAgY29tcG9uZW50OiAnQWRkX1VzZXJfTW9kYWxfRm9ybScsXG4gKiAgICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gKiAgICAgICAgICAgICAgICAgdHJ5IHtcbiAqICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZm9ybS52YWxzKCk7XG4gKiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IENvbnRyb2xsZXIuYWRkX3VzZXIodmFsdWVzKTtcbiAqICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsgLy8gQ2xvc2UgbW9kYWwsIHJldHVybiBkYXRhXG4gKiAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm9ybS5yZW5kZXJfZXJyb3IoZXJyb3IpO1xuICogICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEtlZXAgbW9kYWwgb3BlblxuICogICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgIH0pO1xuICogICAgICAgICByZXR1cm4gcmVzdWx0IHx8IGZhbHNlO1xuICogICAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEN1c3RvbSBjb250ZW50IG1vZGFsOlxuICogYGBgXG4gKiBjbGFzcyBDb25maXJtX0RlbGV0ZV9Nb2RhbCBleHRlbmRzIE1vZGFsX0Fic3RyYWN0IHtcbiAqICAgICBzdGF0aWMgYXN5bmMgc2hvdyh7aXRlbV9uYW1lfSkge1xuICogICAgICAgICByZXR1cm4gYXdhaXQgTW9kYWwuY29uZmlybShcbiAqICAgICAgICAgICAgICdDb25maXJtIERlbGV0ZScsXG4gKiAgICAgICAgICAgICBgQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSAke2l0ZW1fbmFtZX0/YFxuICogICAgICAgICApO1xuICogICAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIE1vZGFsIHdpdGggYmFja2VuZCBjYWxsOlxuICogYGBgXG4gKiBjbGFzcyBTZW5kX0ludml0ZV9Nb2RhbCBleHRlbmRzIE1vZGFsX0Fic3RyYWN0IHtcbiAqICAgICBzdGF0aWMgYXN5bmMgc2hvdyh1c2VyX2lkKSB7XG4gKiAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IENvbnRyb2xsZXIuc2VuZF9pbnZpdGUoe3VzZXJfaWR9KTtcbiAqICAgICAgICAgaWYgKHJlc3VsdC5pbnZpdGVfdXJsKSB7XG4gKiAgICAgICAgICAgICBhd2FpdCBNb2RhbC5hbGVydCgnSW52aXRlIFNlbnQnLCByZXN1bHQuaW52aXRlX3VybCk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAqICAgICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAqKlVzYWdlIFBhdHRlcm4qKjpcbiAqIGBgYFxuICogLy8gUGFnZSBKUyBvcmNoZXN0cmF0ZXMgZmxvdywgbW9kYWxzIGhhbmRsZSBVSVxuICogY29uc3QgdXNlciA9IGF3YWl0IEFkZF9Vc2VyX01vZGFsLnNob3coKTtcbiAqIGlmICh1c2VyKSB7XG4gKiAgICAgJCgnLlVzZXJzX0RhdGFHcmlkJykuY29tcG9uZW50KCkucmVsb2FkKCk7XG4gKiAgICAgYXdhaXQgU2VuZF9Vc2VyX0ludml0ZV9Nb2RhbC5zaG93KHVzZXIuaWQpO1xuICogfVxuICogYGBgXG4gKlxuICogKipCZXN0IFByYWN0aWNlcyoqOlxuICogLSBLZWVwIG1vZGFsIGNsYXNzZXMgZm9jdXNlZDogb25lIG1vZGFsID0gb25lIGNsYXNzXG4gKiAtIFBhZ2UgSlMgb3JjaGVzdHJhdGVzIHNlcXVlbmNlLCBtb2RhbCBjbGFzc2VzIGhhbmRsZSBpbmRpdmlkdWFsIG1vZGFsc1xuICogLSBNb2RhbCBjbGFzc2VzIGRvbid0IGNhbGwgZWFjaCBvdGhlciBkaXJlY3RseVxuICogLSBNb2RhbCBjbGFzc2VzIGRvbid0IHVwZGF0ZSBVSSAoZ3JpZHMsIGxpc3RzKSAtIHBhZ2UgSlMgZG9lcyB0aGF0XG4gKiAtIFVzZSBkZXNjcmlwdGl2ZSBuYW1lcyBlbmRpbmcgaW4gX01vZGFsIChBZGRfVXNlcl9Nb2RhbCwgU2VuZF9JbnZpdGVfTW9kYWwpXG4gKiAtIFBsYWNlIGZlYXR1cmUtc3BlY2lmaWMgbW9kYWxzIGluIGZlYXR1cmUgZGlyZWN0b3J5XG4gKiAtIFBsYWNlIHJldXNhYmxlIG1vZGFscyBpbiB0aGVtZS9jb21wb25lbnRzL21vZGFsL1xuICpcbiAqICoqV2hlbiB0byBVc2UgTW9kYWwgQ2xhc3NlcyoqOlxuICogLSBNdWx0aS1zdGVwIGZvcm1zXG4gKiAtIEZvcm1zIHdpdGggY29tcGxleCB2YWxpZGF0aW9uXG4gKiAtIE1vZGFscyBjYWxsZWQgZnJvbSBtdWx0aXBsZSBwbGFjZXNcbiAqIC0gTW9kYWxzIHdpdGggYmFja2VuZCBpbnRlcmFjdGlvbnNcbiAqXG4gKiAqKldoZW4gTk9UIHRvIFVzZSBNb2RhbCBDbGFzc2VzKio6XG4gKiAtIFNpbXBsZSBhbGVydHM6IGBhd2FpdCBNb2RhbC5hbGVydCgnU2F2ZWQhJylgXG4gKiAtIFNpbXBsZSBjb25maXJtYXRpb25zOiBgaWYgKGF3YWl0IE1vZGFsLmNvbmZpcm0oJ0RlbGV0ZT8nKSkgey4uLn1gXG4gKiAtIE9uZS1vZmYgcHJvbXB0czogYGNvbnN0IG5hbWUgPSBhd2FpdCBNb2RhbC5wcm9tcHQoJ0VudGVyIG5hbWU6JylgXG4gKi9cbmNsYXNzIE1vZGFsX0Fic3RyYWN0IHtcbiAgICAvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIHN0cnVjdHVyZSBhbmQgZG9jdW1lbnRhdGlvbiBmb3IgbW9kYWwgcGF0dGVybnMuXG4gICAgLy8gQ29uY3JldGUgbW9kYWwgY2xhc3NlcyBleHRlbmQgdGhpcyBhbmQgaW1wbGVtZW50IHN0YXRpYyBzaG93KCkgbWV0aG9kLlxufVxuIiwiLyoqXG4gKiBSc3hfTW9kYWwgQ29tcG9uZW50XG4gKlxuICogSW5zdGFuY2Ugb2YgYSBtb2RhbCBkaWFsb2cuIEhhbmRsZXMgbGlmZWN5Y2xlLCBzaXppbmcsIGFuZCB1c2VyIGludGVyYWN0aW9uLlxuICogVHlwaWNhbGx5IGNyZWF0ZWQgYW5kIG1hbmFnZWQgYnkgdGhlIE1vZGFsIHN0YXRpYyBBUEkgY2xhc3MuXG4gKi9cbmNsYXNzIFJzeF9Nb2RhbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnRpdGxlID0gJyc7XG4gICAgICAgIHRoaXMuZGF0YS5ib2R5X2NvbnRlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmRhdGEuYnV0dG9ucyA9IFtdO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEubWF4X3dpZHRoID0gODAwO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2Vfb25fc3VibWl0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5kYXRhLnJlc3VsdF9wcm9taXNlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuXG4gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBib290c3RyYXAgbW9kYWwgaW5zdGFuY2VcbiAgICAgICAgdGhpcy5fYnNfbW9kYWwgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFNldCB1cCBjbG9zZSBidXR0b24gaGFuZGxlclxuICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIGJhY2tkcm9wIGNsaWNrIGhhbmRsZXJcbiAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUgJiYgZS50YXJnZXQgPT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIEVTQyBrZXkgaGFuZGxlclxuICAgICAgICAkKGRvY3VtZW50KS5vbigna2V5ZG93bi5yc3hfbW9kYWxfJyArIHRoaXMuX2NpZCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgJiYgdGhhdC5kYXRhLmNsb3NhYmxlICYmIHRoYXQuZGF0YS5pc192aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5jbG9zZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCB1cCByZXNpemUgaGFuZGxlclxuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IGRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuaXNfdmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuX2FwcGx5X3NpemluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAxMDApO1xuXG4gICAgICAgICQod2luZG93KS5vbigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkLCB0aGlzLl9yZXNpemVfaGFuZGxlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIGFuZCBzaG93IHRoZSBtb2RhbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gTW9kYWwgb3B0aW9ucyAodGl0bGUsIGJvZHksIGJ1dHRvbnMsIGV0Yy4pXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGludGVybmFsX29wdGlvbnMgLSBJbnRlcm5hbCBvcHRpb25zIChza2lwX2JhY2tkcm9wLCBhbmltYXRlKVxuICAgICAqL1xuICAgIGFzeW5jIHNob3cob3B0aW9ucywgaW50ZXJuYWxfb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCBza2lwX2JhY2tkcm9wID0gaW50ZXJuYWxfb3B0aW9ucy5za2lwX2JhY2tkcm9wIHx8IGZhbHNlO1xuICAgICAgICBjb25zdCBzaG91bGRfYW5pbWF0ZSA9IGludGVybmFsX29wdGlvbnMuYW5pbWF0ZSB8fCBmYWxzZTtcblxuICAgICAgICBjb25zb2xlLmxvZygnW1JzeF9Nb2RhbF0gc2hvdygpIGNhbGxlZCB3aXRoIG9wdGlvbnM6Jywgb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gU3RvcmUgb3B0aW9uc1xuICAgICAgICB0aGlzLmRhdGEudGl0bGUgPSBvcHRpb25zLnRpdGxlIHx8ICcnO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSBvcHRpb25zLmNsb3NhYmxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NhYmxlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLm1heF93aWR0aCA9IG9wdGlvbnMubWF4X3dpZHRoIHx8IDgwMDtcbiAgICAgICAgdGhpcy5kYXRhLmNsb3NlX29uX3N1Ym1pdCA9IG9wdGlvbnMuY2xvc2Vfb25fc3VibWl0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NlX29uX3N1Ym1pdCA6IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5idXR0b25zID0gb3B0aW9ucy5idXR0b25zIHx8IFtdO1xuICAgICAgICB0aGlzLmRhdGEuc2tpcF9iYWNrZHJvcCA9IHNraXBfYmFja2Ryb3A7XG4gICAgICAgIHRoaXMuZGF0YS5pY29uID0gb3B0aW9ucy5pY29uIHx8IG51bGw7XG5cbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFNldHRpbmcgdGl0bGUgdG86JywgdGhpcy5kYXRhLnRpdGxlKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFRpdGxlIGVsZW1lbnQ6JywgdGhpcy4kaWQoJ3RpdGxlJykpO1xuXG4gICAgICAgIC8vIFNldCB0aXRsZVxuICAgICAgICB0aGlzLiRpZCgndGl0bGUnKS50ZXh0KHRoaXMuZGF0YS50aXRsZSk7XG5cbiAgICAgICAgLy8gU2hvdy9oaWRlIGNsb3NlIGJ1dHRvbiBiYXNlZCBvbiBjbG9zYWJsZVxuICAgICAgICBpZiAodGhpcy5kYXRhLmNsb3NhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykuc2hvdygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2Nsb3NlX2J0bicpLmhpZGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBib2R5IGNvbnRlbnQgKHdpdGggb3B0aW9uYWwgaWNvbilcbiAgICAgICAgdGhpcy5fc2V0X2JvZHlfY29udGVudChvcHRpb25zLmJvZHksIHRoaXMuZGF0YS5pY29uKTtcblxuICAgICAgICAvLyBTZXQgYnV0dG9uc1xuICAgICAgICB0aGlzLl9zZXRfYnV0dG9ucygpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdoZW4gbW9kYWwgY2xvc2VzXG4gICAgICAgIGNvbnN0IHJlc3VsdF9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoYXQuZGF0YS5yZXNvbHZlX2ZuID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgYmFja2Ryb3BcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSB0cnVlO1xuXG4gICAgICAgIC8vIEFwcGVuZCB0byBib2R5IHNvIGl0J3Mgb24gdG9wIChkb24ndCBhcHBlbmQgYmFja2Ryb3AgaWYgdXNpbmcgc2hhcmVkKVxuICAgICAgICBpZiAoIXNraXBfYmFja2Ryb3ApIHtcbiAgICAgICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kaWQoJ2JhY2tkcm9wJykpO1xuICAgICAgICB9XG4gICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kKTtcblxuICAgICAgICAvLyBBcHBseSBzaXppbmcgYmVmb3JlIHNob3dpbmdcbiAgICAgICAgdGhpcy5fYXBwbHlfc2l6aW5nKCk7XG5cbiAgICAgICAgLy8gRmFkZSBpbiBtb2RhbCAoYW5kIGJhY2tkcm9wIGlmIG5vdCB1c2luZyBzaGFyZWQpXG4gICAgICAgIGF3YWl0IHRoaXMuX2ZhZGVfaW4oc2hvdWxkX2FuaW1hdGUpO1xuXG4gICAgICAgIC8vIEF1dG8tZm9jdXMgZmlyc3QgaW5wdXQgZWxlbWVudFxuICAgICAgICB0aGlzLl9mb2N1c19maXJzdF9pbnB1dCgpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRfcHJvbWlzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYm9keSBjb250ZW50IHdpdGggb3B0aW9uYWwgaWNvblxuICAgICAqL1xuICAgIF9zZXRfYm9keV9jb250ZW50KGJvZHksIGljb24pIHtcbiAgICAgICAgY29uc3QgJGJvZHkgPSB0aGlzLiRpZCgnYm9keScpO1xuICAgICAgICAkYm9keS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIElmIGljb24gcHJvdmlkZWQsIGFkZCBpdFxuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgY29uc3QgJGljb24gPSAkKGA8aSBjbGFzcz1cImJpIGJpLSR7aWNvbn0gbW9kYWwtaWNvblwiPjwvaT5gKTtcbiAgICAgICAgICAgICRib2R5LmFwcGVuZCgkaWNvbik7XG4gICAgICAgICAgICAkYm9keS5hZGRDbGFzcygnaGFzLWljb24nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRib2R5LnJlbW92ZUNsYXNzKCdoYXMtaWNvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IG9yIGNyZWF0ZSBib2R5IGNvbnRlbnQgd3JhcHBlclxuICAgICAgICBsZXQgJGNvbnRlbnQgPSB0aGlzLiRpZCgnYm9keV9jb250ZW50Jyk7XG4gICAgICAgIGlmICghJGNvbnRlbnQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICRjb250ZW50ID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHktY29udGVudFwiPjwvZGl2PicpO1xuICAgICAgICAgICAgJGJvZHkuYXBwZW5kKCRjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIFRleHQgY29udGVudCAtIGVzY2FwZSBhbmQgY29udmVydCBuZXdsaW5lc1xuICAgICAgICAgICAgY29uc3QgZXNjYXBlZCA9ICQoJzxkaXY+JykudGV4dChib2R5KS5odG1sKCkucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgICAgICAgICAkY29udGVudC5odG1sKGVzY2FwZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGJvZHkgaW5zdGFuY2VvZiBqUXVlcnkpIHtcbiAgICAgICAgICAgIC8vIGpRdWVyeSBlbGVtZW50XG4gICAgICAgICAgICAkY29udGVudC5hcHBlbmQoYm9keSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIEFzc3VtZSBpdCdzIGEganFodG1sIGNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICAgICAgJGNvbnRlbnQuYXBwZW5kKGJvZHkuJCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYnV0dG9ucyBpbiBmb290ZXJcbiAgICAgKi9cbiAgICBfc2V0X2J1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCAkZm9vdGVyID0gdGhpcy4kaWQoJ2Zvb3RlcicpO1xuICAgICAgICAkZm9vdGVyLmVtcHR5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5idXR0b25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgJGZvb3Rlci5oaWRlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAkZm9vdGVyLnNob3coKTtcblxuICAgICAgICBmb3IgKGxldCBidXR0b25fZGVmIG9mIHRoaXMuZGF0YS5idXR0b25zKSB7XG4gICAgICAgICAgICBjb25zdCAkYnV0dG9uID0gJCgnPGJ1dHRvbj4nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCd0eXBlJywgJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdidG4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhidXR0b25fZGVmLmNsYXNzIHx8ICdidG4tc2Vjb25kYXJ5JylcbiAgICAgICAgICAgICAgICAudGV4dChidXR0b25fZGVmLmxhYmVsIHx8ICdCdXR0b24nKTtcblxuICAgICAgICAgICAgJGJ1dHRvbi5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGJ1dHRvbl9kZWYudmFsdWU7XG4gICAgICAgICAgICAgICAgbGV0IGhhZF9jYWxsYmFjayA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgYnV0dG9uIGhhcyBhIGNhbGxiYWNrLCBjYWxsIGl0IGFuZCB1c2UgcmV0dXJuIHZhbHVlIGFzIHJlc3VsdFxuICAgICAgICAgICAgICAgIGlmIChidXR0b25fZGVmLmNhbGxiYWNrICYmIHR5cGVvZiBidXR0b25fZGVmLmNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhZF9jYWxsYmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IGJ1dHRvbl9kZWYuY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5lZCBmYWxzZSwga2VlcCBtb2RhbCBvcGVuIChidXQgbm90IGlmIGp1c3QgYnV0dG9uIHZhbHVlIGlzIGZhbHNlKVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlICYmIGhhZF9jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ2xvc2UgbW9kYWwgd2l0aCByZXN1bHRcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGZvb3Rlci5hcHBlbmQoJGJ1dHRvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgYW5kIGFwcGx5IHJlc3BvbnNpdmUgc2l6aW5nXG4gICAgICovXG4gICAgX2FwcGx5X3NpemluZygpIHtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfaGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgICAgICBjb25zdCBpc19tb2JpbGUgPSB2aWV3cG9ydF93aWR0aCA8IDc2ODtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgbWF4IHdpZHRoIGJhc2VkIG9uIHZpZXdwb3J0XG4gICAgICAgIGxldCBtYXhfd2lkdGggPSB0aGlzLmRhdGEubWF4X3dpZHRoO1xuICAgICAgICBjb25zdCB2aWV3cG9ydF9saW1pdCA9IGlzX21vYmlsZSA/IHZpZXdwb3J0X3dpZHRoICogMC45IDogdmlld3BvcnRfd2lkdGggKiAwLjg7XG5cbiAgICAgICAgbWF4X3dpZHRoID0gTWF0aC5taW4obWF4X3dpZHRoLCB2aWV3cG9ydF9saW1pdCk7XG5cbiAgICAgICAgLy8gVHJ5IHRvIGNvbnN0cmFpbiB0byA2MCUgd2lkdGggZm9yIGJldHRlciBwcm9wb3J0aW9ucyBvbiBkZXNrdG9wXG4gICAgICAgIGlmICghaXNfbW9iaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmVmZXJyZWRfd2lkdGggPSB2aWV3cG9ydF93aWR0aCAqIDAuNjtcbiAgICAgICAgICAgIGlmIChwcmVmZXJyZWRfd2lkdGggPCBtYXhfd2lkdGgpIHtcbiAgICAgICAgICAgICAgICBtYXhfd2lkdGggPSBwcmVmZXJyZWRfd2lkdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBseSB3aWR0aFxuICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCdtYXgtd2lkdGgnLCBtYXhfd2lkdGggKyAncHgnKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50IGV4Y2VlZHMgODAlIGhlaWdodFxuICAgICAgICBjb25zdCBjb250ZW50X2hlaWdodCA9IHRoaXMuJGlkKCdkaWFsb2cnKS5vdXRlckhlaWdodCgpO1xuICAgICAgICBjb25zdCBtYXhfaGVpZ2h0ID0gdmlld3BvcnRfaGVpZ2h0ICogMC44O1xuXG4gICAgICAgIGlmIChjb250ZW50X2hlaWdodCA+IG1heF9oZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIEVuYWJsZSBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCBtYXhfaGVpZ2h0ICsgJ3B4Jyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnYXV0bycsXG4gICAgICAgICAgICAgICAgJ21heC1oZWlnaHQnOiBtYXhfaGVpZ2h0IC0gMTUwICsgJ3B4JywgLy8gQWNjb3VudCBmb3IgaGVhZGVyL2Zvb3RlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXNldCBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCAnJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnJyxcbiAgICAgICAgICAgICAgICAnbWF4LWhlaWdodCc6ICcnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNb2JpbGUgZWRnZSBzcGFjaW5nXG4gICAgICAgIGlmIChpc19tb2JpbGUpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21hcmdpbicsICc1JScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWFyZ2luJywgJzAnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW5pbWF0aW9uIChpbnN0YW50IG9yIHdpdGggZmx5LWluKVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYW5pbWF0ZSAtIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgbW9kYWwgZW50cmFuY2VcbiAgICAgKi9cbiAgICBhc3luYyBfZmFkZV9pbihhbmltYXRlID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGFuaW1hdGUpIHtcbiAgICAgICAgICAgIC8vIEluaXRpYWwgc3RhdGU6IG1vZGFsIHBvc2l0aW9uZWQgYWJvdmUgZmluYWwgcG9zaXRpb25cbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ2Rpc3BsYXknLCAnZmxleCcpLmNzcygnb3BhY2l0eScsICcwJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5jc3Moe1xuICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0nOiAndHJhbnNsYXRlKDAsIC01MHB4KScsXG4gICAgICAgICAgICAgICAgJ29wYWNpdHknOiAnMCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcblxuICAgICAgICAgICAgLy8gRm9yY2UgcmVmbG93XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKVswXS5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5hZGRDbGFzcygnc2hvdycpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3RyYW5zZm9ybSc6ICd0cmFuc2xhdGUoMCwgMCknLFxuICAgICAgICAgICAgICAgICdvcGFjaXR5JzogJzEnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgICAgICAvLyBXYWl0IGZvciBhbmltYXRpb24gdG8gY29tcGxldGVcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCAxNTApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIERpc2FibGUgdHJhbnNpdGlvbnMgdGVtcG9yYXJpbHkgZm9yIGluc3RhbnQgZGlzcGxheVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICdub25lJyk7XG5cbiAgICAgICAgICAgIC8vIFNob3cgbW9kYWwgYW5kIGJhY2tkcm9wIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy4kLmNzcygnZGlzcGxheScsICdmbGV4JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpLmFkZENsYXNzKCdzaG93JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmNzcygnZGlzcGxheScsICdibG9jaycpLmFkZENsYXNzKCdzaG93Jyk7XG5cbiAgICAgICAgICAgIC8vIEZvcmNlIHJlZmxvdyB0byBhcHBseSB0aGUgbm8tdHJhbnNpdGlvbiBzdGF0ZVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpWzBdLm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgLy8gUmUtZW5hYmxlIHRyYW5zaXRpb25zIGZvciBmdXR1cmUgYW5pbWF0aW9uc1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb2N1cyB0aGUgZmlyc3QgaW5wdXQgZWxlbWVudCBpbiB0aGUgbW9kYWxcbiAgICAgKi9cbiAgICBfZm9jdXNfZmlyc3RfaW5wdXQoKSB7XG4gICAgICAgIC8vIEZpbmQgZmlyc3QgaW5wdXQvdGV4dGFyZWEvc2VsZWN0IGluIG1vZGFsIGJvZHlcbiAgICAgICAgY29uc3QgJGZpcnN0X2lucHV0ID0gdGhpcy4kaWQoJ2JvZHknKS5maW5kKCdpbnB1dDpub3QoW3R5cGU9XCJoaWRkZW5cIl0pLCB0ZXh0YXJlYSwgc2VsZWN0JykuZmlyc3QoKTtcbiAgICAgICAgaWYgKCRmaXJzdF9pbnB1dC5leGlzdHMoKSkge1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgICAkZmlyc3RfaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGV4dCBpZiBpdCdzIGFuIGlucHV0IHdpdGggZXhpc3RpbmcgdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAoJGZpcnN0X2lucHV0LmlzKCdpbnB1dFt0eXBlPVwidGV4dFwiXSwgaW5wdXRbdHlwZT1cImVtYWlsXCJdJykgJiYgJGZpcnN0X2lucHV0LnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICRmaXJzdF9pbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBtb2RhbCBpbnN0YW50bHlcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZShyZXN1bHQpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gTWFyayBhcyBub3QgdmlzaWJsZVxuICAgICAgICB0aGlzLmRhdGEuaXNfdmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIFJlbW92ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgJChkb2N1bWVudCkub2ZmKCdrZXlkb3duLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcbiAgICAgICAgJCh3aW5kb3cpLm9mZigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcblxuICAgICAgICAvLyBIaWRlIGluc3RhbnRseSAobm8gZmFkZSBvdXQpXG4gICAgICAgIHRoaXMuJC5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmhpZGUoKTtcblxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBET01cbiAgICAgICAgdGhpcy4kLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLiRpZCgnYmFja2Ryb3AnKS5yZW1vdmUoKTtcblxuICAgICAgICAvLyBSZXNvbHZlIHByb21pc2VcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5yZXNvbHZlX2ZuKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEucmVzb2x2ZV9mbihyZXN1bHQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgdmFsaWRhdGlvbiBlcnJvcnMgdG8gZm9ybSBmaWVsZHMgaW4gbW9kYWwgYm9keVxuICAgICAqL1xuICAgIGFwcGx5X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gVXNlIEZvcm1fVXRpbHMgdG8gYXBwbHkgZXJyb3JzIHRvIGVsZW1lbnRzIHdpdGhpbiBtb2RhbCBib2R5XG4gICAgICAgIEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnModGhpcy4kaWQoJ2JvZHknKSwgZXJyb3JzKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIE1vZGFsIFN0YXRpYyBBUElcbiAqXG4gKiBQcmltYXJ5IGludGVyZmFjZSBmb3IgZGlzcGxheWluZyBtb2RhbHMgdGhyb3VnaG91dCB0aGUgYXBwbGljYXRpb24uXG4gKiBQcm92aWRlcyBzaW1wbGUgbWV0aG9kcyBmb3IgY29tbW9uIGRpYWxvZ3MgYW5kIGZsZXhpYmxlIG9wdGlvbnMgZm9yIGN1c3RvbSBtb2RhbHMuXG4gKlxuICogVXNhZ2U6XG4gKiAgIGF3YWl0IE1vZGFsLmFsZXJ0KFwiRmlsZSBzYXZlZFwiKVxuICogICBpZiAoYXdhaXQgTW9kYWwuY29uZmlybShcIkRlbGV0ZT9cIikpIHsgLi4uIH1cbiAqICAgbGV0IG5hbWUgPSBhd2FpdCBNb2RhbC5wcm9tcHQoXCJFbnRlciBuYW1lOlwiKVxuICogICBsZXQgcmVzdWx0ID0gYXdhaXQgTW9kYWwuc2hvdyh7IHRpdGxlLCBib2R5LCBidXR0b25zIH0pXG4gKi9cbmNsYXNzIE1vZGFsIHtcbiAgICAvLyBJbnRlcm5hbCBzdGF0ZVxuICAgIHN0YXRpYyBfcXVldWUgPSBbXTtcbiAgICBzdGF0aWMgX2N1cnJlbnQgPSBudWxsO1xuICAgIHN0YXRpYyBfaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBzdGF0aWMgX2JhY2tkcm9wID0gbnVsbDtcbiAgICBzdGF0aWMgX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgPSBudWxsO1xuICAgIHN0YXRpYyBfb3JpZ2luYWxfYm9keV9wYWRkaW5nID0gbnVsbDtcbiAgICBzdGF0aWMgX3VubG9ja190aW1lb3V0ID0gbnVsbDtcbiAgICBzdGF0aWMgX2xhc3RfY2xvc2VfdGltZXN0YW1wID0gMDtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZ2xvYmFsIGhhbmRsZXJzIChjYWxsZWQgYXV0b21hdGljYWxseSBvbiBmaXJzdCBtb2RhbClcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfaW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgICAvLyBDcmVhdGUgc2hhcmVkIGJhY2tkcm9wIGVsZW1lbnRcbiAgICAgICAgdGhpcy5fYmFja2Ryb3AgPSAkKCc8ZGl2IGNsYXNzPVwibW9kYWwtYmFja2Ryb3AgZmFkZVwiPjwvZGl2PicpO1xuICAgICAgICAkKCdib2R5JykuYXBwZW5kKHRoaXMuX2JhY2tkcm9wKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgc2Nyb2xsYmFyIHdpZHRoXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBfZ2V0X3Njcm9sbGJhcl93aWR0aCgpIHtcbiAgICAgICAgLy8gQ3JlYXRlIHRlbXBvcmFyeSBlbGVtZW50IHRvIG1lYXN1cmUgc2Nyb2xsYmFyIHdpZHRoXG4gICAgICAgIGNvbnN0ICRvdXRlciA9ICQoJzxkaXY+JykuY3NzKHtcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICAgICAgb3ZlcmZsb3c6ICdzY3JvbGwnLFxuICAgICAgICAgICAgd2lkdGg6ICcxMDBweCcsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJy05OTk5cHgnLFxuICAgICAgICB9KTtcbiAgICAgICAgJCgnYm9keScpLmFwcGVuZCgkb3V0ZXIpO1xuXG4gICAgICAgIGNvbnN0IHdpZHRoX3dpdGhfc2Nyb2xsYmFyID0gJG91dGVyWzBdLm9mZnNldFdpZHRoO1xuXG4gICAgICAgIGNvbnN0ICRpbm5lciA9ICQoJzxkaXY+JykuY3NzKCd3aWR0aCcsICcxMDAlJyk7XG4gICAgICAgICRvdXRlci5hcHBlbmQoJGlubmVyKTtcblxuICAgICAgICBjb25zdCB3aWR0aF93aXRob3V0X3Njcm9sbGJhciA9ICRpbm5lclswXS5vZmZzZXRXaWR0aDtcblxuICAgICAgICAkb3V0ZXIucmVtb3ZlKCk7XG5cbiAgICAgICAgcmV0dXJuIHdpZHRoX3dpdGhfc2Nyb2xsYmFyIC0gd2lkdGhfd2l0aG91dF9zY3JvbGxiYXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9jayBib2R5IHNjcm9sbCBhbmQgY29tcGVuc2F0ZSBmb3Igc2Nyb2xsYmFyIHdpZHRoXG4gICAgICogT25seSBsb2NrcyBpZiB3ZSBoYXZlbid0IGFscmVhZHkgc2F2ZWQgdGhlIG9yaWdpbmFsIHN0YXRlIChmaXJzdCBtb2RhbCBpbiBjaGFpbilcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfbG9ja19ib2R5X3Njcm9sbCgpIHtcbiAgICAgICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIHVubG9jayB0aW1lb3V0XG4gICAgICAgIGlmICh0aGlzLl91bmxvY2tfdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3VubG9ja190aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMuX3VubG9ja190aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE9ubHkgbG9jayBzY3JvbGwgaWYgd2UgaGF2ZW4ndCBhbHJlYWR5IHNhdmVkIHN0YXRlIChmaXJzdCBtb2RhbClcbiAgICAgICAgLy8gVGhpcyBpcyB0aGUgdHJ1ZSBpbmRpY2F0b3IgLSBub3QgYmFja2Ryb3AgdmlzaWJpbGl0eSB3aGljaCBjYW4gYmUgdHJhbnNpdGlvbmFsXG4gICAgICAgIGlmICh0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCAkYm9keSA9ICQoJ2JvZHknKTtcblxuICAgICAgICAgICAgLy8gU3RvcmUgb3JpZ2luYWwgdmFsdWVzXG4gICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID0gJGJvZHkuY3NzKCdvdmVyZmxvdycpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nID0gJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0Jyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGJvZHkgY3VycmVudGx5IGhhcyB2ZXJ0aWNhbCBzY3JvbGxcbiAgICAgICAgICAgIGNvbnN0IGhhc19zY3JvbGxiYXIgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUncyBhIHNjcm9sbGJhciwgYWRkIHBhZGRpbmcgdG8gY29tcGVuc2F0ZSBmb3IgaXRzIHJlbW92YWxcbiAgICAgICAgICAgIGlmIChoYXNfc2Nyb2xsYmFyKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsYmFyX3dpZHRoID0gdGhpcy5fZ2V0X3Njcm9sbGJhcl93aWR0aCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRfcGFkZGluZyA9IGludCh0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcpIHx8IDA7XG4gICAgICAgICAgICAgICAgJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgY3VycmVudF9wYWRkaW5nICsgc2Nyb2xsYmFyX3dpZHRoICsgJ3B4Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExvY2sgc2Nyb2xsXG4gICAgICAgICAgICAkYm9keS5jc3MoJ292ZXJmbG93JywgJ2hpZGRlbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5sb2NrIGJvZHkgc2Nyb2xsIGFuZCByZXN0b3JlIG9yaWdpbmFsIHN0YXRlXG4gICAgICogVXNlcyBkZWxheWVkIGNoZWNrIHRvIGVuc3VyZSBubyBvdGhlciBtb2RhbHMgYXJlIG9wZW5pbmdcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfdW5sb2NrX2JvZHlfc2Nyb2xsKCkge1xuICAgICAgICAvLyBDbGVhciBhbnkgZXhpc3RpbmcgdGltZW91dFxuICAgICAgICBpZiAodGhpcy5fdW5sb2NrX3RpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl91bmxvY2tfdGltZW91dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNaW5pbWFsIGRlbGF5IGJlZm9yZSB1bmxvY2tpbmdcbiAgICAgICAgdGhpcy5fdW5sb2NrX3RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIERvdWJsZS1jaGVjayBubyBtb2RhbCBpcyBjdXJyZW50bHkgb3BlbiBhbmQgcXVldWUgaXMgZW1wdHlcbiAgICAgICAgICAgIGlmICghdGhpcy5fY3VycmVudCAmJiB0aGlzLl9xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkYm9keSA9ICQoJ2JvZHknKTtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgJGJvZHkuY3NzKCdvdmVyZmxvdycsIHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl91bmxvY2tfdGltZW91dCA9IG51bGw7XG4gICAgICAgIH0sIDUwKTsgLy8gTWluaW1hbCBzYWZldHkgYnVmZmVyXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyB0aGUgc2hhcmVkIGJhY2tkcm9wIChpbnN0YW50IC0gbm8gYW5pbWF0aW9uKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9zaG93X2JhY2tkcm9wKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2JhY2tkcm9wLmhhc0NsYXNzKCdzaG93JykpIHtcbiAgICAgICAgICAgIC8vIExvY2sgYm9keSBzY3JvbGwgYmVmb3JlIHNob3dpbmcgYmFja2Ryb3BcbiAgICAgICAgICAgIHRoaXMuX2xvY2tfYm9keV9zY3JvbGwoKTtcblxuICAgICAgICAgICAgdGhpcy5fYmFja2Ryb3AuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcbiAgICAgICAgICAgIC8vIE5vIGRlbGF5IC0gcmV0dXJuIGltbWVkaWF0ZWx5XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlIHRoZSBzaGFyZWQgYmFja2Ryb3AgKGluc3RhbnQgLSBubyBhbmltYXRpb24pXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX2hpZGVfYmFja2Ryb3AoKSB7XG4gICAgICAgIHRoaXMuX2JhY2tkcm9wLnJlbW92ZUNsYXNzKCdzaG93JykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcblxuICAgICAgICAvLyBVbmxvY2sgYm9keSBzY3JvbGwgYWZ0ZXIgYmFja2Ryb3AgaXMgaGlkZGVuXG4gICAgICAgIHRoaXMuX3VubG9ja19ib2R5X3Njcm9sbCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBSc3hfTW9kYWwgaW5zdGFuY2VcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfY3JlYXRlX21vZGFsKCkge1xuICAgICAgICAvLyBDcmVhdGUgbW9kYWwgY29tcG9uZW50IHVzaW5nIGpRdWVyeSBwbHVnaW5cbiAgICAgICAgY29uc3QgJG1vZGFsX2VsZW1lbnQgPSAkKCc8ZGl2PicpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBjb21wb25lbnQgaW5zdGFuY2UgZGlyZWN0bHkgKHJldHVybnMgdGhlIGNvbXBvbmVudClcbiAgICAgICAgY29uc3QgbW9kYWxfaW5zdGFuY2UgPSAkbW9kYWxfZWxlbWVudC5jb21wb25lbnQoJ1JzeF9Nb2RhbCcsIHt9KTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wb25lbnQgdG8gYmUgZnVsbHkgcmVhZHkgKERPTSBlbGVtZW50cyBxdWVyeWFibGUpXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBtb2RhbF9pbnN0YW5jZS5vbigncmVhZHknLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1tNb2RhbF0gQ29tcG9uZW50IHJlYWR5LCBlbGVtZW50czonLCB7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBtb2RhbF9pbnN0YW5jZS4kaWQoJ3RpdGxlJykubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBtb2RhbF9pbnN0YW5jZS4kaWQoJ2JvZHknKS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIGZvb3RlcjogbW9kYWxfaW5zdGFuY2UuJGlkKCdmb290ZXInKS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtb2RhbF9pbnN0YW5jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgbW9kYWwgYW5kIG1hbmFnZSBxdWV1ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9zaG93X21vZGFsKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9xdWV1ZS5wdXNoKHsgb3B0aW9ucywgcmVzb2x2ZSB9KTtcblxuICAgICAgICAgICAgLy8gUHJvY2VzcyBxdWV1ZSBpZiBubyBtb2RhbCBjdXJyZW50bHkgc2hvd2luZ1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc19xdWV1ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIHRoZSBtb2RhbCBxdWV1ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9wcm9jZXNzX3F1ZXVlKCkge1xuICAgICAgICBpZiAodGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIEhpZGUgYmFja2Ryb3Agd2hlbiBxdWV1ZSBpcyBlbXB0eVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5faGlkZV9iYWNrZHJvcCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyBvcHRpb25zLCByZXNvbHZlIH0gPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgIC8vIEVuc3VyZSBpbml0aWFsaXplZFxuICAgICAgICB0aGlzLl9pbml0KCk7XG5cbiAgICAgICAgLy8gU2hvdyBiYWNrZHJvcCBpZiBub3QgYWxyZWFkeSB2aXNpYmxlIChpbnN0YW50IC0gbm8gZGVsYXkgYmV0d2VlbiBtb2RhbHMpXG4gICAgICAgIGNvbnN0IGJhY2tkcm9wX3Zpc2libGUgPSB0aGlzLl9iYWNrZHJvcC5oYXNDbGFzcygnc2hvdycpO1xuICAgICAgICBpZiAoIWJhY2tkcm9wX3Zpc2libGUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX3Nob3dfYmFja2Ryb3AoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBkZWxheSBiZXR3ZWVuIHNlcXVlbnRpYWwgbW9kYWxzIC0gaW1tZWRpYXRlIHRyYW5zaXRpb25cblxuICAgICAgICAvLyBDcmVhdGUgbW9kYWwgaW5zdGFuY2VcbiAgICAgICAgY29uc3QgbW9kYWxfaW5zdGFuY2UgPSBhd2FpdCB0aGlzLl9jcmVhdGVfbW9kYWwoKTtcbiAgICAgICAgdGhpcy5fY3VycmVudCA9IG1vZGFsX2luc3RhbmNlO1xuXG4gICAgICAgIC8vIERldGVybWluZSBpZiB3ZSBzaG91bGQgYW5pbWF0ZSBiYXNlZCBvbjpcbiAgICAgICAgLy8gMS4gRGVza3RvcCB2aWV3cG9ydCAoPj0gMTAwMHB4KVxuICAgICAgICAvLyAyLiBNb3JlIHRoYW4gMSBzZWNvbmQgc2luY2UgbGFzdCBtb2RhbCBjbG9zZWRcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICAgICAgY29uc3QgaXNfZGVza3RvcCA9IHZpZXdwb3J0X3dpZHRoID49IDEwMDA7XG4gICAgICAgIGNvbnN0IHRpbWVfc2luY2VfbGFzdF9jbG9zZSA9IERhdGUubm93KCkgLSB0aGlzLl9sYXN0X2Nsb3NlX3RpbWVzdGFtcDtcbiAgICAgICAgY29uc3Qgc2hvdWxkX2FuaW1hdGUgPSBpc19kZXNrdG9wICYmIHRpbWVfc2luY2VfbGFzdF9jbG9zZSA+IDEwMDA7XG5cbiAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgd2FpdCBmb3IgcmVzdWx0IChtb2RhbCB3b24ndCBjcmVhdGUgaXRzIG93biBiYWNrZHJvcClcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbW9kYWxfaW5zdGFuY2Uuc2hvdyhvcHRpb25zLCB7IHNraXBfYmFja2Ryb3A6IHRydWUsIGFuaW1hdGU6IHNob3VsZF9hbmltYXRlIH0pO1xuXG4gICAgICAgIC8vIFJlY29yZCBjbG9zZSB0aW1lc3RhbXAgQkVGT1JFIHJlc29sdmluZyAoZW5zdXJlcyBpdCdzIHNldCBiZWZvcmUgbmV4dCBtb2RhbCBjYW4gc3RhcnQpXG4gICAgICAgIHRoaXMuX2xhc3RfY2xvc2VfdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcblxuICAgICAgICAvLyBSZXNvbHZlIHRoZSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdFxuICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG5cbiAgICAgICAgLy8gQ2xlYXIgY3VycmVudCBhbmQgcHJvY2VzcyBuZXh0XG4gICAgICAgIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9wcm9jZXNzX3F1ZXVlKCk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBTdGF0ZSBNYW5hZ2VtZW50IE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBtb2RhbCBpcyBjdXJyZW50bHkgb3BlblxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIHN0YXRpYyBpc19vcGVuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudCAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnRseSBvcGVuIG1vZGFsIGluc3RhbmNlXG4gICAgICogQHJldHVybnMge1JzeF9Nb2RhbHxudWxsfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfY3VycmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yY2UgY2xvc2UgdGhlIGN1cnJlbnQgbW9kYWxcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jdXJyZW50LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGx5IHZhbGlkYXRpb24gZXJyb3JzIHRvIHRoZSBjdXJyZW50IG1vZGFsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGVycm9ycyAtIEVycm9yIG9iamVjdCB7ZmllbGQ6IG1lc3NhZ2V9XG4gICAgICovXG4gICAgc3RhdGljIGFwcGx5X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQuYXBwbHlfZXJyb3JzKGVycm9ycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFNpbXBsZSBEaWFsb2cgTWV0aG9kc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGFuIGFsZXJ0IGRpYWxvZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gdGl0bGVfb3JfYm9keSAtIE1lc3NhZ2UgKGlmIG9ubHkgMSBhcmcpIG9yIFRpdGxlIChpZiAyIGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gYm9keSAtIE1lc3NhZ2UgYm9keSAoaWYgMiBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYnV0dG9uX2xhYmVsIC0gQnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiT0tcIilcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgYWxlcnQodGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGJ1dHRvbl9sYWJlbCA9ICdPSycpIHtcbiAgICAgICAgbGV0IHRpdGxlID0gJ05vdGljZSc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IG1lc3NhZ2UsXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogYnV0dG9uX2xhYmVsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tcHJpbWFyeScsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIGNvbmZpcm1hdGlvbiBkaWFsb2dcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IHRpdGxlX29yX2JvZHkgLSBNZXNzYWdlIChpZiAxLTIgYXJncykgb3IgVGl0bGUgKGlmIDMtNCBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGJvZHkgLSBNZXNzYWdlIGJvZHkgKG9wdGlvbmFsKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29uZmlybV9sYWJlbCAtIENvbmZpcm0gYnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiQ29uZmlybVwiKVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjYW5jZWxfbGFiZWwgLSBDYW5jZWwgYnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiQ2FuY2VsXCIpXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGNvbmZpcm0odGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGNvbmZpcm1fbGFiZWwgPSAnQ29uZmlybScsIGNhbmNlbF9sYWJlbCA9ICdDYW5jZWwnKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdDb25maXJtJztcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aXRsZV9vcl9ib2R5O1xuXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRpdGxlX29yX2JvZHk7XG4gICAgICAgICAgICBtZXNzYWdlID0gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogbWVzc2FnZSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjYW5jZWxfbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGNvbmZpcm1fbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0ID09PSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBwcm9tcHQgZGlhbG9nIGZvciB0ZXh0IGlucHV0XG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSB0aXRsZV9vcl9ib2R5IC0gTWVzc2FnZSAoaWYgMS0zIGFyZ3MpIG9yIFRpdGxlIChpZiA0IGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gYm9keSAtIE1lc3NhZ2UgYm9keSAob3B0aW9uYWwpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkZWZhdWx0X3ZhbHVlIC0gRGVmYXVsdCBpbnB1dCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbXVsdGlsaW5lIC0gU2hvdyB0ZXh0YXJlYSBpbnN0ZWFkIG9mIGlucHV0XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yIC0gT3B0aW9uYWwgZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IGFzIHZhbGlkYXRpb24gZmVlZGJhY2tcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmd8ZmFsc2U+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBwcm9tcHQodGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGRlZmF1bHRfdmFsdWUgPSAnJywgbXVsdGlsaW5lID0gZmFsc2UsIGVycm9yID0gbnVsbCkge1xuICAgICAgICBsZXQgdGl0bGUgPSAnSW5wdXQnO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IHRpdGxlX29yX2JvZHk7XG5cbiAgICAgICAgLy8gSGFuZGxlIG92ZXJsb2FkZWQgYXJndW1lbnRzXG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycgJiYgYm9keSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGVfb3JfYm9keTtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGlucHV0IGVsZW1lbnQgd2l0aCBtaW5pbXVtIHdpZHRoIGNvbnN0cmFpbnRzXG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IG11bHRpbGluZVxuICAgICAgICAgICAgPyAkKCc8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByb3dzPVwiNFwiIHN0eWxlPVwibWluLXdpZHRoOiAzMTVweDtcIj48L3RleHRhcmVhPicpXG4gICAgICAgICAgICA6ICQoJzxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgc3R5bGU9XCJtaW4td2lkdGg6IDI0NXB4O1wiPicpO1xuXG4gICAgICAgICRpbnB1dC52YWwoZGVmYXVsdF92YWx1ZSk7XG5cbiAgICAgICAgLy8gTWFyayBhcyBpbnZhbGlkIGlmIHRoZXJlJ3MgYW4gZXJyb3JcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAkaW5wdXQuYWRkQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBib2R5IHdpdGggbWVzc2FnZSBhbmQgaW5wdXRcbiAgICAgICAgbGV0ICRib2R5O1xuICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIGpRdWVyeSkge1xuICAgICAgICAgICAgLy8gSWYgbWVzc2FnZSBpcyBhIGpRdWVyeSBlbGVtZW50LCB1c2UgaXQgYXMgdGhlIGNvbnRhaW5lciBhbmQgYXBwZW5kIGlucHV0XG4gICAgICAgICAgICAkYm9keSA9IG1lc3NhZ2UuYXBwZW5kKCRpbnB1dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiBtZXNzYWdlIGlzIGEgc3RyaW5nLCBjcmVhdGUgd3JhcHBlciB3aXRoIHRleHQgYW5kIGlucHV0ICgzNnB4IHNwYWNpbmcpXG4gICAgICAgICAgICAkYm9keSA9ICQoJzxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+JykuYXBwZW5kKCQoJzxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAzNnB4O1wiPicpLnRleHQobWVzc2FnZSkpLmFwcGVuZCgkaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGVycm9yIG1lc3NhZ2UgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zdCAkZXJyb3IgPSAkKCc8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBkLWJsb2NrXCI+PC9kaXY+JykudGV4dChlcnJvcik7XG4gICAgICAgICAgICAkYm9keS5hcHBlbmQoJGVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogJGJvZHksXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0NhbmNlbCcsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdTdWJtaXQnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbnVsbCwgLy8gV2lsbCBiZSByZXBsYWNlZCBieSBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgICAgIG1heF93aWR0aDogNTAwLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBGb2N1cyBhbmQgc2VsZWN0IGlucHV0IGFmdGVyIG1vZGFsIHNob3dzXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAkaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgIGlmICghbXVsdGlsaW5lKSB7XG4gICAgICAgICAgICAgICAgJGlucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gZXJyb3IgZGlhbG9nIHdpdGggcmVkIGFsZXJ0IHN0eWxpbmdcbiAgICAgKlxuICAgICAqIENhbiBhcHBlYXIgb3ZlciBvdGhlciBtb2RhbHMgdG8gc2hvdyBjcml0aWNhbCB1bmNhdWdodCBleGNlcHRpb25zLlxuICAgICAqIFVzZWQgcHJpbWFyaWx5IGZvciBBamF4IGVycm9ycyB0aGF0IHdlcmVuJ3QgY2F1Z2h0IGJ5IGFwcGxpY2F0aW9uIGNvZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xFcnJvcnxPYmplY3R9IGVycm9yIC0gRXJyb3IgbWVzc2FnZSBzdHJpbmcsIEVycm9yIG9iamVjdCwgb3Igc3RydWN0dXJlZCBlcnJvclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSAtIE1vZGFsIHRpdGxlIChkZWZhdWx0OiBcIkVycm9yXCIpXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGVycm9yKGVycm9yLCB0aXRsZSA9ICdFcnJvcicpIHtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSAnJztcblxuICAgICAgICAvLyBIYW5kbGUgZGlmZmVyZW50IGVycm9yIHR5cGVzXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3I7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3IubWVzc2FnZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiBlcnJvci5lcnJvcikge1xuICAgICAgICAgICAgLy8gRmF0YWwgZXJyb3Igd2l0aCBkZXRhaWxzXG4gICAgICAgICAgICBjb25zdCBkZXRhaWxzID0gZXJyb3IuZXJyb3I7XG4gICAgICAgICAgICBpZiAoZGV0YWlscy5maWxlICYmIGRldGFpbHMubGluZSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgVW5jYXVnaHQgRmF0YWwgRXJyb3IgaW4gJHtkZXRhaWxzLmZpbGV9OiR7ZGV0YWlscy5saW5lfTpcXG5cXG4ke2RldGFpbHMuZXJyb3J9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGRldGFpbHMuZXJyb3IgfHwgJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWVzc2FnZSA9ICdBbiB1bmtub3duIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBlcnJvciBib2R5IHdpdGggcmVkIGFsZXJ0IHN0eWxpbmdcbiAgICAgICAgY29uc3QgJGJvZHkgPSAkKCc8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyIG1iLTBcIiByb2xlPVwiYWxlcnRcIj4nKS5hcHBlbmQoXG4gICAgICAgICAgICAkKCc8cHJlIGNsYXNzPVwibWItMFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IHByZS13cmFwOyB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7IGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7IGZvbnQtc2l6ZTogMC45ZW07XCI+JykudGV4dChcbiAgICAgICAgICAgICAgICBtZXNzYWdlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiAkYm9keSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQ2xvc2UnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tZGFuZ2VyJyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA2MDAsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gQ3VzdG9tIE1vZGFsIE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIGN1c3RvbSBtb2RhbCB3aXRoIHNwZWNpZmllZCBjb250ZW50IGFuZCBidXR0b25zXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgc2hvdyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgdGl0bGU6ICdNb2RhbCcsXG4gICAgICAgICAgICBib2R5OiAnJyxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtdLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA4MDAsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmaW5hbF9vcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9zaG93X21vZGFsKGZpbmFsX29wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBtb2RhbCB3aXRoIGEganFodG1sIGZvcm0gY29tcG9uZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jb21wb25lbnQgLSBDb21wb25lbnQgY2xhc3MgbmFtZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbXBvbmVudF9hcmdzIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gY29tcG9uZW50XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9ucy5vbl9zdWJtaXQgLSBDYWxsYmFjayBmdW5jdGlvbiBjYWxsZWQgb24gc3VibWl0LiBSZWNlaXZlcyBmb3JtIGNvbXBvbmVudCBpbnN0YW5jZS5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXR1cm4gZmFsc2UgdG8ga2VlcCBtb2RhbCBvcGVuLCBvciByZXR1cm4gZGF0YSB0byBjbG9zZSBhbmQgcmVzb2x2ZS5cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3R8ZmFsc2U+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBmb3JtKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgICAgICAgICB0aXRsZTogJ0Zvcm0nLFxuICAgICAgICAgICAgY29tcG9uZW50OiBudWxsLFxuICAgICAgICAgICAgY29tcG9uZW50X2FyZ3M6IHt9LFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA4MDAsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHN1Ym1pdF9sYWJlbDogJ1N1Ym1pdCcsXG4gICAgICAgICAgICBjYW5jZWxfbGFiZWw6ICdDYW5jZWwnLFxuICAgICAgICAgICAgb25fc3VibWl0OiBudWxsLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGZpbmFsX29wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKCFmaW5hbF9vcHRpb25zLmNvbXBvbmVudCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignTW9kYWwuZm9ybSgpIHJlcXVpcmVzIGEgY29tcG9uZW50Jyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgY29tcG9uZW50IGluc3RhbmNlXG4gICAgICAgIGxldCAkY29tcG9uZW50X2NvbnRhaW5lciA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIGxldCBjb21wb25lbnRfaW5zdGFuY2UgPSAkY29tcG9uZW50X2NvbnRhaW5lci5jb21wb25lbnQoZmluYWxfb3B0aW9ucy5jb21wb25lbnQsIGZpbmFsX29wdGlvbnMuY29tcG9uZW50X2FyZ3MpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIGNvbXBvbmVudCB0byBiZSByZWFkeVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29tcG9uZW50X2luc3RhbmNlLm9uKCdyZWFkeScsICgpID0+IHJlc29sdmUoKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZpbmQgYSBmb3JtIGluc3RhbmNlIGlmIGNvbXBvbmVudCBpbnN0YW5jZSBkb2VzbnQgaGF2ZSAudmFscygpXG4gICAgICAgIGlmICghY29tcG9uZW50X2luc3RhbmNlLnZhbHMpIHtcbiAgICAgICAgICAgIGxldCAkZm9ybSA9IGNvbXBvbmVudF9pbnN0YW5jZS4kLmZpbmQoJy5Sc3hfRm9ybScpO1xuICAgICAgICAgICAgaWYgKCRmb3JtLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50X2luc3RhbmNlID0gJGZvcm0uY29tcG9uZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgYnV0dG9uc1xuICAgICAgICBjb25zdCBidXR0b25zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiBmaW5hbF9vcHRpb25zLmNhbmNlbF9sYWJlbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IGZpbmFsX29wdGlvbnMuc3VibWl0X2xhYmVsLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXByaW1hcnknLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgb25fc3VibWl0IGNhbGxiYWNrIHByb3ZpZGVkLCB1c2UgaXRcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsX29wdGlvbnMub25fc3VibWl0ICYmIHR5cGVvZiBmaW5hbF9vcHRpb25zLm9uX3N1Ym1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluYWxfb3B0aW9ucy5vbl9zdWJtaXQoY29tcG9uZW50X2luc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybnMgbnVsbC91bmRlZmluZWQsIGtlZXAgbW9kYWwgb3BlblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSAoaW5jbHVkaW5nIGZhbHNlKSwgcmV0dXJuIHRoZSByZXN1bHQgdG8gY2xvc2UgbW9kYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBObyBvbl9zdWJtaXQgY2FsbGJhY2sgLSBnZXQgZm9ybSBkYXRhIGFuZCBjbG9zZSBtb2RhbFxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50X2luc3RhbmNlLnN1Ym1pdCAmJiB0eXBlb2YgY29tcG9uZW50X2luc3RhbmNlLnN1Ym1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNvbXBvbmVudF9pbnN0YW5jZS5zdWJtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21wb25lbnRfaW5zdGFuY2UudmFscyAmJiB0eXBlb2YgY29tcG9uZW50X2luc3RhbmNlLnZhbHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21wb25lbnRfaW5zdGFuY2UudmFscygpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdGb3JtIGNvbXBvbmVudCBoYXMgbm8gc3VibWl0KCkgb3IgdmFscygpIG1ldGhvZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogZmluYWxfb3B0aW9ucy50aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IGNvbXBvbmVudF9pbnN0YW5jZS4kLFxuICAgICAgICAgICAgYnV0dG9uczogYnV0dG9ucyxcbiAgICAgICAgICAgIG1heF93aWR0aDogZmluYWxfb3B0aW9ucy5tYXhfd2lkdGgsXG4gICAgICAgICAgICBjbG9zYWJsZTogZmluYWxfb3B0aW9ucy5jbG9zYWJsZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbiB1bmNsb3NhYmxlIG1vZGFsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlX29yX2JvZHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYm9keVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyB1bmNsb3NhYmxlKHRpdGxlX29yX2JvZHksIGJvZHkgPSBudWxsKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdQbGVhc2UgV2FpdCc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb24ndCB3YWl0IGZvciB0aGlzIHByb21pc2UgLSBpdCBuZXZlciByZXNvbHZlcyB1bnRpbCBjbG9zZWQgbWFudWFsbHlcbiAgICAgICAgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgYnV0dG9uczogW10sIC8vIE5vIGJ1dHRvbnNcbiAgICAgICAgICAgIGNsb3NhYmxlOiBmYWxzZSwgLy8gQ2FuJ3QgY2xvc2VcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIG5leHQgYW5pbWF0aW9uIGZyYW1lIGZvciBtb2RhbCB0byByZW5kZXJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBtb2RhbCB3aXRoIGN1c3RvbSBqUXVlcnkgY29udGVudFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGN1c3RvbShvcHRpb25zKSB7XG4gICAgICAgIC8vIEFsaWFzIGZvciBzaG93KCkgLSBzYW1lIGZ1bmN0aW9uYWxpdHlcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2hvdyhvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIEhlbHBlciBNZXRob2RzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gZXJyb3IgYWxlcnRcbiAgICAgKiBAcGFyYW0geyp9IGVycm9yc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBlcnJvcihlcnJvcnMsIHRpdGxlID0gJ0Vycm9yJykge1xuICAgICAgICBsZXQgbWVzc2FnZSA9ICdBbiBlcnJvciBvY2N1cnJlZCc7XG5cbiAgICAgICAgLy8gSGFuZGxlIHZhcmlvdXMgZXJyb3IgZm9ybWF0c1xuICAgICAgICBpZiAodHlwZW9mIGVycm9ycyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcnM7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3JzICYmICdyZXNwb25zZUpTT04nIGluIGVycm9ycyAmJiAnbWVzc2FnZScgaW4gZXJyb3JzLnJlc3BvbnNlSlNPTikge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9ycy5yZXNwb25zZUpTT04ubWVzc2FnZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvcnMgJiYgJ21lc3NhZ2UnIGluIGVycm9ycykge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9ycy5tZXNzYWdlO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9ycyAmJiB0eXBlb2YgZXJyb3JzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIGZvcm1hdCBlcnJvciBvYmplY3RcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX21lc3NhZ2VzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoZXJyb3JzW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2VzLnB1c2goZXJyb3JzW2tleV1bMF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2VzLnB1c2goZXJyb3JzW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlcnJvcl9tZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yX21lc3NhZ2VzLmpvaW4oJ1xcbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgaWNvbjogJ2V4Y2xhbWF0aW9uLWNpcmNsZScsXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ09LJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLWRhbmdlcicsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVvcGVuIGN1cnJlbnQgbW9kYWwgd2l0aCB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBlcnJvcnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgcmVvcGVuX3dpdGhfZXJyb3JzKGVycm9ycykge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudCkge1xuICAgICAgICAgICAgLy8gTW9kYWwgaXMgc3RpbGwgb3BlbiwganVzdCBhcHBseSBlcnJvcnNcbiAgICAgICAgICAgIHRoaXMuYXBwbHlfZXJyb3JzKGVycm9ycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ05vIG1vZGFsIG9wZW4gdG8gYXBwbHkgZXJyb3JzIHRvJyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBCcmVhZGNydW1iX0l0ZW0gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIFJlYWQgaHJlZiBmcm9tIEhUTUwgYXR0cmlidXRlIGlmIHByZXNlbnRcbiAgICAgICAgY29uc3QgaHJlZiA9IHRoaXMuJC5hdHRyKCdocmVmJyk7XG4gICAgICAgIGlmIChocmVmKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuaHJlZiA9IGhyZWY7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWFkIGFjdGl2ZSBmcm9tIEhUTUwgYXR0cmlidXRlIGlmIHByZXNlbnRcbiAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy4kLmF0dHIoJ2FjdGl2ZScpO1xuICAgICAgICBpZiAoYWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdhcmlhLWN1cnJlbnQnLCAncGFnZScpO1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUF0dHIoJ2FjdGl2ZScpOyAvLyBSZW1vdmUgdGhlIGF0dHJpYnV0ZSBhZnRlciByZWFkaW5nXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBDbGllbnRfTGFiZWxfTGluayBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gbnVsbDtcblxuICAgICAgICAvLyBDb252ZXJ0IGNsaWVudF9pZCB0byBudW1iZXIgaWYgaXQncyBhIG51bWVyaWMgc3RyaW5nXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSh0aGlzLmFyZ3MuY2xpZW50X2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY2xpZW50IGRhdGEgaWYgd2UgaGF2ZSBhbiBJRFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsaWVudF9pZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50KHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmFyZ3MuY2xpZW50X2lkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNsaWVudDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZW5kZXIoKSB7XG4gICAgICAgIC8vIFNldCBocmVmIGR5bmFtaWNhbGx5IGFmdGVyIGVhY2ggcmVuZGVyXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICBjb25zdCBocmVmID0gUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXInLCAndmlldycsIHRoaXMuYXJncy5jbGllbnRfaWQpO1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2hyZWYnLCBocmVmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdocmVmJywgJyMnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgdGhlIGNsaWVudF9pZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbY2xpZW50X2lkXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBjbGllbnRfaWQgYW5kIHJlbG9hZHNcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBDdXJyZW50IGNsaWVudF9pZCB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwoY2xpZW50X2lkKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3MuY2xpZW50X2lkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gdXBkYXRlIGNsaWVudF9pZCBhbmQgcmVsb2FkXG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZShjbGllbnRfaWQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNsaWVudCA9IG51bGw7XG5cbiAgICAgICAgICAgIC8vIFJlbG9hZCBjbGllbnQgZGF0YSBhbmQgcmUtcmVuZGVyIChvbl9yZW5kZXIgd2lsbCB1cGRhdGUgaHJlZilcbiAgICAgICAgICAgIHRoaXMub25fbG9hZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENsaWVudF9MYWJlbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gbnVsbDtcblxuICAgICAgICAvLyBDb252ZXJ0IGNsaWVudF9pZCB0byBudW1iZXIgaWYgaXQncyBhIG51bWVyaWMgc3RyaW5nXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSh0aGlzLmFyZ3MuY2xpZW50X2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY2xpZW50IGRhdGEgaWYgd2UgaGF2ZSBhbiBJRFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsaWVudF9pZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50KHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmFyZ3MuY2xpZW50X2lkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNsaWVudDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3Igc2V0IHRoZSBjbGllbnRfaWRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2NsaWVudF9pZF0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgY2xpZW50X2lkIGFuZCByZWxvYWRzXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ3VycmVudCBjbGllbnRfaWQgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKGNsaWVudF9pZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcmdzLmNsaWVudF9pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSBjbGllbnRfaWQgYW5kIHJlbG9hZFxuICAgICAgICAgICAgdGhpcy5hcmdzLmNsaWVudF9pZCA9IHZhbHVlX3VubGVzc19udW1lcmljX3N0cmluZ190aGVuX251bWVyaWNfdmFsdWUoY2xpZW50X2lkKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBudWxsO1xuXG4gICAgICAgICAgICAvLyBSZWxvYWQgY2xpZW50IGRhdGEgYW5kIHJlLXJlbmRlciAob25fcmVuZGVyIHdpbGwgdXBkYXRlIGhyZWYpXG4gICAgICAgICAgICB0aGlzLm9uX2xvYWQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fSW5wdXRfQWJzdHJhY3QgLSBCYXNlIGNsYXNzIGZvciBhbGwgZm9ybSBpbnB1dCB3aWRnZXRzXG4gKlxuICogRGVmaW5lcyB0aGUgaW50ZXJmYWNlIHRoYXQgYWxsIGZvcm0gd2lkZ2V0cyBtdXN0IGltcGxlbWVudC5cbiAqIFRoaXMgZW5zdXJlcyBjb25zaXN0ZW5jeSBhY3Jvc3MgYWxsIGlucHV0IHR5cGVzICh0ZXh0LCBzZWxlY3QsIHd5c2l3eWcsIGV0Yy4pXG4gKlxuICogUkVRVUlSRUQgTUVUSE9EUyAobXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzKTpcbiAqIC0gdmFsKCkgLSBHZXQgY3VycmVudCB2YWx1ZSAobm8gYXJndW1lbnRzKVxuICogLSB2YWwodmFsdWUpIC0gU2V0IHZhbHVlIChvbmUgYXJndW1lbnQpXG4gKiAtIHNlZWQoKSAtIEZpbGxzIHRoZSB3aWRnZXQgd2l0aCByYW5kb20gdGVzdCBkYXRhIChvcHRpb25hbClcbiAqXG4gKiBBbGwgd2lkZ2V0cyBtdXN0OlxuICogLSBIYXZlIC5XaWRnZXQgQ1NTIGNsYXNzXG4gKiAtIEhhdmUgZGF0YS1uYW1lIGF0dHJpYnV0ZSBzZXQgYnkgRm9ybV9GaWVsZFxuICovXG5jbGFzcyBGb3JtX0lucHV0X0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICogU3ViY2xhc3NlcyBNVVNUIGltcGxlbWVudCB0aGlzIG1ldGhvZFxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlLiBJZiBvbWl0dGVkLCByZXR1cm5zIHRoZSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHZhbCgpIGdldHRlcmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSBtdXN0IGltcGxlbWVudCB2YWwodmFsdWUpIHNldHRlcmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlZCAtIEZpbGwgd2l0aCByYW5kb20gdGVzdCBkYXRhIChvcHRpb25hbClcbiAgICAgKiBTdWJjbGFzc2VzIE1BWSBpbXBsZW1lbnQgdGhpcyBtZXRob2RcbiAgICAgKi9cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICAvLyBPcHRpb25hbCAtIHdpZGdldHMgY2FuIG92ZXJyaWRlIGlmIHRoZXkgc3VwcG9ydCBzZWVkaW5nXG4gICAgfVxufVxuIiwiY2xhc3MgVGV4dF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBpbnB1dCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlclxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodGhpcy5kYXRhLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2VlZGVyKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgUnN4X1JhbmRvbV9WYWx1ZXMgZW5kcG9pbnRcbiAgICAgICAgICAgIC8vIGxldCB2YWx1ZSA9IGF3YWl0IFJzeF9SYW5kb21fVmFsdWVzW3RoaXMuYXJncy5zZWVkZXJdKCk7XG4gICAgICAgICAgICAvLyBGb3Igbm93LCBqdXN0IHVzZSBwbGFjZWhvbGRlciB0ZXh0XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSAnVGVzdCAnICsgKHRoaXMuYXJncy5zZWVkZXIgfHwgJ1ZhbHVlJyk7XG4gICAgICAgICAgICB0aGlzLnZhbCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBDaGVja2JveF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmNoZWNrZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGVja2VkX3ZhbHVlID0gdGhpcy5hcmdzLmNoZWNrZWRfdmFsdWUgfHwgJzEnO1xuICAgICAgICB0aGlzLnVuY2hlY2tlZF92YWx1ZSA9IHRoaXMuYXJncy51bmNoZWNrZWRfdmFsdWUgfHwgJzAnO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDb25uZWN0IGxhYmVsIGNsaWNrcyB0byBjaGVja2JveFxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgY29uc3QgJGxhYmVsID0gdGhpcy4kaWQoJ2xhYmVsJyk7XG5cbiAgICAgICAgaWYgKCRsYWJlbC5leGlzdHMoKSkge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRfaWQgPSAkaW5wdXQuYXR0cignaWQnKTtcbiAgICAgICAgICAgICRsYWJlbC5hdHRyKCdmb3InLCBpbnB1dF9pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGNoZWNrYm94IHN0YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Ym9vbGVhbn0gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBjaGVja2VkIHN0YXRlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNoZWNrZWRfdmFsdWUgb3IgdW5jaGVja2VkX3ZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBjb25zdCBpc19jaGVja2VkID0gdGhpcy4kaWQoJ2lucHV0JykucHJvcCgnY2hlY2tlZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGlzX2NoZWNrZWQgPyB0aGlzLmNoZWNrZWRfdmFsdWUgOiB0aGlzLnVuY2hlY2tlZF92YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGFjY2VwdHMgYm9vbGVhbiwgY2hlY2tlZF92YWx1ZSwgb3IgdW5jaGVja2VkX3ZhbHVlXG4gICAgICAgICAgICBsZXQgc2hvdWxkX2NoZWNrID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICAgIHNob3VsZF9jaGVjayA9IHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gdGhpcy5jaGVja2VkX3ZhbHVlIHx8IHZhbHVlID09PSAnMScgfHwgdmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBzaG91bGRfY2hlY2sgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmRhdGEuY2hlY2tlZCA9IHNob3VsZF9jaGVjaztcbiAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnByb3AoJ2NoZWNrZWQnLCBzaG91bGRfY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgLy8gUmFuZG9tbHkgY2hlY2sgb3IgdW5jaGVja1xuICAgICAgICB0aGlzLnZhbChNYXRoLnJhbmRvbSgpID4gMC41KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFd5c2l3eWdfSW5wdXQgLSBXWVNJV1lHIGVkaXRvciB3aWRnZXQgdXNpbmcgUXVpbGxcbiAqXG4gKiBJbXBsZW1lbnRzIHRoZSBmb3JtIHdpZGdldCBpbnRlcmZhY2U6XG4gKiAtIHZhbCgpIC0gR2V0L3NldCBIVE1MIGNvbnRlbnRcbiAqIC0gc2VlZCgpIC0gRmlsbHMgd2l0aCByYW5kb20gY29udGVudFxuICovXG5jbGFzcyBXeXNpd3lnX0lucHV0IGV4dGVuZHMgRm9ybV9JbnB1dF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLnF1aWxsID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV2FpdCBmb3IgUXVpbGwgdG8gYmUgbG9hZGVkLCB0aGVuIGluaXRpYWxpemVcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHF1aWxsX3JlYWR5KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhhdC5faW5pdGlhbGl6ZV9xdWlsbCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfaW5pdGlhbGl6ZV9xdWlsbCgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBRdWlsbCBlZGl0b3JcbiAgICAgICAgdGhpcy5xdWlsbCA9IG5ldyBRdWlsbCh0aGlzLiRpZCgnZWRpdG9yJylbMF0sIHtcbiAgICAgICAgICAgIHRoZW1lOiAnc25vdycsXG4gICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdFbnRlciB0ZXh0Li4uJyxcbiAgICAgICAgICAgIG1vZHVsZXM6IHtcbiAgICAgICAgICAgICAgICB0b29sYmFyOiBbXG4gICAgICAgICAgICAgICAgICAgIFt7ICdoZWFkZXInOiBbMSwgMiwgMywgZmFsc2VdIH1dLFxuICAgICAgICAgICAgICAgICAgICBbJ2JvbGQnLCAnaXRhbGljJywgJ3VuZGVybGluZScsICdzdHJpa2UnXSxcbiAgICAgICAgICAgICAgICAgICAgWydibG9ja3F1b3RlJywgJ2NvZGUtYmxvY2snXSxcbiAgICAgICAgICAgICAgICAgICAgW3sgJ2xpc3QnOiAnb3JkZXJlZCd9LCB7ICdsaXN0JzogJ2J1bGxldCcgfV0sXG4gICAgICAgICAgICAgICAgICAgIFt7ICdpbmRlbnQnOiAnLTEnfSwgeyAnaW5kZW50JzogJysxJyB9XSxcbiAgICAgICAgICAgICAgICAgICAgWydsaW5rJywgJ2ltYWdlJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnY2xlYW4nXVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIGhpZGRlbiBpbnB1dCBvbiB0ZXh0IGNoYW5nZVxuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgdGhpcy5xdWlsbC5vbigndGV4dC1jaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHRoYXQuJGlkKCdoaWRkZW5faW5wdXQnKS52YWwodGhhdC5xdWlsbC5yb290LmlubmVySFRNTCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCBIVE1MIGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBIVE1MIGNvbnRlbnRcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgSFRNTCBjb250ZW50IHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybiAnJztcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnF1aWxsLnJvb3QuaW5uZXJIVE1MO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHtcbiAgICAgICAgICAgICAgICAvLyBRdWlsbCBub3QgcmVhZHkgeWV0LCB3YWl0IGFuZCB0cnkgYWdhaW5cbiAgICAgICAgICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoYXQudmFsKHZhbHVlKSwgMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucXVpbGwucm9vdC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaGlkZGVuX2lucHV0JykudmFsKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZWQgLSBGaWxsIHdpdGggcmFuZG9tIGNvbnRlbnQgZm9yIHRlc3RpbmdcbiAgICAgKi9cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybjtcblxuICAgICAgICBjb25zdCBzYW1wbGVfY29udGVudCA9IGBcbiAgICAgICAgICAgIDxoMj5TYW1wbGUgSGVhZGluZzwvaDI+XG4gICAgICAgICAgICA8cD5UaGlzIGlzIGEgc2FtcGxlIHBhcmFncmFwaCB3aXRoIDxzdHJvbmc+Ym9sZCB0ZXh0PC9zdHJvbmc+IGFuZCA8ZW0+aXRhbGljIHRleHQ8L2VtPi48L3A+XG4gICAgICAgICAgICA8dWw+XG4gICAgICAgICAgICAgICAgPGxpPkZpcnN0IGJ1bGxldCBwb2ludDwvbGk+XG4gICAgICAgICAgICAgICAgPGxpPlNlY29uZCBidWxsZXQgcG9pbnQ8L2xpPlxuICAgICAgICAgICAgICAgIDxsaT5UaGlyZCBidWxsZXQgcG9pbnQ8L2xpPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDxwPkFub3RoZXIgcGFyYWdyYXBoIHdpdGggPGEgaHJlZj1cIiNcIj5hIHNhbXBsZSBsaW5rPC9hPi48L3A+XG4gICAgICAgIGA7XG5cbiAgICAgICAgdGhpcy52YWwoc2FtcGxlX2NvbnRlbnQpO1xuICAgIH1cbn1cbiIsImNsYXNzIFNlbGVjdF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG5cbiAgICAgICAgLy8gUGFyc2Ugb3B0aW9ucyBpZiBwYXNzZWQgYXMgSlNPTiBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmFyZ3Mub3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gRGVjb2RlIEhUTUwgZW50aXRpZXMgYmVmb3JlIHBhcnNpbmcgSlNPTlxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaGFuZGxlcyBjYXNlcyB3aGVyZSBKU09OIGlzIHBhc3NlZCB0aHJvdWdoIEJsYWRlIHshISAhIX0gc3ludGF4XG4gICAgICAgICAgICAgICAgY29uc3QgZGVjb2RlZCA9ICQoJzx0ZXh0YXJlYT4nKS5odG1sKHRoaXMuYXJncy5vcHRpb25zKS50ZXh0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9wdGlvbnMgPSBqc29uX2RlY29kZShkZWNvZGVkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gcGFyc2Ugb3B0aW9ucyBKU09OOicsIGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vcHRpb25zID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb252ZXJ0IG9iamVjdCBvcHRpb25zIHRvIGFycmF5IGZvcm1hdFxuICAgICAgICBpZiAodGhpcy5hcmdzLm9wdGlvbnMgJiYgdHlwZW9mIHRoaXMuYXJncy5vcHRpb25zID09PSAnb2JqZWN0JyAmJiAhaXNfYXJyYXkodGhpcy5hcmdzLm9wdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub3B0aW9ucyA9IE9iamVjdC5lbnRyaWVzKHRoaXMuYXJncy5vcHRpb25zKS5tYXAoKFt2YWx1ZSwgbGFiZWxdKSA9PiAoe3ZhbHVlLCBsYWJlbH0pKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIFRvbSBTZWxlY3RcbiAgICAgICAgbGV0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycsXG4gICAgICAgICAgICBhbGxvd0VtcHR5T3B0aW9uOiB0cnVlLFxuICAgICAgICAgICAgY3JlYXRlOiBmYWxzZSxcbiAgICAgICAgICAgIG1heE9wdGlvbnM6IG51bGwsICAvLyBTaG93IGFsbCBvcHRpb25zIChkZWZhdWx0IGlzIDUwKVxuICAgICAgICAgICAgcGx1Z2luczogWydkcm9wZG93bl9pbnB1dCddLCAgLy8gRW5hYmxlIHNlYXJjaCBpbiBkcm9wZG93blxuICAgICAgICAgICAgb25Jbml0aWFsaXplOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAvLyBLZWVwIEJvb3RzdHJhcCBmb3JtLXNlbGVjdCBjbGFzc1xuICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5jbGFzc0xpc3QuYWRkKCdmb3JtLXNlbGVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMudG9tX3NlbGVjdCA9IG5ldyBUb21TZWxlY3QodGhpcy4kaWQoJ2lucHV0JykuZ2V0KDApLCBjb25maWcpO1xuXG4gICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmRhdGEudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBzZWxlY3RlZCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b21fc2VsZWN0LmdldFZhbHVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh0aGlzLmRhdGEudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zZWVkZXIpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IEltcGxlbWVudCBSc3hfUmFuZG9tX1ZhbHVlcyBlbmRwb2ludFxuICAgICAgICAgICAgbGV0IHZhbHVlID0gJ1Rlc3QgJyArICh0aGlzLmFyZ3Muc2VlZGVyIHx8ICdWYWx1ZScpO1xuICAgICAgICAgICAgdGhpcy52YWwodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5vcHRpb25zICYmIHRoaXMuYXJncy5vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIFNlbGVjdCByYW5kb20gb3B0aW9uXG4gICAgICAgICAgICBsZXQgcmFuZG9tX2luZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdGhpcy5hcmdzLm9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgICAgIGxldCByYW5kb21fb3B0ID0gdGhpcy5hcmdzLm9wdGlvbnNbcmFuZG9tX2luZGV4XTtcbiAgICAgICAgICAgIGxldCByYW5kb21fdmFsdWUgPSB0eXBlb2YgcmFuZG9tX29wdCA9PT0gJ29iamVjdCcgPyByYW5kb21fb3B0LnZhbHVlIDogcmFuZG9tX29wdDtcbiAgICAgICAgICAgIHRoaXMudmFsKHJhbmRvbV92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9kZXN0cm95KCkge1xuICAgICAgICAvLyBDbGVhbiB1cCBUb20gU2VsZWN0IGluc3RhbmNlXG4gICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBamF4X1NlbGVjdF9JbnB1dCBleHRlbmRzIFNlbGVjdF9JbnB1dCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIGVtcHR5IHNlbGVjdCB2YWx1ZXMgYXJyYXlcbiAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbXTtcblxuICAgICAgICAvLyBTdG9yZSBmb3IgdmFsdWUgc2V0IGJlZm9yZSBpbml0aWFsaXphdGlvbiBjb21wbGV0ZXNcbiAgICAgICAgdGhpcy5fcGVuZGluZ192YWx1ZSA9IG51bGw7XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gZG8gYmFzaWMgc2V0dXBcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBvcHRpb25zIGZyb20gQWpheCBlbmRwb2ludCBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGEpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgZXJyb3IhIHN0YXR1czogJHtyZXNwb25zZS5zdGF0dXN9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBkYXRhO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCBzZWxlY3Qgb3B0aW9uczonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBpbml0aWFsaXplIFRvbSBTZWxlY3RcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICAvLyBJZiBhIHZhbHVlIHdhcyBzZXQgYmVmb3JlIGluaXRpYWxpemF0aW9uLCBhcHBseSBpdCBub3dcbiAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdfdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3Quc2V0VmFsdWUodGhpcy5fcGVuZGluZ192YWx1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKHRoaXMuX3BlbmRpbmdfdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdGhpcy5fcGVuZGluZ192YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdfdmFsdWUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBzZWxlY3RlZCB2YWx1ZVxuICAgICAqIEhhbmRsZXMgY2FsbHMgYmVmb3JlIFRvbSBTZWxlY3QgaW5pdGlhbGl6YXRpb24gY29tcGxldGVzXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudCB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemVkIC0gZ2V0IGZyb20gVG9tIFNlbGVjdFxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvbV9zZWxlY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGVuZGluZ192YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIE5vdCB5ZXQgaW5pdGlhbGl6ZWQgLSByZXR1cm4gcGVuZGluZyB2YWx1ZVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wZW5kaW5nX3ZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRhdGEudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gZGF0YSB2YWx1ZVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGEudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplZCAtIHNldCB2aWEgVG9tIFNlbGVjdFxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBOb3QgeWV0IGluaXRpYWxpemVkIC0gc3RvcmUgZm9yIGxhdGVyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGVuZGluZ192YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqXG4gKiBDdXJyZW5jeV9JbnB1dFxuICpcbiAqIEV4dGVuZHMgVGV4dF9JbnB1dCB0byBwcm92aWRlIGF1dG9tYXRpYyBjdXJyZW5jeSBmb3JtYXR0aW5nLlxuICpcbiAqIEZlYXR1cmVzOlxuICogLSBBZGRzIHRob3VzYW5kcyBzZXBhcmF0b3JzIChjb21tYXMpIGV2ZXJ5IDMgZGlnaXRzXG4gKiAtIE9wdGlvbmFsIGN1cnJlbmN5IHN5bWJvbCBwcmVmaXggKGRlZmF1bHQ6IGhpZGRlbilcbiAqIC0gT3B0aW9uYWwgZGVjaW1hbCBzdXBwb3J0IChkZWZhdWx0OiBkaXNhYmxlZClcbiAqIC0gU21hcnQgYmFja3NwYWNlIG92ZXIgZm9ybWF0dGluZyBjaGFyYWN0ZXJzXG4gKiAtIE5vIG1pZC1zdHJpbmcgZm9ybWF0dGluZyAod2FpdHMgZm9yIGJsdXIpXG4gKlxuICogQXJndW1lbnRzOlxuICogLSAkYWxsb3dfZGVjaW1hbHMgLSBBbGxvdyAyIGRlY2ltYWwgcGxhY2VzIChkZWZhdWx0OiBmYWxzZSlcbiAqIC0gJHNob3dfc3ltYm9sIC0gU2hvdyBjdXJyZW5jeSBzeW1ib2wgKGRlZmF1bHQ6IGZhbHNlKVxuICogLSAkY3VycmVuY3lfc3ltYm9sIC0gQ3VycmVuY3kgc3ltYm9sIHRvIHVzZSAoZGVmYXVsdDogXCIkXCIpXG4gKlxuICogVXNhZ2U6XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAvPlxuICogICA8Q3VycmVuY3lfSW5wdXQgJHNob3dfc3ltYm9sPXRydWUgLz5cbiAqICAgPEN1cnJlbmN5X0lucHV0ICRhbGxvd19kZWNpbWFscz10cnVlIC8+XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAkc2hvd19zeW1ib2w9dHJ1ZSAkYWxsb3dfZGVjaW1hbHM9dHJ1ZSAkY3VycmVuY3lfc3ltYm9sPVwi4oKsXCIgLz5cbiAqXG4gKiBCZWhhdmlvcjpcbiAqIC0gVHlwZSBcIjEyMzQ1NjdcIiAtPiBkaXNwbGF5cyBcIjEsMjM0LDU2N1wiLCB2YWwoKSByZXR1cm5zIFwiMTIzNDU2N1wiXG4gKiAtIFR5cGUgXCIxMjM0NTY3Ljg5XCIgKHdpdGggZGVjaW1hbHMpIC0+IGRpc3BsYXlzIFwiMSwyMzQsNTY3Ljg5XCIsIHZhbCgpIHJldHVybnMgXCIxMjM0NTY3Ljg5XCJcbiAqIC0gV2l0aCBzeW1ib2w6IGRpc3BsYXlzIFwiJDEsMjM0LDU2N1wiLCB2YWwoKSBzdGlsbCByZXR1cm5zIFwiMTIzNDU2N1wiXG4gKi9cbmNsYXNzIEN1cnJlbmN5X0lucHV0IGV4dGVuZHMgVGV4dF9JbnB1dCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcblxuICAgICAgICAvLyBTZXQgZGVmYXVsdHMgZm9yIG9wdGlvbnNcbiAgICAgICAgaWYgKHRoaXMuYXJncy5hbGxvd19kZWNpbWFscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5zaG93X3N5bWJvbCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgPSAnJCc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JtYXQgY3VycmVuY3kgd2l0aCBjb21tYXMgYW5kIG9wdGlvbmFsIHN5bWJvbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIE51bWVyaWMgdmFsdWUgKG1heSBpbmNsdWRlIGRlY2ltYWwpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRm9ybWF0dGVkIGN1cnJlbmN5IHN0cmluZ1xuICAgICAqL1xuICAgIF9mb3JtYXRfY3VycmVuY3kodmFsdWUpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3BsaXQgaW50byBpbnRlZ2VyIGFuZCBkZWNpbWFsIHBhcnRzXG4gICAgICAgIGxldCBwYXJ0cyA9IHZhbHVlLnNwbGl0KCcuJyk7XG4gICAgICAgIGxldCBpbnRlZ2VyX3BhcnQgPSBwYXJ0c1swXTtcbiAgICAgICAgbGV0IGRlY2ltYWxfcGFydCA9IHBhcnRzWzFdO1xuXG4gICAgICAgIC8vIEFkZCBjb21tYXMgdG8gaW50ZWdlciBwYXJ0XG4gICAgICAgIGludGVnZXJfcGFydCA9IGludGVnZXJfcGFydC5yZXBsYWNlKC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLCAnLCcpO1xuXG4gICAgICAgIC8vIFJlY29uc3RydWN0IHdpdGggZGVjaW1hbCBpZiBhbGxvd2VkXG4gICAgICAgIGxldCBmb3JtYXR0ZWQgPSBpbnRlZ2VyX3BhcnQ7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMgJiYgZGVjaW1hbF9wYXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIExpbWl0IHRvIDIgZGVjaW1hbCBwbGFjZXNcbiAgICAgICAgICAgIGRlY2ltYWxfcGFydCA9IGRlY2ltYWxfcGFydC5zdWJzdHIoMCwgMik7XG4gICAgICAgICAgICBmb3JtYXR0ZWQgKz0gJy4nICsgZGVjaW1hbF9wYXJ0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1cnJlbmN5IHN5bWJvbCBpZiBlbmFibGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2hvd19zeW1ib2wpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZCA9IHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgKyBmb3JtYXR0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ybWF0dGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgbnVtZXJpYyB2YWx1ZSBmcm9tIGZvcm1hdHRlZCBzdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0dGVkIC0gRm9ybWF0dGVkIGN1cnJlbmN5IHN0cmluZ1xuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IENsZWFuIG51bWVyaWMgdmFsdWUgKGRpZ2l0cyBhbmQgZGVjaW1hbCBvbmx5KVxuICAgICAqL1xuICAgIF9nZXRfbnVtZXJpY192YWx1ZShmb3JtYXR0ZWQpIHtcbiAgICAgICAgaWYgKCFmb3JtYXR0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSBjdXJyZW5jeSBzeW1ib2wgYW5kIGNvbW1hc1xuICAgICAgICBsZXQgY2xlYW5lZCA9IGZvcm1hdHRlZC5yZXBsYWNlKC9bXjAtOS5dL2csICcnKTtcblxuICAgICAgICAvLyBFbnN1cmUgb25seSBvbmUgZGVjaW1hbCBwb2ludFxuICAgICAgICBjb25zdCBkZWNpbWFsX2NvdW50ID0gKGNsZWFuZWQubWF0Y2goL1xcLi9nKSB8fCBbXSkubGVuZ3RoO1xuICAgICAgICBpZiAoZGVjaW1hbF9jb3VudCA+IDEpIHtcbiAgICAgICAgICAgIC8vIEtlZXAgb25seSBmaXJzdCBkZWNpbWFsIHBvaW50XG4gICAgICAgICAgICBjb25zdCBmaXJzdF9kZWNpbWFsID0gY2xlYW5lZC5pbmRleE9mKCcuJyk7XG4gICAgICAgICAgICBjbGVhbmVkID0gY2xlYW5lZC5zdWJzdHIoMCwgZmlyc3RfZGVjaW1hbCArIDEpICsgY2xlYW5lZC5zdWJzdHIoZmlyc3RfZGVjaW1hbCArIDEpLnJlcGxhY2UoL1xcLi9nLCAnJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2xlYW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGN1cnJlbmN5IHZhbHVlXG4gICAgICogR2V0dGVyIHJldHVybnMgbnVtZXJpYyBzdHJpbmcgKG5vIGNvbW1hcywgbm8gc3ltYm9sKVxuICAgICAqIFNldHRlciBhY2NlcHRzIGFueXRoaW5nIGFuZCBmb3JtYXRzIHdpdGggY29tbWFzL3N5bWJvbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHJldHVybiBudW1lcmljIHZhbHVlIG9ubHlcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9IHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXIgLSBmb3JtYXQgYW5kIGRpc3BsYXlcbiAgICAgICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDbGVhbiB0aGUgaW5wdXQgdmFsdWVcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShzdHIodmFsdWUpKTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShudW1lcmljKTtcblxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKGZvcm1hdHRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICAvLyBIYW5kbGUga2V5ZG93biB0byBpbnRlcmNlcHQgYmFja3NwYWNlIGF0IGVuZCBvZiBzdHJpbmdcbiAgICAgICAgJGlucHV0Lm9uKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgYmFja3NwYWNlIGtleVxuICAgICAgICAgICAgaWYgKGUua2V5ICE9PSAnQmFja3NwYWNlJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaW5wdXRfZWxlbWVudCA9ICRpbnB1dFswXTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9wb3MgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX2VuZCA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uRW5kO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVfbGVuZ3RoID0gcmF3Lmxlbmd0aDtcblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgaWYgY3Vyc29yIGlzIGF0IHRoZSBlbmQgYW5kIG5vIHNlbGVjdGlvblxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCAmJiBjdXJzb3JfcG9zID09PSBjdXJzb3JfZW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm9uLW51bWVyaWNcbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcl9iZWZvcmUgPSByYXcuY2hhckF0KGN1cnNvcl9wb3MgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEvWzAtOV0vLnRlc3QoY2hhcl9iZWZvcmUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGFyYWN0ZXIgYmVmb3JlIGN1cnNvciBpcyBub3QgYSBkaWdpdFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBsYXN0IGRpZ2l0IGluc3RlYWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVtZXJpYy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGxhc3QgY2hhcmFjdGVyIGZyb20gbnVtZXJpYyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19udW1lcmljID0gbnVtZXJpYy5zdWJzdHIoMCwgbnVtZXJpYy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobmV3X251bWVyaWMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIGN1cnNvciBhdCBlbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2xlbmd0aCA9ICRpbnB1dC52YWwoKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3X2xlbmd0aCwgbmV3X2xlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBpbnB1dCBldmVudCBmb3IgbGl2ZSBmb3JtYXR0aW5nXG4gICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICBjb25zdCBpbnB1dF9lbGVtZW50ID0gJGlucHV0WzBdO1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX3BvcyA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZV9sZW5ndGggPSByYXcubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGFwcGx5IGxpdmUgZm9ybWF0dGluZyBpZiBjdXJzb3IgaXMgYXQgdGhlIGVuZFxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgbnVtZXJpYyB2YWx1ZVxuICAgICAgICAgICAgICAgIGxldCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcblxuICAgICAgICAgICAgICAgIC8vIExpbWl0IGRlY2ltYWwgcGxhY2VzIHRvIDIgaWYgZGVjaW1hbHMgYWxsb3dlZFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydHMgPSBudW1lcmljLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0c1sxXSAmJiBwYXJ0c1sxXS5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBudW1lcmljID0gcGFydHNbMF0gKyAnLicgKyBwYXJ0c1sxXS5zdWJzdHIoMCwgMik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBGb3JtYXQgdGhlIG51bWVyaWMgdmFsdWVcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYyk7XG4gICAgICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBDdXJzb3IgaXMgbm90IGF0IGVuZCAtIHVzZXIgaXMgZWRpdGluZyBpbiB0aGUgbWlkZGxlXG4gICAgICAgICAgICAgICAgLy8gRG9uJ3QgZm9ybWF0LCBqdXN0IGNsZWFuIGludmFsaWQgY2hhcmFjdGVyc1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuXG4gICAgICAgICAgICAgICAgLy8gT25seSB1cGRhdGUgaWYgd2UgcmVtb3ZlZCBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZm9ybWF0X2N1cnJlbmN5KG51bWVyaWMpICE9PSByYXcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJlc2VydmUganVzdCB0aGUgbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN5bWJvbF9vZmZzZXQgPSB0aGlzLmFyZ3Muc2hvd19zeW1ib2wgPyB0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sLmxlbmd0aCA6IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuZWQgPSAodGhpcy5hcmdzLnNob3dfc3ltYm9sID8gdGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbCA6ICcnKSArIG51bWVyaWM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsZWFuZWQgIT09IHJhdykge1xuICAgICAgICAgICAgICAgICAgICAgICAgJGlucHV0LnZhbChjbGVhbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgY3Vyc29yIHBvc2l0aW9uIChhcHByb3hpbWF0ZWx5KVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2N1cnNvciA9IE1hdGgubWluKGN1cnNvcl9wb3MsIGNsZWFuZWQubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3X2N1cnNvciwgbmV3X2N1cnNvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBibHVyIHRvIHJlZm9ybWF0IHdoZW4gZG9uZSBlZGl0aW5nXG4gICAgICAgICRpbnB1dC5vbignYmx1cicsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgaWYgKCFyYXcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlZm9ybWF0IHRoZSBlbnRpcmUgdmFsdWUgb24gYmx1clxuICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYyk7XG4gICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBmb2N1cyB0byBzZWxlY3QgYWxsIGZvciBlYXN5IHJlcGxhY2VtZW50XG4gICAgICAgICRpbnB1dC5vbignZm9jdXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAkaW5wdXRbMF0uc2VsZWN0KCk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBmb3JtYXR0aW5nIGlmIHRoZXJlJ3MgYSB2YWx1ZVxuICAgICAgICBjb25zdCBpbml0aWFsX3ZhbHVlID0gJGlucHV0LnZhbCgpO1xuICAgICAgICBpZiAoaW5pdGlhbF92YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWwoaW5pdGlhbF92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFBob25lX1RleHRfSW5wdXRcbiAqXG4gKiBFeHRlbmRzIFRleHRfSW5wdXQgdG8gcHJvdmlkZSBhdXRvbWF0aWMgcGhvbmUgbnVtYmVyIGZvcm1hdHRpbmcuXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIFVTIE1vZGUgKGRlZmF1bHQpOiBGb3JtYXRzIGFzIChYWFgpIFhYWC1YWFhYIG9uIGV2ZXJ5IGtleXN0cm9rZVxuICogLSBJbnRlcm5hdGlvbmFsIE1vZGU6IFRyaWdnZXJlZCBieSBzdGFydGluZyB3aXRoICcrJywgZGlzYWJsZXMgZm9ybWF0dGluZ1xuICogLSB2YWwoKSBnZXR0ZXIgcmV0dXJucyBmb3JtYXR0ZWQgc3RyaW5nIGFzIGRpc3BsYXllZFxuICogLSB2YWwoKSBzZXR0ZXIgYWNjZXB0cyBhbnkgZm9ybWF0IGFuZCBkaXNwbGF5cyBhcHByb3ByaWF0ZWx5XG4gKlxuICogVXNhZ2U6XG4gKiAgIDxQaG9uZV9UZXh0X0lucHV0ICRwbGFjZWhvbGRlcj1cIlBob25lIG51bWJlclwiIC8+XG4gKlxuICogQmVoYXZpb3I6XG4gKiAtIFR5cGUgXCI1NTUxMjM0NTY3XCIgLT4gZGlzcGxheXMgXCIoNTU1KSAxMjMtNDU2N1wiLCB2YWwoKSByZXR1cm5zIFwiKDU1NSkgMTIzLTQ1NjdcIlxuICogLSBUeXBlIFwiKzQ0IDIwIDcxMjMgNDU2N1wiIC0+IGRpc3BsYXlzIGFzIHR5cGVkLCB2YWwoKSByZXR1cm5zIFwiKzQ0IDIwIDcxMjMgNDU2N1wiXG4gKiAtIExlYWRpbmcgXCIxXCIgaXMgc3RyaXBwZWQ6IFwiMTU1NTEyMzQ1NjdcIiAtPiBcIig1NTUpIDEyMy00NTY3XCJcbiAqL1xuY2xhc3MgUGhvbmVfVGV4dF9JbnB1dCBleHRlbmRzIFRleHRfSW5wdXQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgICAgIHRoaXMuX2lzX2ludGVybmF0aW9uYWwgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBpbnB1dCBpcyBpbiBpbnRlcm5hdGlvbmFsIG1vZGUgKHN0YXJ0cyB3aXRoICspXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgX2NoZWNrX2ludGVybmF0aW9uYWxfbW9kZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgJiYgc3RyKHZhbHVlKS5jaGFyQXQoMCkgPT09ICcrJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JtYXQgVVMgcGhvbmUgbnVtYmVyIGFzIChYWFgpIFhYWC1YWFhYXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGRpZ2l0cyAtIENsZWFuIG51bWVyaWMgc3RyaW5nIChzaG91bGQgYmUgMTAgZGlnaXRzIG9yIGxlc3MgYWZ0ZXIgcHJvY2Vzc2luZylcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBGb3JtYXR0ZWQgcGhvbmUgbnVtYmVyXG4gICAgICovXG4gICAgX2Zvcm1hdF91c19waG9uZShkaWdpdHMpIHtcbiAgICAgICAgLy8gRm9ybWF0IGJhc2VkIG9uIGxlbmd0aCAoYXNzdW1lcyBkaWdpdHMgYXJlIGFscmVhZHkgY2xlYW5lZCBhbmQgbGltaXRlZCB0byAxMClcbiAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPj0gNikge1xuICAgICAgICAgICAgLy8gKFhYWCkgWFhYLVhYWFhcbiAgICAgICAgICAgIHJldHVybiAnKCcgKyBkaWdpdHMuc3Vic3RyKDAsIDMpICsgJykgJyArIGRpZ2l0cy5zdWJzdHIoMywgMykgKyAnLScgKyBkaWdpdHMuc3Vic3RyKDYpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgLy8gKFhYWCkgWFhYXG4gICAgICAgICAgICByZXR1cm4gJygnICsgZGlnaXRzLnN1YnN0cigwLCAzKSArICcpICcgKyBkaWdpdHMuc3Vic3RyKDMpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyAoWFhcbiAgICAgICAgICAgIHJldHVybiAnKCcgKyBkaWdpdHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGlnaXRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCB0aGUgcGhvbmUgbnVtYmVyXG4gICAgICogR2V0dGVyIHJldHVybnMgZm9ybWF0dGVkIHZhbHVlIGFzIGRpc3BsYXllZCAod2l0aCBwYXJlbnMsIGRhc2hlcywgZXRjKVxuICAgICAqIFNldHRlciBhY2NlcHRzIGFueXRoaW5nIGFuZCBmb3JtYXRzIGFwcHJvcHJpYXRlbHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXIgLSByZXR1cm4gdGhlIGZvcm1hdHRlZCB2YWx1ZSBhcyBkaXNwbGF5ZWRcbiAgICAgICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKSB8fCAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGZvcm1hdCBhbmQgZGlzcGxheVxuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHN0cl92YWx1ZSA9IHN0cih2YWx1ZSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUoc3RyX3ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIC8vIEludGVybmF0aW9uYWwgbW9kZSAtIG5vIGZvcm1hdHRpbmdcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSBzdHJfdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbChzdHJfdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVVMgbW9kZSAtIGNsZWFuIGRpZ2l0cyBhbmQgZm9ybWF0XG4gICAgICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gc3RyX3ZhbHVlLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hpY2ggZGlnaXRzIHRvIGZvcm1hdFxuICAgICAgICAgICAgICAgIGxldCBkaWdpdHNfdG9fZm9ybWF0O1xuICAgICAgICAgICAgICAgIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiBkaWdpdHMuY2hhckF0KDApID09PSAnMScgJiYgL1syLTldLy50ZXN0KGRpZ2l0cy5jaGFyQXQoMSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0cmlwIFVTIGNvdW50cnkgY29kZVxuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPiAxMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUYWtlIGZpcnN0IDEwXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDAsIDEwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYXMtaXNcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfdXNfcGhvbmUoZGlnaXRzX3RvX2Zvcm1hdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgbGV0IF9sYXN0X2N1cnNvcl9wb3NpdGlvbiA9IG51bGw7XG5cbiAgICAgICAgLy8gSGFuZGxlIGtleWRvd24gdG8gaW50ZXJjZXB0IGJhY2tzcGFjZSBhdCBlbmQgb2Ygc3RyaW5nXG4gICAgICAgICRpbnB1dC5vbigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIC8vIFNraXAgaWYgaW50ZXJuYXRpb25hbCBtb2RlXG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGJhY2tzcGFjZSBrZXlcbiAgICAgICAgICAgIGlmIChlLmtleSAhPT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlucHV0X2VsZW1lbnQgPSAkaW5wdXRbMF07XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9lbmQgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvbkVuZDtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlX2xlbmd0aCA9IHJhdy5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGlmIGN1cnNvciBpcyBhdCB0aGUgZW5kIGFuZCBubyBzZWxlY3Rpb25cbiAgICAgICAgICAgIGlmIChjdXJzb3JfcG9zID09PSB2YWx1ZV9sZW5ndGggJiYgY3Vyc29yX3BvcyA9PT0gY3Vyc29yX2VuZCkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNoYXJhY3RlciBiZWZvcmUgY3Vyc29yIGlzIG5vbi1udW1lcmljXG4gICAgICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJfYmVmb3JlID0gcmF3LmNoYXJBdChjdXJzb3JfcG9zIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghL1swLTldLy50ZXN0KGNoYXJfYmVmb3JlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm90IGEgZGlnaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgbGFzdCBkaWdpdCBpbnN0ZWFkXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2l0cyA9IHJhdy5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2RpZ2l0cyA9IGRpZ2l0cy5zdWJzdHIoMCwgZGlnaXRzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF91c19waG9uZShuZXdfZGlnaXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbGFjZSBjdXJzb3IgYXQgZW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19sZW5ndGggPSAkaW5wdXQudmFsKCkubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9lbGVtZW50LnNldFNlbGVjdGlvblJhbmdlKG5ld19sZW5ndGgsIG5ld19sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgaW5wdXQgZXZlbnQgZm9yIGxpdmUgZm9ybWF0dGluZ1xuICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3ID0gJGlucHV0LnZhbCgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykpIHtcbiAgICAgICAgICAgICAgICAvLyBJbnRlcm5hdGlvbmFsIG1vZGUgLSBhbGxvdyBhbnl0aGluZ1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzX2ludGVybmF0aW9uYWwgPSB0cnVlO1xuICAgICAgICAgICAgICAgIC8vIE5vIGZvcm1hdHRpbmcsIG5vIHJlc3RyaWN0aW9uc1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVVMgbW9kZVxuICAgICAgICAgICAgdGhpcy5faXNfaW50ZXJuYXRpb25hbCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnB1dF9lbGVtZW50ID0gJGlucHV0WzBdO1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX3BvcyA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZV9sZW5ndGggPSByYXcubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGFwcGx5IGxpdmUgZm9ybWF0dGluZyBpZiBjdXJzb3IgaXMgYXQgdGhlIGVuZFxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBhbnkgbm9uLWRpZ2l0LCBub24tZm9ybWF0dGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZCA9IHJhdy5yZXBsYWNlKC9bXjAtOVxcc1xcLSgpXS9nLCAnJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gY2xlYW5lZC5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuXG4gICAgICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGRpZ2l0cyB0byBmb3JtYXRcbiAgICAgICAgICAgICAgICBsZXQgZGlnaXRzX3RvX2Zvcm1hdDtcblxuICAgICAgICAgICAgICAgIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiBkaWdpdHMuY2hhckF0KDApID09PSAnMScgJiYgL1syLTldLy50ZXN0KGRpZ2l0cy5jaGFyQXQoMSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEV4YWN0bHkgMTEgZGlnaXRzIHN0YXJ0aW5nIHdpdGggXCIxXCIgZm9sbG93ZWQgYnkgdmFsaWQgYXJlYSBjb2RlIGRpZ2l0ICgyLTkpXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBVUyBjb3VudHJ5IGNvZGUgLSBzdHJpcCB0aGUgbGVhZGluZyAxXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE1vcmUgdGhhbiAxMCBkaWdpdHMgLSBqdXN0IHRha2UgdGhlIGZpcnN0IDEwIGFuZCBpZ25vcmUgdGhlIHJlc3RcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cy5zdWJzdHIoMCwgMTApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDEwIG9yIGZld2VyIGRpZ2l0cyAtIHVzZSBhcy1pc1xuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEZvcm1hdCB0aGUgZGlnaXRzXG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X3VzX3Bob25lKGRpZ2l0c190b19mb3JtYXQpO1xuICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ3Vyc29yIGlzIG5vdCBhdCBlbmQgLSB1c2VyIGlzIGVkaXRpbmcgaW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgICAgIC8vIERvbid0IGZvcm1hdCwganVzdCBjbGVhbiBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkID0gcmF3LnJlcGxhY2UoL1teMC05XFxzXFwtKCldL2csICcnKTtcbiAgICAgICAgICAgICAgICBpZiAoY2xlYW5lZCAhPT0gcmF3KSB7XG4gICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoY2xlYW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgY3Vyc29yIHBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoY3Vyc29yX3BvcywgY3Vyc29yX3Bvcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgYmx1ciB0byByZWZvcm1hdCB3aGVuIGRvbmUgZWRpdGluZ1xuICAgICAgICAkaW5wdXQub24oJ2JsdXInLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIC8vIFNraXAgaWYgaW50ZXJuYXRpb25hbCBtb2RlIG9yIGVtcHR5XG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykgfHwgIXJhdykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVmb3JtYXQgdGhlIGVudGlyZSB2YWx1ZSBvbiBibHVyXG4gICAgICAgICAgICBjb25zdCBkaWdpdHMgPSByYXcucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGRpZ2l0cyB0byBmb3JtYXRcbiAgICAgICAgICAgIGxldCBkaWdpdHNfdG9fZm9ybWF0O1xuXG4gICAgICAgICAgICBpZiAoZGlnaXRzLmxlbmd0aCA9PT0gMTEgJiYgZGlnaXRzLmNoYXJBdCgwKSA9PT0gJzEnICYmIC9bMi05XS8udGVzdChkaWdpdHMuY2hhckF0KDEpKSkge1xuICAgICAgICAgICAgICAgIC8vIEV4YWN0bHkgMTEgZGlnaXRzIHN0YXJ0aW5nIHdpdGggXCIxXCIgZm9sbG93ZWQgYnkgdmFsaWQgYXJlYSBjb2RlIGRpZ2l0ICgyLTkpXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIFVTIGNvdW50cnkgY29kZSAtIHN0cmlwIHRoZSBsZWFkaW5nIDFcbiAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgICAgLy8gTW9yZSB0aGFuIDEwIGRpZ2l0cyAtIGp1c3QgdGFrZSB0aGUgZmlyc3QgMTBcbiAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigwLCAxMCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIDEwIG9yIGZld2VyIGRpZ2l0cyAtIHVzZSBhcy1pc1xuICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF91c19waG9uZShkaWdpdHNfdG9fZm9ybWF0KTtcbiAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBmb3JtYXR0aW5nIGlmIHRoZXJlJ3MgYSB2YWx1ZVxuICAgICAgICBjb25zdCBpbml0aWFsX3ZhbHVlID0gJGlucHV0LnZhbCgpO1xuICAgICAgICBpZiAoaW5pdGlhbF92YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWwoaW5pdGlhbF92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBTdGF0ZV9TZWxlY3RfSW5wdXQgZXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBjb3VudHJ5IGNvZGUgZnJvbSBhcmdzIG9yIGRlZmF1bHQgdG8gVVNcbiAgICAgICAgaWYgKCF0aGlzLmRhdGEuY291bnRyeV9jb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY291bnRyeV9jb2RlID0gdGhpcy5hcmdzLmNvdW50cnlfY29kZSB8fCAnVVMnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9hZCBzdGF0ZXMgdmlhIEFqYXggZW5kcG9pbnQgaWYgY291bnRyeSBjb2RlIGlzIHNldFxuICAgICAgICBpZiAodGhpcy5kYXRhLmNvdW50cnlfY29kZSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBhd2FpdCBSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci5zdGF0ZXMoeyBjb3VudHJ5OiB0aGlzLmRhdGEuY291bnRyeV9jb2RlIH0pO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBzdGF0ZXMgcmV0dXJuZWQsIGFkZCBOL0Egb3B0aW9uXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzIHx8IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW3sgdmFsdWU6ICdOL0EnLCBsYWJlbDogJ04vQScgfV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBTZXQgZGVmYXVsdCBwbGFjZWhvbGRlciBpZiBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5wbGFjZWhvbGRlciA9ICdTZWxlY3QgU3RhdGUuLi4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBjb3VudHJ5IGNvZGUgaW4gZGF0YVxuICAgICAgICB0aGlzLmRhdGEuY291bnRyeV9jb2RlID0gdGhpcy5hcmdzLmNvdW50cnlfY29kZSB8fCAnJztcblxuICAgICAgICAvLyBDYWNoZSBmb3Igc2VsZWN0ZWQgc3RhdGUgcGVyIGNvdW50cnkgY29kZVxuICAgICAgICB0aGlzLl9zdGF0ZV9jYWNoZSA9IHt9O1xuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgQWpheF9TZWxlY3RfSW5wdXRcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgTi9BIGNhc2UgKG5vIHN0YXRlcyBmb3IgY291bnRyeSlcbiAgICAgICAgY29uc3QgaXNfbmEgPSB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDEgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXNbMF0udmFsdWUgPT09ICdOL0EnO1xuXG4gICAgICAgIC8vIERpc2FibGUgaWYgbm8gY291bnRyeSBjb2RlIG9yIE4vQSBjYXNlXG4gICAgICAgIGlmICgoIXRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgfHwgaXNfbmEpICYmIHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRpc2FibGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSB0byBOL0EgaWYgdGhhdCdzIHRoZSBvbmx5IG9wdGlvblxuICAgICAgICBpZiAoaXNfbmEpIHtcbiAgICAgICAgICAgIHRoaXMudmFsKCdOL0EnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBjb3VudHJ5IGNvZGUgYW5kIHJlbG9hZCBzdGF0ZSBsaXN0XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvdW50cnlfY29kZSAtIElTTyBjb3VudHJ5IGNvZGUgKGUuZy4sICdVUycsICdDQScpXG4gICAgICovXG4gICAgYXN5bmMgc2V0X2NvdW50cnlfY29kZShjb3VudHJ5X2NvZGUpIHtcbiAgICAgICAgLy8gQ2FjaGUgdGhlIGN1cnJlbnQgdmFsdWUgZm9yIHRoZSBjdXJyZW50IGNvdW50cnkgYmVmb3JlIHN3aXRjaGluZ1xuICAgICAgICBjb25zdCBjdXJyZW50X2NvdW50cnkgPSB0aGlzLmRhdGEuY291bnRyeV9jb2RlO1xuICAgICAgICBjb25zdCBjdXJyZW50X3ZhbHVlID0gdGhpcy52YWwoKTtcbiAgICAgICAgaWYgKGN1cnJlbnRfY291bnRyeSAmJiBjdXJyZW50X3ZhbHVlICYmIGN1cnJlbnRfdmFsdWUgIT09ICdOL0EnKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZV9jYWNoZVtjdXJyZW50X2NvdW50cnldID0gY3VycmVudF92YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBjb3VudHJ5IGNvZGVcbiAgICAgICAgdGhpcy5kYXRhLmNvdW50cnlfY29kZSA9IGNvdW50cnlfY29kZTtcblxuICAgICAgICAvLyBEaXNhYmxlIHRoZSBzZWxlY3RvciB3aGlsZSBsb2FkaW5nXG4gICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5kaXNhYmxlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb2FkIG5ldyBzdGF0ZSBsaXN0XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IGF3YWl0IFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLnN0YXRlcyh7IGNvdW50cnk6IGNvdW50cnlfY29kZSB9KTtcblxuICAgICAgICAgICAgLy8gUmFjZSBjb25kaXRpb24gY2hlY2s6IHZlcmlmeSBjb3VudHJ5IGhhc24ndCBjaGFuZ2VkIGR1cmluZyB0aGUgcmVxdWVzdFxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgIT09IGNvdW50cnlfY29kZSkge1xuICAgICAgICAgICAgICAgIC8vIENvdW50cnkgY2hhbmdlZCB3aGlsZSByZXF1ZXN0IHdhcyBpbiBmbGlnaHQgLSBpZ25vcmUgdGhpcyByZXNwb25zZVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gc3RhdGVzIHJldHVybmVkLCBhZGQgTi9BIG9wdGlvblxuICAgICAgICAgICAgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFt7IHZhbHVlOiAnTi9BJywgbGFiZWw6ICdOL0EnIH1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZS1yZW5kZXIgdGhlIHdpZGdldCB3aXRoIG5ldyBzdGF0ZXNcbiAgICAgICAgICAgIHRoaXMucmVkcmF3KCk7XG5cbiAgICAgICAgICAgIC8vIFJlLWluaXRpYWxpemUgVG9tIFNlbGVjdCBhZnRlciByZWRyYXdcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZS1ydW4gb25fcmVhZHkgdG8gc2V0IHVwIFRvbSBTZWxlY3QgYWdhaW5cbiAgICAgICAgICAgIHRoaXMub25fcmVhZHkoKTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBOL0EgY2FzZVxuICAgICAgICAgICAgY29uc3QgaXNfbmEgPSB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDEgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXNbMF0udmFsdWUgPT09ICdOL0EnO1xuXG4gICAgICAgICAgICBpZiAoaXNfbmEpIHtcbiAgICAgICAgICAgICAgICAvLyBTZXQgdG8gTi9BIGFuZCBrZWVwIGRpc2FibGVkXG4gICAgICAgICAgICAgICAgdGhpcy52YWwoJ04vQScpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRpc2FibGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRyeSB0byByZXN0b3JlIGNhY2hlZCB2YWx1ZSBmb3IgdGhpcyBjb3VudHJ5XG4gICAgICAgICAgICAgICAgY29uc3QgY2FjaGVkX3ZhbHVlID0gdGhpcy5fc3RhdGVfY2FjaGVbY291bnRyeV9jb2RlXTtcblxuICAgICAgICAgICAgICAgIGlmIChjYWNoZWRfdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVfZXhpc3RzID0gdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMuc29tZSgob3B0KSA9PiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcgPyBvcHQudmFsdWUgOiBvcHQpID09PSBjYWNoZWRfdmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZV9leGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsKGNhY2hlZF92YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbCgnJyk7IC8vIENsZWFyIGlmIGNhY2hlZCB2YWx1ZSBub3QgaW4gbmV3IGxpc3RcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsKCcnKTsgLy8gTm8gY2FjaGVkIHZhbHVlIC0gbGVhdmUgZW1wdHlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBFbmFibGUgdGhlIHdpZGdldCBub3cgdGhhdCB3ZSBoYXZlIGEgY291bnRyeSB3aXRoIHN0YXRlc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmVuYWJsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHN0YXRlcyBmb3IgY291bnRyeTonLCBjb3VudHJ5X2NvZGUsIGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW107XG5cbiAgICAgICAgICAgIC8vIFJlLWVuYWJsZSBldmVuIG9uIGVycm9yXG4gICAgICAgICAgICBpZiAodGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmVuYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgdmFsKCkgdG8gdXBkYXRlIGNhY2hlIHdoZW4gdXNlciBtYW51YWxseSBzZWxlY3RzIGEgc3RhdGVcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHVzZSBwYXJlbnQgaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAgIHJldHVybiBzdXBlci52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSBjYWNoZSBhbmQgY2FsbCBwYXJlbnRcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuY291bnRyeV9jb2RlICYmIHZhbHVlICYmIHZhbHVlICE9PSAnTi9BJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlX2NhY2hlW3RoaXMuZGF0YS5jb3VudHJ5X2NvZGVdID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIudmFsKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENvdW50cnlfU2VsZWN0X0lucHV0IGV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY291bnRyaWVzIHZpYSBBamF4IGVuZHBvaW50IGlmIGRhdGEgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLmRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gYXdhaXQgUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIuY291bnRyaWVzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVc2UgcGFyZW50IG9uX2xvYWQgZm9yIGN1c3RvbSBkYXRhIGVuZHBvaW50c1xuICAgICAgICAgICAgYXdhaXQgc3VwZXIub25fbG9hZCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVvcmRlciBzZWxlY3RfdmFsdWVzIHRvIHB1dCBkZWZhdWx0IGNvdW50cnkgZmlyc3QgaW4gdGhlIGxpc3RcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kZWZhdWx0X2NvdW50cnkgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgJiYgaXNfYXJyYXkodGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0X2NvdW50cnlfY29kZSA9IHRoaXMuYXJncy5kZWZhdWx0X2NvdW50cnk7XG5cbiAgICAgICAgICAgIC8vIEZpbmQgdGhlIGRlZmF1bHQgY291bnRyeSBpbiB0aGUgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRfY291bnRyeV9pbmRleCA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmZpbmRJbmRleChcbiAgICAgICAgICAgICAgICBvcHQgPT4gKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnID8gb3B0LnZhbHVlIDogb3B0KSA9PT0gZGVmYXVsdF9jb3VudHJ5X2NvZGVcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChkZWZhdWx0X2NvdW50cnlfaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGl0IGZyb20gaXRzIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgICAgICAgICAgICBjb25zdCBbZGVmYXVsdF9jb3VudHJ5XSA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLnNwbGljZShkZWZhdWx0X2NvdW50cnlfaW5kZXgsIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIGl0IHRvIHRoZSBiZWdpbm5pbmdcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy51bnNoaWZ0KGRlZmF1bHRfY291bnRyeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIFNldCBkZWZhdWx0IHBsYWNlaG9sZGVyIGlmIG5vdCBwcm92aWRlZFxuICAgICAgICBpZiAoIXRoaXMuYXJncy5wbGFjZWhvbGRlcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLnBsYWNlaG9sZGVyID0gJ1NlbGVjdCBDb3VudHJ5Li4uJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgQWpheF9TZWxlY3RfSW5wdXRcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGRlZmF1bHQgY291bnRyeSB2YWx1ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLmRlZmF1bHRfY291bnRyeSAmJiAhdGhpcy5kYXRhLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSB0aGlzLmFyZ3MuZGVmYXVsdF9jb3VudHJ5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBzdGF0ZSBzZWxlY3RvciB3aXRoIGluaXRpYWwvZGVmYXVsdCBjb3VudHJ5XG4gICAgICAgIHRoaXMuX3VwZGF0ZV9zdGF0ZV9zZWxlY3RvcigpO1xuXG4gICAgICAgIC8vIExpc3RlbiBmb3IgY291bnRyeSBjaGFuZ2VzIGFuZCB1cGRhdGUgc3RhdGUgc2VsZWN0b3JcbiAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0Lm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlX3N0YXRlX3NlbGVjdG9yKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmQgU3RhdGVfU2VsZWN0X0lucHV0IHNpYmxpbmcgYW5kIHVwZGF0ZSBpdHMgY291bnRyeSBjb2RlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdXBkYXRlX3N0YXRlX3NlbGVjdG9yKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50X2NvdW50cnkgPSB0aGlzLnZhbCgpO1xuXG4gICAgICAgIC8vIEZpbmQgU3RhdGVfU2VsZWN0X0lucHV0IGNvbXBvbmVudCB1c2luZyBjbG9zZXN0X3NpYmxpbmdcbiAgICAgICAgY29uc3Qgc3RhdGVfY29tcG9uZW50ID0gdGhpcy4kLmNsb3Nlc3Rfc2libGluZygnLlN0YXRlX1NlbGVjdF9JbnB1dCcpLmNvbXBvbmVudCgpO1xuXG4gICAgICAgIGlmIChzdGF0ZV9jb21wb25lbnQgJiYgdHlwZW9mIHN0YXRlX2NvbXBvbmVudC5zZXRfY291bnRyeV9jb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzdGF0ZV9jb21wb25lbnQuc2V0X2NvdW50cnlfY29kZShjdXJyZW50X2NvdW50cnkpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqXG4gKiBQcm9maWxlX1Bob3RvX0lucHV0XG4gKlxuICogUHJvZmlsZSBwaG90byB1cGxvYWQgd2lkZ2V0IHdpdGggdGh1bWJuYWlsIGRpc3BsYXkgYW5kIHVwbG9hZCBoYW5kbGluZy5cbiAqIFNlZSBwcm9maWxlX3Bob3RvX2lucHV0LmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gSGFuZGxlIGZpbGUgc2VsZWN0aW9uIGFuZCB1cGxvYWRcbiAqIC0gVXBkYXRlIHRodW1ibmFpbCBvbiBzdWNjZXNzZnVsIHVwbG9hZFxuICogLSBNYW5hZ2UgbG9hZGluZyBzdGF0ZSB3aXRoIHNwaW5uZXJcbiAqIC0gUHJvdmlkZSB2YWwoKSBnZXR0ZXIvc2V0dGVyIGZvciBhdHRhY2htZW50IGtleVxuICogLSBIYW5kbGUgcmVtb3ZlIGJ1dHRvbiBmdW5jdGlvbmFsaXR5XG4gKi9cbmNsYXNzIFByb2ZpbGVfUGhvdG9fSW5wdXQgZXh0ZW5kcyBGb3JtX0lucHV0X0Fic3RyYWN0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgZGF0YVxuICAgICAgICB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkgPSAnJztcbiAgICAgICAgdGhpcy5kYXRhLnRodW1ibmFpbF91cmwgPSAnJztcbiAgICB9XG5cbiAgICBvbl9yZW5kZXIoKSB7XG4gICAgICAgIC8vIEhhbmRsZSB1cGxvYWQgYnV0dG9uIGNsaWNrIC0gdHJpZ2dlciBoaWRkZW4gZmlsZSBpbnB1dFxuICAgICAgICB0aGlzLiRpZCgndXBsb2FkX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykuY2xpY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGZpbGUgc2VsZWN0aW9uXG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0Jykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpWzBdLmZpbGVzWzBdO1xuICAgICAgICAgICAgaWYgKCFmaWxlKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMudXBsb2FkX3Bob3RvKGZpbGUpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgcmVtb3ZlIGJ1dHRvblxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfcmVtb3ZlKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgncmVtb3ZlX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZV9waG90bygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGF0dGFjaG1lbnQga2V5XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIGF0dGFjaG1lbnQga2V5IGFuZCB1cGRhdGVzIHRodW1ibmFpbFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IGF0dGFjaG1lbnQga2V5IHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbChrZXkpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHJldHVybiBhdHRhY2htZW50IGtleVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5hdHRhY2htZW50X2tleSB8fCAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHNldCBhdHRhY2htZW50IGtleSBhbmQgdXBkYXRlIHRodW1ibmFpbFxuICAgICAgICAgICAgdGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5ID0ga2V5IHx8ICcnO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGh1bWJuYWlsIFVSTCBmcm9tIGF0dGFjaG1lbnQga2V5XG4gICAgICAgICAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLmFyZ3Mud2lkdGggfHwgOTY7XG4gICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5hcmdzLmhlaWdodCB8fCA5NjtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCA9IGAvX3RodW1ibmFpbC8ke3RoaXMuZGF0YS5hdHRhY2htZW50X2tleX0vY292ZXIvJHt3aWR0aH0vJHtoZWlnaHR9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8ga2V5IC0gY2xlYXIgdGh1bWJuYWlsXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnRodW1ibmFpbF91cmwgPSAnJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1JlcmVuZGVyJyk7XG4gICAgICAgICAgICAvLyBSZS1yZW5kZXIgdG8gc3dpdGNoIGJldHdlZW4gaWNvbiBhbmQgaW1hZ2VcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGxvYWRfcGhvdG8oZmlsZSkge1xuICAgICAgICAvLyBWYWxpZGF0ZSBmaWxlIHNpemVcbiAgICAgICAgY29uc3QgbWF4X3NpemUgPSAodGhpcy5hcmdzLm1heF9zaXplIHx8IDIpICogMTAyNCAqIDEwMjQ7IC8vIENvbnZlcnQgTUIgdG8gYnl0ZXNcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IG1heF9zaXplKSB7XG4gICAgICAgICAgICBhbGVydChgRmlsZSBzaXplIG11c3QgYmUgbGVzcyB0aGFuICR7dGhpcy5hcmdzLm1heF9zaXplIHx8IDJ9TUJgKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykudmFsKCcnKTsgLy8gQ2xlYXIgc2VsZWN0aW9uXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IHNwaW5uZXIsIGRpbSBpbWFnZVxuICAgICAgICB0aGlzLiRpZCgnc3Bpbm5lcicpLnJlbW92ZUNsYXNzKCdkLW5vbmUnKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Bob3RvJykuY3NzKCdvcGFjaXR5JywgJzAuMycpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBGb3JtRGF0YSBmb3IgZmlsZSB1cGxvYWRcbiAgICAgICAgY29uc3QgZm9ybV9kYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1fZGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlKTtcbiAgICAgICAgZm9ybV9kYXRhLmFwcGVuZCgnc2l0ZV9pZCcsICcxJyk7IC8vIFRPRE86IEdldCBmcm9tIHNlc3Npb24vY29uZmlnXG4gICAgICAgIC8vIERvIE5PVCBzZXQgZmlsZWFibGVfdHlwZS9maWxlYWJsZV9jYXRlZ29yeSAtIGZpbGUgdXBsb2FkcyB1bmF0dGFjaGVkXG4gICAgICAgIC8vIFRoZSBwYXJlbnQgZm9ybSB3aWxsIGFzc2lnbiBpdCB2aWEgYXR0YWNoX3RvKCkgb24gc2F2ZVxuXG4gICAgICAgIC8vIFVwbG9hZCBmaWxlIHZpYSBBSkFYXG4gICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6ICcvX3VwbG9hZCcsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBmb3JtX2RhdGEsXG4gICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogZmFsc2UsXG4gICAgICAgICAgICBzdWNjZXNzOiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnUHJvZmlsZSBwaG90byB1cGxvYWQgc3VjY2Vzc2Z1bDonLCByZXNwb25zZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgYXR0YWNobWVudCBrZXkgKHRoaXMgd2lsbCBhbHNvIHVwZGF0ZSB0aHVtYm5haWwpXG4gICAgICAgICAgICAgICAgdGhpcy52YWwocmVzcG9uc2UuYXR0YWNobWVudC5rZXkpO1xuXG4gICAgICAgICAgICAgICAgLy8gSGlkZSBzcGlubmVyLCByZXN0b3JlIG9wYWNpdHlcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnc3Bpbm5lcicpLmFkZENsYXNzKCdkLW5vbmUnKTtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgncGhvdG8nKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgZmlsZSBpbnB1dCBmb3IgZnV0dXJlIHVwbG9hZHNcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpLnZhbCgnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGNoYW5nZSBldmVudCBmb3IgZm9ybSB0cmFja2luZ1xuICAgICAgICAgICAgICAgIHRoaXMuJC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogKHhociwgc3RhdHVzLCBlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Byb2ZpbGUgcGhvdG8gdXBsb2FkIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignUmVzcG9uc2U6JywgeGhyLnJlc3BvbnNlSlNPTik7XG5cbiAgICAgICAgICAgICAgICAvLyBIaWRlIHNwaW5uZXIsIHJlc3RvcmUgb3BhY2l0eVxuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdzcGlubmVyJykuYWRkQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdwaG90bycpLmNzcygnb3BhY2l0eScsICcxJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBDbGVhciBmaWxlIGlucHV0XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS52YWwoJycpO1xuXG4gICAgICAgICAgICAgICAgLy8gU2hvdyBlcnJvciB0byB1c2VyXG4gICAgICAgICAgICAgICAgYWxlcnQoJ1VwbG9hZCBmYWlsZWQ6ICcgKyAoeGhyLnJlc3BvbnNlSlNPTj8uZXJyb3IgfHwgZXJyb3IpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVwZGF0ZV9waG90bygpIHtcbiAgICAgICAgLy8gPCUgaWYgKHRoaXMuYXJncy5zaG93X3JlbW92ZSAmJiB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkpIHsgJT5cbiAgICB9XG5cbiAgICByZW1vdmVfcGhvdG8oKSB7XG4gICAgICAgIC8vIENsZWFyIGF0dGFjaG1lbnQga2V5IChzZXRzIHRvIHBsYWNlaG9sZGVyKVxuICAgICAgICB0aGlzLnZhbCgnJyk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjaGFuZ2UgZXZlbnQgZm9yIGZvcm0gdHJhY2tpbmdcbiAgICAgICAgdGhpcy4kLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIC8vIEZvciB0ZXN0aW5nIC0gc2V0IGEgcGxhY2Vob2xkZXIga2V5XG4gICAgICAgIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQgdXNlIGFjdHVhbCB0ZXN0IGRhdGFcbiAgICAgICAgdGhpcy52YWwoJycpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X1RhYnNcbiAqXG4gKiBUYWIgY29udGFpbmVyIGNvbXBvbmVudCB3aXRoIGZvcm0tYXdhcmUgZXJyb3IgaGFuZGxpbmcgaW50ZWdyYXRpb24uXG4gKiBTZWUgcnN4X3RhYnMuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBCdWlsZHMgdGFiIG5hdmlnYXRpb24gZHluYW1pY2FsbHkgZnJvbSByZWdpc3RlcmVkIFJzeF9UYWIgY2hpbGRyZW5cbiAqIC0gTWFuYWdlcyB0YWIgYWN0aXZhdGlvbiBhbmQgc3dpdGNoaW5nIGJlaGF2aW9yXG4gKiAtIFBlcnNpc3RzIGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nXG4gKiAtIEludGVncmF0ZXMgd2l0aCBmb3JtIHZhbGlkYXRpb24gdG8gc2hvdyBlcnJvciBiYWRnZXMgb24gdGFic1xuICogLSBBdXRvLXN3aXRjaGVzIHRvIGZpcnN0IHRhYiB3aXRoIGVycm9ycyBvbiB2YWxpZGF0aW9uIGZhaWx1cmVcbiAqIC0gUHJvdmlkZXMgQVBJIGZvciBwYXJlbnQgZm9ybXMgdG8gcmVwb3J0IHZhbGlkYXRpb24gZXJyb3JzXG4gKi9cbmNsYXNzIFJzeF9UYWJzIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLnRhYnMgPSBbXTsgLy8gUmVnaXN0ZXJlZCBSc3hfVGFiIGNvbXBvbmVudHNcbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRmluZCBwYXJlbnQgZm9ybSBpZiBpdCBleGlzdHNcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5jbG9zZXN0KCcuUnN4X0Zvcm0nKTtcblxuICAgICAgICAvLyBCdWlsZCB0YWIgbmF2aWdhdGlvbiBmcm9tIHJlZ2lzdGVyZWQgdGFic1xuICAgICAgICB0aGlzLl9idWlsZF9uYXYoKTtcblxuICAgICAgICAvLyBSZXN0b3JlIGFjdGl2ZSB0YWIgZnJvbSBVUkwgaGFzaCBvciBhY3RpdmF0ZSBmaXJzdCB0YWJcbiAgICAgICAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICBpZiAoaGFzaCkge1xuICAgICAgICAgICAgY29uc3QgdGFiX2lkID0gaGFzaC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0YWJfaWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0aGlzLnRhYnNbMF0uYXJncy5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQZXJzaXN0IGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2hcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKS5vbignY2xpY2snLCAnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJfaWQgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgndGFiLWlkJyk7XG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9ICcjJyArIHRhYl9pZDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVnaXN0ZXJfdGFiKHRhYl9jb21wb25lbnQpIHtcbiAgICAgICAgdGhpcy50YWJzLnB1c2godGFiX2NvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgX2J1aWxkX25hdigpIHtcbiAgICAgICAgY29uc3QgJG5hdiA9IHRoaXMuJGlkKCduYXYnKTtcbiAgICAgICAgJG5hdi5lbXB0eSgpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnNbaV07XG4gICAgICAgICAgICBjb25zdCBpc19hY3RpdmUgPSBpID09PSAwID8gJ2FjdGl2ZScgOiAnJztcblxuICAgICAgICAgICAgY29uc3QgJGxpID0gJChgXG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW1cIiByb2xlPVwicHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibmF2LWxpbmsgJHtpc19hY3RpdmV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS1icy10b2dnbGU9XCJ0YWJcIlxuICAgICAgICAgICAgICAgICAgICAgICBocmVmPVwiIyR7dGFiLmFyZ3MuaWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10YWItaWQ9XCIke3RhYi5hcmdzLmlkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9XCIke2kgPT09IDAgPyAndHJ1ZScgOiAnZmFsc2UnfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHJvbGU9XCJ0YWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MuaWNvbiA/IGA8aSBjbGFzcz1cIiR7dGFiLmFyZ3MuaWNvbn1cIj48L2k+IGAgOiAnJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MubGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlciBtcy0yXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIGRhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiPjA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgYCk7XG5cbiAgICAgICAgICAgICRuYXYuYXBwZW5kKCRsaSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhY3RpdmF0ZV90YWIodGFiX2lkKSB7XG4gICAgICAgIC8vIEZpbmQgdGhlIHRhYlxuICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnMuZmluZCgodCkgPT4gdC5hcmdzLmlkID09PSB0YWJfaWQpO1xuICAgICAgICBpZiAoIXRhYikgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJlbW92ZSBhY3RpdmUgc2hvdyBmcm9tIGFsbCB0YWIgcGFuZXNcbiAgICAgICAgZm9yIChsZXQgdCBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIHQuJC5yZW1vdmVDbGFzcygnYWN0aXZlIHNob3cnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBhY3RpdmUgc2hvdyB0byB0aGUgc2VsZWN0ZWQgdGFiIHBhbmVcbiAgICAgICAgdGFiLiQuYWRkQ2xhc3MoJ2FjdGl2ZSBzaG93Jyk7XG5cbiAgICAgICAgLy8gVXBkYXRlIEJvb3RzdHJhcCB0YWIgbmF2aWdhdGlvblxuICAgICAgICB0aGlzLiRpZCgnbmF2JykuZmluZCgnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgJ2ZhbHNlJyk7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKVxuICAgICAgICAgICAgLmZpbmQoJ2FbZGF0YS10YWItaWQ9XCInICsgdGFiX2lkICsgJ1wiXScpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgICAuYXR0cignYXJpYS1zZWxlY3RlZCcsICd0cnVlJyk7XG5cbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gdGFiX2lkO1xuICAgIH1cblxuICAgIGhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gQ291bnQgZXJyb3JzIHBlciB0YWJcbiAgICAgICAgY29uc3QgdGFiX2Vycm9ycyA9IHt9O1xuXG4gICAgICAgIGZvciAobGV0IHRhYiBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX2NvdW50ID0gdGFiLmNvdW50X2Vycm9ycyhlcnJvcnMpO1xuICAgICAgICAgICAgdGFiX2Vycm9yc1t0YWIuYXJncy5pZF0gPSBlcnJvcl9jb3VudDtcblxuICAgICAgICAgICAgLy8gVXBkYXRlIGJhZGdlXG4gICAgICAgICAgICBjb25zdCAkYmFkZ2UgPSB0aGlzLiRpZCgnbmF2JykuZmluZChgW2RhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiXWApO1xuICAgICAgICAgICAgaWYgKGVycm9yX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICRiYWRnZS50ZXh0KGVycm9yX2NvdW50KS5zaG93KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICRiYWRnZS5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGZpcnN0IHRhYiB3aXRoIGVycm9yc1xuICAgICAgICBjb25zdCBmaXJzdF9lcnJvcmVkX3RhYiA9IHRoaXMudGFicy5maW5kKCh0KSA9PiB0YWJfZXJyb3JzW3QuYXJncy5pZF0gPiAwKTtcblxuICAgICAgICAvLyBTd2l0Y2ggdG8gZmlyc3QgZXJyb3JlZCB0YWIgaWYgbm90IGN1cnJlbnRseSBvbiBhbiBlcnJvcmVkIHRhYlxuICAgICAgICBpZiAoZmlyc3RfZXJyb3JlZF90YWIgJiYgdGFiX2Vycm9yc1t0aGlzLmFjdGl2ZV90YWJfaWRdID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYihmaXJzdF9lcnJvcmVkX3RhYi5hcmdzLmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsZWFyX2Vycm9yX2JhZGdlcygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ25hdicpLmZpbmQoJ1tkYXRhLWVycm9yLWJhZGdlXScpLmhpZGUoKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFJzeF9UYWJcbiAqXG4gKiBJbmRpdmlkdWFsIHRhYiBwYW5lIGNvbXBvbmVudCB0aGF0IHdvcmtzIHdpdGggUnN4X1RhYnMgZm9yIGZvcm0gdmFsaWRhdGlvbi5cbiAqIFNlZSByc3hfdGFiLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gQXV0by1yZWdpc3RlcnMgd2l0aCBwYXJlbnQgUnN4X1RhYnMgY29tcG9uZW50IG9uIGNyZWF0aW9uXG4gKiAtIFNldHMgdGFiIHBhbmUgSUQgYXR0cmlidXRlIGZyb20gJGlkIGFyZ3VtZW50XG4gKiAtIERpc2NvdmVycyBhbmQgdHJhY2tzIGNoaWxkIEZvcm1fRmllbGQgY29tcG9uZW50c1xuICogLSBDb3VudHMgdmFsaWRhdGlvbiBlcnJvcnMgd2l0aGluIHRoaXMgdGFiJ3MgZmllbGRzXG4gKiAtIFByb3ZpZGVzIGVycm9yIGNvdW50IHRvIHBhcmVudCBmb3IgYmFkZ2UgZGlzcGxheVxuICovXG5jbGFzcyBSc3hfVGFiIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IHRoZSB0YWIgSUQgZHluYW1pY2FsbHkgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGF0LmFyZ3MuaWQpIHtcbiAgICAgICAgICAgIHRoYXQuJC5hdHRyKCdpZCcsIHRoYXQuYXJncy5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIHBhcmVudCBSc3hfVGFicyBhbmQgcmVnaXN0ZXJcbiAgICAgICAgdGhhdC50YWJzX2NvbnRhaW5lciA9IHRoYXQuY2xvc2VzdCgnLlJzeF9UYWJzJyk7XG4gICAgICAgIGlmICh0aGF0LnRhYnNfY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGF0LnRhYnNfY29udGFpbmVyLnJlZ2lzdGVyX3RhYih0aGF0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBhbGwgRm9ybV9GaWVsZCBjb21wb25lbnRzIHdpdGhpbiB0aGlzIHRhYlxuICAgICAgICB0aGF0LmZpZWxkcyA9IFtdO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gRmluZCBhbGwgRm9ybV9GaWVsZCBjb21wb25lbnRzIHdpdGhpbiB0aGlzIHRhYlxuICAgICAgICB0aGF0LiQuZmluZCgnLkZvcm1fRmllbGQnKS5lYWNoKChpbmRleCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmllbGRfY29tcG9uZW50ID0gJChlbGVtZW50KS5jb21wb25lbnQoKTtcbiAgICAgICAgICAgIGlmIChmaWVsZF9jb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmZpZWxkcy5wdXNoKGZpZWxkX2NvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvdW50IHZhbGlkYXRpb24gZXJyb3JzIGluIEZvcm1fRmllbGQgY29tcG9uZW50cyB3aXRoaW4gdGhpcyB0YWJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZXJyb3JzIC0gRXJyb3Igb2JqZWN0IGZyb20gZm9ybSB2YWxpZGF0aW9uIHtmaWVsZF9uYW1lOiBlcnJvcl9tZXNzYWdlfVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IENvdW50IG9mIGVycm9ycyBpbiB0aGlzIHRhYlxuICAgICAqL1xuICAgIGNvdW50X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuICAgICAgICBsZXQgY291bnQgPSAwO1xuXG4gICAgICAgIGZvciAobGV0IGZpZWxkIG9mIHRoYXQuZmllbGRzKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3JzW2ZpZWxkLmFyZ3MubmFtZV0pIHtcbiAgICAgICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvdW50O1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X0Zvcm1cbiAqXG4gKiBGb3JtIGNvbnRhaW5lciB3aXRoIHZhbGlkYXRpb24sIHN1Ym1pc3Npb24sIGFuZCB3aWRnZXQgdmFsdWUgbWFuYWdlbWVudC5cbiAqIFNlZSByc3hfZm9ybS5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIFBhcnNlcyBhbmQgc3RvcmVzIGluaXRpYWwgZm9ybSBkYXRhIGZyb20gJGRhdGEgYXR0cmlidXRlIChKU09OIG9yIG9iamVjdClcbiAqIC0gRGlzY292ZXJzIGFuZCBtYW5hZ2VzIGNoaWxkIFdpZGdldCBjb21wb25lbnRzIHZpYSB2YWxzKCkgZ2V0dGVyL3NldHRlclxuICogLSBIYW5kbGVzIGZvcm0gc3VibWlzc2lvbiB2aWEgQWpheCB0byBjb250cm9sbGVyL21ldGhvZCBlbmRwb2ludHNcbiAqIC0gQXBwbGllcyB2YWxpZGF0aW9uIGVycm9ycyB0byBmaWVsZHMgdXNpbmcgRm9ybV9VdGlsc1xuICogLSBJbnRlZ3JhdGVzIHdpdGggUnN4X1RhYnMgZm9yIHRhYi1hd2FyZSBlcnJvciBoYW5kbGluZ1xuICogLSBQcm92aWRlcyBzZWVkKCkgZnVuY3Rpb25hbGl0eSBmb3IgZGVidWcvdGVzdGluZ1xuICogLSBNYW5hZ2VzIGZvcm0gc3RhdGUgKHZhbHVlcywgZXJyb3JzKSB0aHJvdWdob3V0IGxpZmVjeWNsZVxuICovXG5jbGFzcyBSc3hfRm9ybSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlcyA9IHt9OyAvLyBDdXJyZW50IGZvcm0gdmFsdWVzIHtuYW1lOiB2YWx1ZX1cbiAgICAgICAgdGhpcy5kYXRhLmVycm9ycyA9IHt9OyAvLyBWYWxpZGF0aW9uIGVycm9ycyB7bmFtZTogZXJyb3JfbWVzc2FnZX1cbiAgICAgICAgdGhpcy50YWJzID0gbnVsbDsgLy8gUmVmZXJlbmNlIHRvIFJzeF9UYWJzIGNvbXBvbmVudCBpZiBwcmVzZW50XG5cbiAgICAgICAgLy8gUGFyc2UgaW5pdGlhbCBkYXRhIGZyb20gJGRhdGEgYXR0cmlidXRlIChlLmcuLCBmcm9tICRkYXRhPSRjbGllbnQpXG4gICAgICAgIGxldCBkYXRhID0gdGhpcy5hcmdzLmRhdGE7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBEZWNvZGUgSFRNTCBlbnRpdGllcyBiZWZvcmUgcGFyc2luZyBKU09OXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIEpTT04gaXMgcGFzc2VkIHRocm91Z2ggQmxhZGUgeyEhICEhfSBzeW50YXhcbiAgICAgICAgICAgICAgICBjb25zdCBkZWNvZGVkID0gJCgnPHRleHRhcmVhPicpLmh0bWwoZGF0YSkudGV4dCgpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSBqc29uX2RlY29kZShkZWNvZGVkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGb3JtOiBGYWlsZWQgdG8gcGFyc2UgZGF0YSBKU09OIHN0cmluZycsIGUpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhICYmIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlcyA9IGRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCBlcnJvciBjb250YWluZXIgZXhpc3RzXG4gICAgICAgIGlmICghdGhpcy4kaWQoJ2Vycm9yJykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuJC5odG1sKCkpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdSc3hfRm9ybSByZXF1aXJlcyBhbiBlcnJvciBjb250YWluZXIgd2l0aCAkaWQ9XCJlcnJvclwiLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ0FkZCA8ZGl2ICRpZD1cImVycm9yXCI+PC9kaXY+IHRvIHlvdXIgZm9ybSB0ZW1wbGF0ZSBmb3IgZGlzcGxheWluZyB2YWxpZGF0aW9uIGFuZCBlcnJvciBtZXNzYWdlcy4nXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHVwIHNlZWQgYnV0dG9uIGhhbmRsZXIgaWYgaW4gZGVidWcgbW9kZVxuICAgICAgICBpZiAod2luZG93LnJzeGFwcC5kZWJ1ZyAmJiB0aGlzLiRpZCgnc2VlZF9idG4nKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgdGhhdC4kaWQoJ3NlZWRfYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoYXQuc2VlZCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGNoaWxkIFJzeF9UYWJzIGNvbXBvbmVudCBpZiBwcmVzZW50IGZvciBlcnJvciBoYW5kbGluZyBpbnRlZ3JhdGlvblxuICAgICAgICBjb25zdCB0YWJzX2VsID0gdGhpcy4kLmZpbmQoJy5Sc3hfVGFicycpLmZpcnN0KCk7XG4gICAgICAgIGlmICh0YWJzX2VsLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhhdC50YWJzID0gdGFic19lbC5jb21wb25lbnQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEF1dG9tYXRpY2FsbHkgd2lyZSBhbGwgc3VibWl0IGJ1dHRvbnMgdG8gY2FsbCBmb3JtIHN1Ym1pdCgpXG4gICAgICAgIHRoaXMuJC5maW5kKCdidXR0b25bdHlwZT1cInN1Ym1pdFwiXScpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJCh0aGlzKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGF0LnN1Ym1pdCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE5vdGlmeSBhbGwgZmllbGRzIHRvIGxvYWQgdGhlaXIgaW5pdGlhbCB2YWx1ZXNcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIGluIG9uX3JlYWR5IHRvIGVuc3VyZSBhbGwgRm9ybV9GaWVsZCBjaGlsZHJlbiBhcmUgaW5pdGlhbGl6ZWRcbiAgICAgICAgdGhpcy52YWxzKHRoaXMuZGF0YS52YWx1ZXMpO1xuXG4gICAgICAgIC8vIEhpZGUgbG9hZGluZyBzcGlubmVyIGFuZCBzaG93IGZvcm0gY29udGVudCAod2l0aG91dCByZS1yZW5kZXJpbmcpXG4gICAgICAgIHRoaXMuJGlkKCdsb2FkZXInKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdmb3JtX2NvbnRlbnQnKS5zaG93KCk7XG4gICAgfVxuXG4gICAgLy8gR2V0dGVyIG9yIHNldHRlciBmb3IgYWxsIGZvcm0gdmFsdWVzLCBzaW1pbGFyIHRvIGpxdWVyeSB2YWxcbiAgICB2YWxzKHZhbHVlcykge1xuICAgICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcblxuICAgICAgICAgICAgdGhpcy4kLnNoYWxsb3dGaW5kKCcuV2lkZ2V0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICR3aWRnZXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkd2lkZ2V0LmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3ZhbCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB3aWRnZXRfbmFtZSA9ICR3aWRnZXQuZGF0YSgnbmFtZScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAod2lkZ2V0X25hbWUgaW4gdmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQudmFsKHZhbHVlc1t3aWRnZXRfbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBsZXQgZGF0YSA9IHt9O1xuXG4gICAgICAgICAgICAvLyBHZXQgd2lkZ2V0IHZhbHVlc1xuICAgICAgICAgICAgdGhpcy4kLnNoYWxsb3dGaW5kKCcuV2lkZ2V0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICR3aWRnZXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkd2lkZ2V0LmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3ZhbCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB3aWRnZXRfbmFtZSA9ICR3aWRnZXQuZGF0YSgnbmFtZScpO1xuICAgICAgICAgICAgICAgICAgICBkYXRhW3dpZGdldF9uYW1lXSA9IGNvbXBvbmVudC52YWwoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWxzbyBnZXQgcmVndWxhciBoaWRkZW4gaW5wdXRzIChub24td2lkZ2V0IGlucHV0cylcbiAgICAgICAgICAgIHRoaXMuJC5maW5kKCdpbnB1dFt0eXBlPVwiaGlkZGVuXCJdW25hbWVdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICRpbnB1dCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgbGV0IG5hbWUgPSAkaW5wdXQuYXR0cignbmFtZScpO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbbmFtZV0gPSAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X2Vycm9yKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5lcnJvcnNbbmFtZV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVyIGFuIGVycm9yIGluIHRoZSBmb3JtJ3MgZXJyb3IgY29udGFpbmVyXG4gICAgICpcbiAgICAgKiBIYW5kbGVzIGJvdGggZmllbGQtc3BlY2lmaWMgdmFsaWRhdGlvbiBlcnJvcnMgYW5kIGdlbmVyaWMgZXJyb3JzLlxuICAgICAqIENhbiBiZSBjYWxsZWQgYnkgZXh0ZXJuYWwgaGFuZGxlcnMgKGUuZy4sIG1vZGFsIG9uX3N1Ym1pdCkgb3IgaW50ZXJuYWxseVxuICAgICAqIGJ5IHRoZSBmb3JtJ3Mgb3duIHN1Ym1pdCgpIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J8T2JqZWN0fSBlcnJvciAtIEVycm9yIG9iamVjdCBmcm9tIEFqYXggY2FsbFxuICAgICAqL1xuICAgIGFzeW5jIHJlbmRlcl9lcnJvcihlcnJvcikge1xuICAgICAgICAvLyBIYW5kbGUgdmFsaWRhdGlvbiBlcnJvcnMgLSBhcHBseSB0byBmaWVsZHNcbiAgICAgICAgaWYgKGVycm9yLnR5cGUgPT09ICdmb3JtX2Vycm9yJyAmJiBlcnJvci5kZXRhaWxzKSB7XG4gICAgICAgICAgICBhd2FpdCBGb3JtX1V0aWxzLmFwcGx5X2Zvcm1fZXJyb3JzKHRoaXMuJCwgZXJyb3IuZGV0YWlscyk7XG5cbiAgICAgICAgICAgIC8vIE5vdGlmeSB0YWJzIG9mIHZhbGlkYXRpb24gZXJyb3JzIGZvciBlcnJvciBiYWRnZXMgYW5kIGF1dG8tc3dpdGNoaW5nXG4gICAgICAgICAgICBpZiAodGhpcy50YWJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YWJzLmhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyhlcnJvci5kZXRhaWxzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRm9ybV9VdGlscyBoYW5kbGVzIGFsbCByZW5kZXJpbmcgKGlubGluZSBlcnJvcnMgKyB1bm1hdGNoZWQgZXJyb3JzIGFsZXJ0KVxuICAgICAgICAgICAgLy8gRG9uJ3QgY2FsbCBSc3gucmVuZGVyX2Vycm9yKCkgdG8gYXZvaWQgZHVwbGljYXRlIGFsZXJ0c1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG5vbi1mb3JtIGVycm9ycyAoZmF0YWwsIGF1dGgsIG5ldHdvcmssIGV0Yy4pLCByZW5kZXIgaW4gZm9ybSdzIGVycm9yIGNvbnRhaW5lclxuICAgICAgICBSc3gucmVuZGVyX2Vycm9yKGVycm9yLCB0aGlzLiRpZCgnZXJyb3InKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgc3VibWl0KCkge1xuICAgICAgICAvLyBDbGVhciBhbnkgcHJldmlvdXMgZXJyb3JzXG4gICAgICAgIEZvcm1fVXRpbHMucmVzZXRfZm9ybV9lcnJvcnModGhpcy4kKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Vycm9yJykuZW1wdHkoKTtcblxuICAgICAgICAvLyBDbGVhciB0YWIgZXJyb3IgYmFkZ2VzIGlmIHRhYnMgYXJlIHByZXNlbnRcbiAgICAgICAgaWYgKHRoaXMudGFicykge1xuICAgICAgICAgICAgdGhpcy50YWJzLmNsZWFyX2Vycm9yX2JhZGdlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VyaWFsaXplIGFsbCBmaWVsZCB2YWx1ZXNcbiAgICAgICAgbGV0IHZhbHVlcyA9IHRoaXMudmFscygpO1xuXG4gICAgICAgIC8vIENhbGwgc3VibWl0IGhhbmRsZXJcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuY29udHJvbGxlciB8fCAhdGhpcy5hcmdzLm1ldGhvZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRm9ybTogTm8gY29udHJvbGxlci9tZXRob2QgcHJvdmlkZWQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRm9ybSBjb25maWd1cmF0aW9uIGVycm9yOiBNaXNzaW5nIGNvbnRyb2xsZXIgb3IgbWV0aG9kJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQnVpbGQgQWpheCBVUkwgZnJvbSBjb250cm9sbGVyIGFuZCBtZXRob2RcbiAgICAgICAgICAgIGNvbnN0IGFqYXhfdXJsID0gYC9fYWpheC8ke3RoaXMuYXJncy5jb250cm9sbGVyfS8ke3RoaXMuYXJncy5tZXRob2R9YDtcblxuICAgICAgICAgICAgLy8gQ2FsbCBBamF4IGVuZHBvaW50IC0gcmVzcG9uc2UgaXMgZGlyZWN0bHkgd2hhdCBQSFAgcmV0dXJuZWRcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEFqYXguY2FsbChhamF4X3VybCwgdmFsdWVzKTtcblxuICAgICAgICAgICAgLy8gU3VjY2VzcyEgSGFuZGxlIHJlc3VsdFxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQucmVkaXJlY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBSZWRpcmVjdCB0byBVUkxcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHJlc3VsdC5yZWRpcmVjdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU3VjY2VzcyB3aXRob3V0IHJlZGlyZWN0XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0Zvcm0gc3VibWl0dGVkIHN1Y2Nlc3NmdWxseScsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBSZW5kZXIgZXJyb3IgKGhhbmRsZXMgYm90aCB2YWxpZGF0aW9uIGFuZCBnZW5lcmljIGVycm9ycylcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVuZGVyX2Vycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLkZvcm1fRmllbGQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkKHRoaXMpLmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAnc2VlZCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjb21wb25lbnQuc2VlZCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFBpbl9WZXJpZmljYXRpb25fRm9ybVxuICpcbiAqIFNwZWNpYWxpemVkIDYtZGlnaXQgUElOIGVudHJ5IGZvcm0gd2l0aCBhdXRvLW5hdmlnYXRpb24gYmV0d2VlbiBpbnB1dHMuXG4gKiBTZWUgcGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gQXV0by1hZHZhbmNlcyB0byBuZXh0IGlucHV0IHdoZW4gZGlnaXQgaXMgZW50ZXJlZFxuICogLSBTbWFydCBiYWNrc3BhY2U6IGNsZWFycyBjdXJyZW50IGJveCBhbmQgbW92ZXMgdG8gcHJldmlvdXNcbiAqIC0gUGFzdGUgc3VwcG9ydDogZGlzdHJpYnV0ZXMgcGFzdGVkIGRpZ2l0cyBhY3Jvc3MgYWxsIDYgaW5wdXRzXG4gKiAtIEFycm93IGtleSBuYXZpZ2F0aW9uIGJldHdlZW4gaW5wdXRzXG4gKiAtIE51bWVyaWMtb25seSBpbnB1dCB2YWxpZGF0aW9uXG4gKiAtIFNlbGVjdC1hbGwgb24gZm9jdXMgZm9yIGVhc3kgZGlnaXQgcmVwbGFjZW1lbnRcbiAqIC0gVmFsaWRhdGVzIGFsbCA2IGRpZ2l0cyBlbnRlcmVkIGJlZm9yZSBhbGxvd2luZyBzdWJtaXNzaW9uXG4gKiAtIFByb3ZpZGVzIHZhbCgpIGdldHRlci9zZXR0ZXIgZm9yIHByb2dyYW1tYXRpYyBQSU4gYWNjZXNzXG4gKi9cbmNsYXNzIFBpbl9WZXJpZmljYXRpb25fRm9ybSBleHRlbmRzIFJzeF9Gb3JtIHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHN1cGVyLm9uX2NyZWF0ZSgpO1xuICAgICAgICB0aGlzLnBpbl9sZW5ndGggPSA2O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgdGhlIFBJTiB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIFBJTiAoZGlzdHJpYnV0ZXMgYWNyb3NzIGlucHV0cylcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBDdXJyZW50IFBJTiB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIGNvbGxlY3QgYWxsIGRpZ2l0c1xuICAgICAgICAgICAgbGV0IHBpbiA9ICcnO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHBpbiArPSB0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbCgpIHx8ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBpbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGRpc3RyaWJ1dGUgZGlnaXRzIGFjcm9zcyBpbnB1dHNcbiAgICAgICAgICAgIGNvbnN0IGRpZ2l0cyA9IHN0cih2YWx1ZSB8fCAnJykucmVwbGFjZSgvW14wLTldL2csICcnKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbChkaWdpdHNbaV0gfHwgJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRm9jdXMgZmlyc3QgZW1wdHkgaW5wdXQgb3IgbGFzdCBpbnB1dFxuICAgICAgICAgICAgY29uc3QgZmlyc3RfZW1wdHkgPSB0aGlzLl9maW5kX2ZpcnN0X2VtcHR5X2luZGV4KCk7XG4gICAgICAgICAgICBpZiAoZmlyc3RfZW1wdHkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7Zmlyc3RfZW1wdHl9YClbMF0uZm9jdXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7dGhpcy5waW5fbGVuZ3RoIC0gMX1gKVswXS5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmluZCB0aGUgZmlyc3QgZW1wdHkgaW5wdXQgaW5kZXhcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBJbmRleCBvZiBmaXJzdCBlbXB0eSBpbnB1dCwgb3IgLTEgaWYgYWxsIGZpbGxlZFxuICAgICAqL1xuICAgIF9maW5kX2ZpcnN0X2VtcHR5X2luZGV4KCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuJGlkKGBkaWdpdF8ke2l9YCkudmFsKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW92ZSBmb2N1cyB0byBzcGVjaWZpYyBpbnB1dCBpbmRleFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICAgICAqL1xuICAgIF9mb2N1c19pbnB1dChpbmRleCkge1xuICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMucGluX2xlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoYGRpZ2l0XyR7aW5kZXh9YCk7XG4gICAgICAgICAgICBpZiAoJGlucHV0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgJGlucHV0WzBdLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgLy8gU2VsZWN0IHRoZSBjb250ZW50IGlmIHRoZXJlIGlzIGFueVxuICAgICAgICAgICAgICAgICRpbnB1dFswXS5zZWxlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBwYXN0ZSBldmVudCAtIGRpc3RyaWJ1dGUgZGlnaXRzIGFjcm9zcyBpbnB1dHNcbiAgICAgKiBAcGFyYW0ge0NsaXBib2FyZEV2ZW50fSBlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0X2luZGV4XG4gICAgICovXG4gICAgX2hhbmRsZV9wYXN0ZShlLCBzdGFydF9pbmRleCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gR2V0IHBhc3RlZCBkYXRhXG4gICAgICAgIGNvbnN0IHBhc3RlID0gKGUub3JpZ2luYWxFdmVudCB8fCBlKS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQnKTtcbiAgICAgICAgY29uc3QgZGlnaXRzID0gcGFzdGUucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICBpZiAoIWRpZ2l0cykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGlzdHJpYnV0ZSBkaWdpdHMgc3RhcnRpbmcgZnJvbSBjdXJyZW50IGlucHV0XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlnaXRzLmxlbmd0aCAmJiAoc3RhcnRfaW5kZXggKyBpKSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtzdGFydF9pbmRleCArIGl9YCkudmFsKGRpZ2l0c1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb2N1cyBuZXh0IGVtcHR5IGlucHV0IG9yIGxhc3QgaW5wdXRcbiAgICAgICAgY29uc3QgbmV4dF9pbmRleCA9IE1hdGgubWluKHN0YXJ0X2luZGV4ICsgZGlnaXRzLmxlbmd0aCwgdGhpcy5waW5fbGVuZ3RoIC0gMSk7XG4gICAgICAgIHRoaXMuX2ZvY3VzX2lucHV0KG5leHRfaW5kZXgpO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFNldCB1cCBldmVudCBoYW5kbGVycyBmb3IgZWFjaCBpbnB1dFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZChgZGlnaXRfJHtpfWApO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBpO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUgaW5wdXQgZXZlbnQgLSBhdXRvLWFkdmFuY2VcbiAgICAgICAgICAgICRpbnB1dC5vbignaW5wdXQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuXG4gICAgICAgICAgICAgICAgLy8gT25seSBhbGxvdyBudW1lcmljIGlucHV0XG4gICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHZhbHVlLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG4gICAgICAgICAgICAgICAgaWYgKG51bWVyaWMgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykudmFsKG51bWVyaWMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIG11bHRpcGxlIGRpZ2l0cyB3ZXJlIGVudGVyZWQgKHBhc3RlKSwgZGlzdHJpYnV0ZSB0aGVtXG4gICAgICAgICAgICAgICAgaWYgKG51bWVyaWMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9oYW5kbGVfcGFzdGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6ICgpID0+IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxFdmVudDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXBib2FyZERhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RGF0YTogKCkgPT4gbnVtZXJpY1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXV0by1hZHZhbmNlIHRvIG5leHQgaW5wdXQgaWYgZGlnaXQgd2FzIGVudGVyZWRcbiAgICAgICAgICAgICAgICBpZiAobnVtZXJpYy5sZW5ndGggPT09IDEgJiYgaW5kZXggPCB0aGF0LnBpbl9sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4ICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBrZXlkb3duIGZvciBiYWNrc3BhY2VcbiAgICAgICAgICAgICRpbnB1dC5vbigna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBCYWNrc3BhY2Uga2V5XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQmFja3NwYWNlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50X3ZhbHVlID0gJCh0aGlzKS52YWwoKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBjdXJyZW50IGlucHV0IGlzIGVtcHR5LCBtb3ZlIHRvIHByZXZpb3VzIGFuZCBjbGVhciBpdFxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRfdmFsdWUgJiYgaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0LiRpZChgZGlnaXRfJHtpbmRleCAtIDF9YCkudmFsKCcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgY3VycmVudCBpbnB1dCBoYXMgdmFsdWUsIGl0IHdpbGwgYmUgY2xlYXJlZCBieSBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBzdGF5IG9uIGN1cnJlbnQgaW5wdXRcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcnJvdyBsZWZ0XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQXJyb3dMZWZ0JyAmJiBpbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9mb2N1c19pbnB1dChpbmRleCAtIDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFycm93IHJpZ2h0XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQXJyb3dSaWdodCcgJiYgaW5kZXggPCB0aGF0LnBpbl9sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fZm9jdXNfaW5wdXQoaW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gSGFuZGxlIHBhc3RlIGV2ZW50XG4gICAgICAgICAgICAkaW5wdXQub24oJ3Bhc3RlJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuX2hhbmRsZV9wYXN0ZShlLCBpbmRleCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gU2VsZWN0IGFsbCBvbiBmb2N1cyBmb3IgZWFzeSByZXBsYWNlbWVudFxuICAgICAgICAgICAgJGlucHV0Lm9uKCdmb2N1cycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICQodGhpcylbMF0uc2VsZWN0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvY3VzIGZpcnN0IGlucHV0IG9uIGxvYWRcbiAgICAgICAgdGhpcy5fZm9jdXNfaW5wdXQoMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgc3VibWl0IHRvIHZhbGlkYXRlIFBJTiBpcyBjb21wbGV0ZVxuICAgICAqL1xuICAgIGFzeW5jIHN1Ym1pdCgpIHtcbiAgICAgICAgY29uc3QgcGluID0gdGhpcy52YWwoKTtcblxuICAgICAgICAvLyBDbGVhciBwcmV2aW91cyBlcnJvcnNcbiAgICAgICAgdGhpcy4kaWQoJ2Vycm9yX2NvbnRhaW5lcicpLmhpZGUoKS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIFBJTiBpcyA2IGRpZ2l0c1xuICAgICAgICBpZiAocGluLmxlbmd0aCAhPT0gdGhpcy5waW5fbGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnZXJyb3JfY29udGFpbmVyJylcbiAgICAgICAgICAgICAgICAudGV4dCgnUGxlYXNlIGVudGVyIGFsbCA2IGRpZ2l0cycpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcblxuICAgICAgICAgICAgLy8gTWFyayBpbnB1dHMgYXMgaW52YWxpZFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS52YWwoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtpfWApLmFkZENsYXNzKCdpcy1pbnZhbGlkJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgaW52YWxpZCBjbGFzcyBmcm9tIGFsbCBpbnB1dHNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS5yZW1vdmVDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgc3VibWl0ICh3aGljaCB3aWxsIHVzZSBjb250cm9sbGVyL21ldGhvZCBpZiBwcm92aWRlZClcbiAgICAgICAgYXdhaXQgc3VwZXIuc3VibWl0KCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBGb3JtX0ZpZWxkX0Fic3RyYWN0XG4gKlxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZm9ybSBmaWVsZCB3cmFwcGVycy4gUHJvdmlkZXMgY29yZSBmdW5jdGlvbmFsaXR5IHdpdGhvdXQgdmlzdWFsIGZvcm1hdHRpbmcuXG4gKiBTZWUgZm9ybV9maWVsZF9hYnN0cmFjdC5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIERpc2NvdmVycyBhbmQgY29uZmlndXJlcyBjaGlsZCBXaWRnZXQgY29tcG9uZW50XG4gKiAtIFNldHMgZGF0YS1uYW1lIGF0dHJpYnV0ZSBvbiB3aWRnZXQgZm9yIGZvcm0gdmFsdWUgY29sbGVjdGlvblxuICogLSBTZXRzIG5hbWUgYXR0cmlidXRlIG9uIG5hdGl2ZSBpbnB1dHMgZm9yIEZvcm1fVXRpbHMgY29tcGF0aWJpbGl0eVxuICogLSBXaXJlcyBsYWJlbCAnZm9yJyBhdHRyaWJ1dGUgdG8gaW5wdXQgZWxlbWVudCBJRCBmb3IgYWNjZXNzaWJpbGl0eSAoaWYgbGFiZWwgZXhpc3RzKVxuICogLSBQcm92aWRlcyBzZWVkKCkgc3VwcG9ydCBmb3IgZGVidWcvdGVzdGluZyBkYXRhXG4gKiAtIEJyaWRnZXMgYmV0d2VlbiBmb3JtIHZhbGlkYXRpb24gc3RhdGUgYW5kIGNoaWxkIHdpZGdldFxuICovXG5jbGFzcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBGaW5kIHBhcmVudCBmb3JtIGZvciBlcnJvciBkaXNwbGF5XG4gICAgICAgIHRoaXMuZm9ybSA9IHRoaXMuY2xvc2VzdCgnLlJzeF9Gb3JtJyk7XG4gICAgICAgIGlmICghdGhpcy5mb3JtKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Zvcm1fRmllbGRfQWJzdHJhY3QgbXVzdCBiZSBpbnNpZGUgYSBSc3hfRm9ybSBjb21wb25lbnQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBGaW5kIGNoaWxkIHdpZGdldCBhbmQgc2V0IGl0cyBkYXRhLW5hbWUgYXR0cmlidXRlXG4gICAgICAgIGxldCAkd2lkZ2V0ID0gdGhpcy4kLmZpbmQoJy5XaWRnZXQnKS5maXJzdCgpO1xuXG4gICAgICAgIGlmICghJHdpZGdldC5leGlzdHMoKSkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKFxuICAgICAgICAgICAgICAgIGBGb3JtX0ZpZWxkX0Fic3RyYWN0IFwiJHt0aGlzLmFyZ3MubmFtZX1cIiBoYXMgbm8gLldpZGdldCBjaGlsZC4gRXZlcnkgRm9ybV9GaWVsZCBtdXN0IGNvbnRhaW4gZXhhY3RseSBvbmUgd2lkZ2V0IChUZXh0X0lucHV0LCBXeXNpd3lnX0lucHV0LCBldGMuKWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGF0YS1uYW1lIG9uIHRoZSB3aWRnZXQgc28gUnN4X0Zvcm0gY2FuIGNvbGxlY3QgdmFsdWVzXG4gICAgICAgICR3aWRnZXQuYXR0cignZGF0YS1uYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuXG4gICAgICAgIGxldCAkaW5wdXQgPSB0aGlzLiQuZmluZCgnaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEnKS5maXJzdCgpO1xuICAgICAgICBpZiAoJGlucHV0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICAvLyBBbHNvIHNldCBuYW1lIGF0dHJpYnV0ZSBvbiBuYXRpdmUgaW5wdXRzIGZvciBGb3JtX1V0aWxzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgICAgIC8vIFRvZG86IGNsZXZlciB3YXkgdG8gZGVhbCB3aXRoIHRoaXMgZm9yIG5vbiBzdGFuZGFyZCBpbnB1dCBlbGVtZW50c1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG5cbiAgICAgICAgICAgIC8vIFNldCB0aGUgZm9yIGZpZWxkIHRvIHRoZSBlbGVtZW50IGlmIGxhYmVsIGV4aXN0cyAoZm9yIGNoaWxkIGNsYXNzZXMpXG4gICAgICAgICAgICAvLyBUb2RvOiBjbGV2ZXIgd2F5IHRvIGRlYWwgd2l0aCB0aGlzIGZvciBub24gc3RhbmRhcmQgaW5wdXQgZWxlbWVudHNcbiAgICAgICAgICAgIGxldCAkbGFiZWwgPSB0aGlzLiRpZCgnZm9ybV9sYWJlbCcpO1xuICAgICAgICAgICAgaWYgKCRsYWJlbC5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICRsYWJlbC5hdHRyKCdmb3InLCAkaW5wdXQuYXR0cignaWQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZXJyb3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0X2Vycm9yKHRoaXMuYXJncy5uYW1lKTtcbiAgICB9XG5cbiAgICBoYXNfZXJyb3IoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuZ2V0X2Vycm9yKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3Muc2VlZGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGNoaWxkIHdpZGdldFxuICAgICAgICBsZXQgJHdpZGdldCA9IHRoaXMuJC5maW5kKCcuV2lkZ2V0JykuZmlyc3QoKTtcbiAgICAgICAgaWYgKCEkd2lkZ2V0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgd2lkZ2V0X2NvbXBvbmVudCA9ICR3aWRnZXQuY29tcG9uZW50KCk7XG4gICAgICAgIGlmICghd2lkZ2V0X2NvbXBvbmVudCB8fCAhd2lkZ2V0X2NvbXBvbmVudC52YWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgdGhlIHNlZWRlciBlbmRwb2ludCAoQWpheCByb3V0ZSByZWZlcmVuY2UgbGlrZSBmb3JtICRhY3Rpb24pXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBhd2FpdCBBamF4LmNhbGwodGhpcy5hcmdzLnNlZWRlciwge30pO1xuICAgICAgICAgICAgd2lkZ2V0X2NvbXBvbmVudC52YWwodmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgU2VlZGVyIGVycm9yIGZvciAke3RoaXMuYXJncy5uYW1lfTpgLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fRmllbGRcbiAqXG4gKiBGb3JtIGZpZWxkIHdyYXBwZXIgdGhhdCBhZGRzIGxhYmVscywgaGVscCB0ZXh0LCBhbmQgcmVxdWlyZWQgaW5kaWNhdG9ycy5cbiAqIFNlZSBmb3JtX2ZpZWxkLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEV4dGVuZHMgRm9ybV9GaWVsZF9BYnN0cmFjdCB0byBpbmhlcml0IGFsbCBjb3JlIGZ1bmN0aW9uYWxpdHkuXG4gKiBUaGlzIGNsYXNzIGV4aXN0cyBwcmltYXJpbHkgZm9yIHRlbXBsYXRlIGluaGVyaXRhbmNlIGFuZCBhbnkgZnV0dXJlXG4gKiBmb3JtYXR0ZWQtZmllbGQtc3BlY2lmaWMgYmVoYXZpb3IuXG4gKi9cbmNsYXNzIEZvcm1fRmllbGQgZXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IHtcbiAgICAvLyBBbGwgZnVuY3Rpb25hbGl0eSBpbmhlcml0ZWQgZnJvbSBGb3JtX0ZpZWxkX0Fic3RyYWN0XG4gICAgLy8gVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgZm9ybWF0dGVkIHZpc3VhbCB3cmFwcGVyIHZpYSBpdHMgdGVtcGxhdGVcbn1cbiIsIi8qKlxuICogRm9ybV9IaWRkZW5fRmllbGQgLSBIaWRkZW4gaW5wdXQgZmllbGQgY29tcG9uZW50XG4gKlxuICogRXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IGJ1dCBJUyB0aGUgaW5wdXQgZWxlbWVudCBpdHNlbGYgKHVzaW5nIHRhZz1cImlucHV0XCIgdHlwZT1cImhpZGRlblwiKS5cbiAqIFNlZSBmb3JtX2hpZGRlbl9maWVsZC5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIFNldHMgdmFsdWUgYXR0cmlidXRlIGR5bmFtaWNhbGx5IGluIG9uX2NyZWF0ZSgpXG4gKiAtIE92ZXJyaWRlcyBvbl9yZWFkeSgpIHRvIGhhbmRsZSB0aGF0IHRoaXMuJCBJUyBib3RoIHRoZSB3aWRnZXQgYW5kIHRoZSBpbnB1dFxuICogLSBQcm92aWRlcyB2YWwoKSBtZXRob2QgZm9yIGdldHRpbmcvc2V0dGluZyB0aGUgaGlkZGVuIHZhbHVlXG4gKi9cbmNsYXNzIEZvcm1fSGlkZGVuX0ZpZWxkIGV4dGVuZHMgRm9ybV9GaWVsZF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBzZXQgdXAgZm9ybSByZWZlcmVuY2VcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG5cbiAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWUgYXR0cmlidXRlIChjYW4ndCBiZSBkb25lIGluIERlZmluZSB0YWcpXG4gICAgICAgIHRoaXMuJC5hdHRyKCd2YWx1ZScsICcnKTtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gT3ZlcnJpZGUgcGFyZW50IG9uX3JlYWR5KCkgYmVjYXVzZSB0aGlzLiQgSVMgdGhlIHdpZGdldCBhbmQgdGhlIGlucHV0XG4gICAgICAgIC8vIFNldCBkYXRhLW5hbWUgb24gdGhpcy4kICh3aGljaCBpcyB0aGUgaW5wdXQgZWxlbWVudClcbiAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcblxuICAgICAgICAvLyBTZXQgbmFtZSBhdHRyaWJ1dGUgb24gdGhpcy4kIGZvciBGb3JtX1V0aWxzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgdGhpcy4kLmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBoaWRkZW4gaW5wdXQgdmFsdWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IHZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gdGhpcy4kIGlzIHRoZSBpbnB1dCBlbGVtZW50IGl0c2VsZlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuJC52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSB0aGUgaW5wdXQgdmFsdWUgZGlyZWN0bHkgKHRoaXMuJCBpcyB0aGUgaW5wdXQpXG4gICAgICAgICAgICB0aGlzLiQudmFsKHZhbHVlIHx8ICcnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjwhLS1cblRlc3RfTW9kYWxfRm9ybVxuXG5TaW1wbGUgdGVzdCBmb3JtIGZvciBkZW1vbnN0cmF0aW5nIG1vZGFsIGZvcm0gZnVuY3Rpb25hbGl0eS5cbkRlbW9uc3RyYXRlcyB0ZXh0IGlucHV0cywgZHJvcGRvd24sIGFuZCB2YWxpZGF0aW9uIGVycm9yIGhhbmRsaW5nLlxuLS0+XG48RGVmaW5lOlRlc3RfTW9kYWxfRm9ybSB0YWc9XCJkaXZcIj5cbiAgICA8ZGl2IGNsYXNzPVwibWItNFwiPlxuICAgICAgICA8aDUgY2xhc3M9XCJ0ZXh0LW11dGVkIG1iLTNcIj5Vc2VyIEluZm9ybWF0aW9uPC9oNT5cblxuICAgICAgICA8ZGl2ICRpZD1cImVycm9yX2NvbnRhaW5lclwiPjwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJuYW1lXCIgY2xhc3M9XCJmb3JtLWxhYmVsXCI+RnVsbCBOYW1lIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAkaWQ9XCJuYW1lX2lucHV0XCJcbiAgICAgICAgICAgICAgICAgICBuYW1lPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciB5b3VyIGZ1bGwgbmFtZVwiPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICA8bGFiZWwgZm9yPVwiZW1haWxcIiBjbGFzcz1cImZvcm0tbGFiZWxcIj5FbWFpbCBBZGRyZXNzIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgJGlkPVwiZW1haWxfaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgIG5hbWU9XCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ1c2VyQGV4YW1wbGUuY29tXCI+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJyb2xlXCIgY2xhc3M9XCJmb3JtLWxhYmVsXCI+Um9sZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgJGlkPVwicm9sZV9zZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicm9sZVwiPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgYSByb2xlIC0tPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImFkbWluXCI+QWRtaW5pc3RyYXRvcjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtYW5hZ2VyXCI+TWFuYWdlcjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ1c2VyXCI+VXNlcjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJndWVzdFwiPkd1ZXN0PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L0RlZmluZTpUZXN0X01vZGFsX0Zvcm0+XG4iLCI8IS0tXG5Db250YWN0c19EYXRhR3JpZFxuXG5DdXN0b20gZGF0YWdyaWQgZm9yIGNvbnRhY3RzIHdpdGggc3BlY2lhbGl6ZWQgcm93IHJlbmRlcmluZy5cbldyYXBzIGJhc2UgRGF0YUdyaWQgY29tcG9uZW50LlxuXG5BUkdVTUVOVFM6XG4gICAgJGFwaSAtIEFQSSBjb250cm9sbGVyIGNsYXNzXG4tLT5cbjxEZWZpbmU6RGF0YUdyaWRfQWJzdHJhY3QgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8Q2FyZF9IZWFkZXI+XG4gICAgICAgIDwlPSBjb250ZW50KCdER19DYXJkX0hlYWRlcicpOyAlPlxuICAgIDwvQ2FyZF9IZWFkZXI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IHAtMFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtaG92ZXIgbWItMFwiPlxuICAgICAgICAgICAgICAgIDx0aGVhZCAkcmVkcmF3YWJsZSAkaWQ9XCJkYXRhZ3JpZF90YWJsZV9oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCU9IGNvbnRlbnQoJ0RHX1RhYmxlX0hlYWRlcicpOyAlPlxuICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgPHRib2R5ICRyZWRyYXdhYmxlICRpZD1cImRhdGFncmlkX3RhYmxlX2JvZHlcIiBjbGFzcz1cIjwlPSAodGhpcy5kYXRhLmxvYWRpbmcgJiYgdGhpcy5kYXRhLnJvd3MubGVuZ3RoID09PSAwKSA/ICdpcy1sb2FkaW5nJyA6ICh0aGlzLmRhdGEuaXNfZW1wdHkgPyAnaXMtZW1wdHknIDogJycpICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmRhdGEubG9hZGluZyAmJiB0aGlzLmRhdGEucm93cy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImxvYWRpbmctcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49XCI5OTlcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHRleHQtcHJpbWFyeSBtYi0zXCIgcm9sZT1cInN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5Mb2FkaW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+TG9hZGluZy4uLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmICh0aGlzLmRhdGEuaXNfZW1wdHkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImVtcHR5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiOTk5XCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktaW5ib3hcIiBzdHlsZT1cImZvbnQtc2l6ZTogM3JlbTsgY29sb3I6ICM2Yzc1N2Q7XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5kYXRhLmZpbHRlcikgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkIG10LTNcIj5ObyByZXN1bHRzIGZvdW5kIGZvciBcIjwlPSB0aGlzLmRhdGEuZmlsdGVyICU+XCI8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICRpZD1cImNsZWFyX2ZpbHRlcl9idG5cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLXNlY29uZGFyeSBtdC0yXCI+Q2xlYXIgRmlsdGVyPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQtbXV0ZWQgbXQtM1wiPk5vIHJlc3VsdHMgZm91bmQ8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlIGZvcihsZXQgcm93IG9mIHRoaXMuZGF0YS5yb3dzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCU9IGNvbnRlbnQoJ3JvdycsIHJvdyk7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8Q2FyZF9Gb290ZXI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTIgYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnkgYnRuLXNtIGRyb3Bkb3duLXRvZ2dsZVwiIHR5cGU9XCJidXR0b25cIiBkYXRhLWJzLXRvZ2dsZT1cImRyb3Bkb3duXCI+XG4gICAgICAgICAgICAgICAgICAgIEFjdGlvbnNcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJkcm9wZG93bi1tZW51XCI+XG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIiBocmVmPVwiI1wiPkV4cG9ydCBTZWxlY3RlZDwvYT48L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGk+PGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIj5EZWxldGUgU2VsZWN0ZWQ8L2E+PC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwiZHJvcGRvd24tZGl2aWRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGk+PGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIj5NYXJrIGFzIEFjdGl2ZTwvYT48L2xpPlxuICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxQYWdpbmF0aW9uX0luZm8gJGlkPVwicGFnaW5hdGlvbl9pbmZvXCI+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50b3RhbCAmJiB0aGlzLmRhdGEucGFnZSAmJiB0aGlzLmRhdGEucGVyX3BhZ2UpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCVcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gKCh0aGlzLmRhdGEucGFnZSAtIDEpICogdGhpcy5kYXRhLnBlcl9wYWdlKSArIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmQgPSBNYXRoLm1pbih0aGlzLmRhdGEucGFnZSAqIHRoaXMuZGF0YS5wZXJfcGFnZSwgdGhpcy5kYXRhLnRvdGFsKTtcbiAgICAgICAgICAgICAgICAgICAgJT5cbiAgICAgICAgICAgICAgICAgICAgU2hvd2luZyA8JT0gc3RhcnQgJT4gdG8gPCU9IGVuZCAlPiBvZiA8JT0gdGhpcy5kYXRhLnRvdGFsICU+IGVudHJpZXNcbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L1BhZ2luYXRpb25fSW5mbz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPFBhZ2luYXRpb25fQ29udHJvbHMgJGlkPVwicGFnaW5hdGlvbl9jb250cm9sc1wiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50b3RhbF9wYWdlcyAmJiB0aGlzLmRhdGEudG90YWxfcGFnZXMgPiAxKSB7ICU+XG4gICAgICAgICAgICAgICAgPCVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFBhZ2UgPSB0aGlzLmRhdGEucGFnZSB8fCAxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0b3RhbFBhZ2VzID0gdGhpcy5kYXRhLnRvdGFsX3BhZ2VzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhWaXNpYmxlID0gNzsgLy8gTWF4aW11bSBwYWdlIG51bWJlcnMgdG8gc2hvd1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBwYWdlIHJhbmdlIHRvIGRpc3BsYXlcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN0YXJ0UGFnZSwgZW5kUGFnZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodG90YWxQYWdlcyA8PSBtYXhWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaG93IGFsbCBwYWdlcyBpZiB0b3RhbCBpcyBsZXNzIHRoYW4gbWF4XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFBhZ2UgPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kUGFnZSA9IHRvdGFsUGFnZXM7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgcmFuZ2Ugd2l0aCBjdXJyZW50IHBhZ2UgbmVhciBjZW50ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heFBhZ2VzQmVmb3JlQ3VycmVudFBhZ2UgPSBNYXRoLmZsb29yKG1heFZpc2libGUgLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heFBhZ2VzQWZ0ZXJDdXJyZW50UGFnZSA9IE1hdGguY2VpbChtYXhWaXNpYmxlIC8gMikgLSAxO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFBhZ2UgPD0gbWF4UGFnZXNCZWZvcmVDdXJyZW50UGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lYXIgdGhlIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRQYWdlID0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gbWF4VmlzaWJsZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFBhZ2UgKyBtYXhQYWdlc0FmdGVyQ3VycmVudFBhZ2UgPj0gdG90YWxQYWdlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lYXIgdGhlIGVuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UGFnZSA9IHRvdGFsUGFnZXMgLSBtYXhWaXNpYmxlICsgMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gdG90YWxQYWdlcztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UGFnZSA9IGN1cnJlbnRQYWdlIC0gbWF4UGFnZXNCZWZvcmVDdXJyZW50UGFnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gY3VycmVudFBhZ2UgKyBtYXhQYWdlc0FmdGVyQ3VycmVudFBhZ2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBwYWdlIG51bWJlcnMgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFnZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0UGFnZTsgaSA8PSBlbmRQYWdlOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaG93U3RhcnRFbGxpcHNpcyA9IHN0YXJ0UGFnZSA+IDE7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3dFbmRFbGxpcHNpcyA9IGVuZFBhZ2UgPCB0b3RhbFBhZ2VzO1xuICAgICAgICAgICAgICAgICU+XG5cbiAgICAgICAgICAgICAgICA8JS0tIFByZXZpb3VzIGJ1dHRvbiAtLSU+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSBjdXJyZW50UGFnZSA9PT0gMSA/ICdkaXNhYmxlZCcgOiAnJyAlPlwiPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IGN1cnJlbnRQYWdlIC0gMSAlPlwiIHRhYmluZGV4PVwiPCU9IGN1cnJlbnRQYWdlID09PSAxID8gJy0xJyA6ICcwJyAlPlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUHJldmlvdXNcbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwvbGk+XG5cbiAgICAgICAgICAgICAgICA8JS0tIEZpcnN0IHBhZ2UgKyBlbGxpcHNpcyAtLSU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHNob3dTdGFydEVsbGlwc2lzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBocmVmPVwiI1wiIGRhdGEtcGFnZT1cIjFcIj4xPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGFnZS1saW5rXCI+Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cblxuICAgICAgICAgICAgICAgIDwlLS0gUGFnZSBudW1iZXJzIC0tJT5cbiAgICAgICAgICAgICAgICA8JSBmb3IgKGxldCBwYWdlTnVtIG9mIHBhZ2VzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlIGNvbnNvbGUubG9nKFwiTG9vcCBjaGVja1wiLCBwYWdlTnVtLCBjdXJyZW50UGFnZSk7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbSA8JT0gcGFnZU51bSA9PT0gY3VycmVudFBhZ2UgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IHBhZ2VOdW0gJT5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8JT0gcGFnZU51bSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cblxuICAgICAgICAgICAgICAgIDwlLS0gRWxsaXBzaXMgKyBsYXN0IHBhZ2UgLS0lPlxuICAgICAgICAgICAgICAgIDwlIGlmIChzaG93RW5kRWxsaXBzaXMpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIGRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhZ2UtbGlua1wiPi4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IHRvdGFsUGFnZXMgJT5cIj48JT0gdG90YWxQYWdlcyAlPjwvYT5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG5cbiAgICAgICAgICAgICAgICA8JS0tIE5leHQgYnV0dG9uIC0tJT5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gPCU9IGN1cnJlbnRQYWdlID09PSB0b3RhbFBhZ2VzID8gJ2Rpc2FibGVkJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiBkYXRhLXBhZ2U9XCI8JT0gY3VycmVudFBhZ2UgKyAxICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBOZXh0XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L1BhZ2luYXRpb25fQ29udHJvbHM+XG4gICAgPC9DYXJkX0Zvb3Rlcj5cblxuPC9EZWZpbmU6RGF0YUdyaWRfQWJzdHJhY3Q+IiwiPERlZmluZTpBY3Rpb25fQnV0dG9uX0RlbGV0ZSB0YWc9XCJidXR0b25cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG48L0RlZmluZTpBY3Rpb25fQnV0dG9uX0RlbGV0ZT5cbiIsIjxEZWZpbmU6QWN0aW9uX0J1dHRvbl9FZGl0IHRhZz1cImFcIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuPC9EZWZpbmU6QWN0aW9uX0J1dHRvbl9FZGl0PlxuIiwiPERlZmluZTpBY3Rpb25fQnV0dG9uX1ZpZXcgdGFnPVwiYVwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3XCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuPC9EZWZpbmU6QWN0aW9uX0J1dHRvbl9WaWV3PlxuIiwiPERlZmluZTpBY3Rpdml0eV9GZWVkIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCI+XG4gIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS00XCI+XG4gICAgICA8U3Bpbm5lciAvPlxuICAgICAgPGRpdiBjbGFzcz1cIm10LTIgdGV4dC1tdXRlZCBzbWFsbFwiPkxvYWRpbmcgYWN0aXZpdHkuLi48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPCUgfSBlbHNlIGlmICh0aGlzLmRhdGEuYWN0aXZpdGllcyAmJiB0aGlzLmRhdGEuYWN0aXZpdGllcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICA8RW1wdHlfU3RhdGVcbiAgICAgICRpY29uPVwiYWN0aXZpdHlcIlxuICAgICAgJHRpdGxlPVwiTm8gYWN0aXZpdHkgeWV0XCJcbiAgICAgICRtZXNzYWdlPVwiQWN0aXZpdHkgd2lsbCBhcHBlYXIgaGVyZVwiXG4gICAgLz5cbiAgPCUgfSBlbHNlIHsgJT5cbiAgICA8JSBmb3IgKGxldCBhY3Rpdml0eSBvZiB0aGlzLmRhdGEuYWN0aXZpdGllcyB8fCBbXSkgeyAlPlxuICAgICAgPGRpdiBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBkLWZsZXggZ2FwLTMgcHktM1wiPlxuICAgICAgICA8JSBpZiAoYWN0aXZpdHkuYXZhdGFyKSB7ICU+XG4gICAgICAgICAgPEF2YXRhciAkc3JjPWFjdGl2aXR5LmF2YXRhciAkc2l6ZT1cInNtXCIgLz5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZC1jaXJjbGUgYmctcHJpbWFyeSB0ZXh0LXdoaXRlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIHN0eWxlPVwid2lkdGg6IDMycHg7IGhlaWdodDogMzJweDsgZmxleC1zaHJpbms6IDA7XCI+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLTwlPSBhY3Rpdml0eS5pY29uIHx8ICdhY3Rpdml0eScgJT5cIj48L2k+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIH0gJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPHN0cm9uZz48JT0gYWN0aXZpdHkudXNlcl9uYW1lICU+PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSBhY3Rpdml0eS5hY3Rpb24gJT48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj48JT0gYWN0aXZpdHkudGltZV9hZ28gJT48L3NtYWxsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwlIGlmIChhY3Rpdml0eS5kZXNjcmlwdGlvbikgeyAlPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGwgbXQtMVwiPjwlPSBhY3Rpdml0eS5kZXNjcmlwdGlvbiAlPjwvZGl2PlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSBpZiAoYWN0aXZpdHkubWV0YWRhdGEpIHsgJT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yXCI+XG4gICAgICAgICAgICAgIDwlIGZvciAobGV0IGtleSBpbiBhY3Rpdml0eS5tZXRhZGF0YSkgeyAlPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctbGlnaHQgdGV4dC1kYXJrIG1lLTFcIj5cbiAgICAgICAgICAgICAgICAgIDwlPSBrZXkgJT46IDwlPSBhY3Rpdml0eS5tZXRhZGF0YVtrZXldICU+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuICA8JSB9ICU+XG48L0RlZmluZTpBY3Rpdml0eV9GZWVkPlxuIiwiPERlZmluZTpBY3Rvcl9SZWZlcmVuY2UgdGFnPVwic21hbGxcIiBjbGFzcz1cInRleHQtbXV0ZWQgZC1ibG9jayBtdC0xXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkFjdG9yX1JlZmVyZW5jZT5cbiIsIjxEZWZpbmU6QWR2YW5jZWRfU2VhcmNoX1BhbmVsIGNsYXNzPVwiY2FyZFwiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIj5BZHZhbmNlZCBTZWFyY2g8L2g1PlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgJGlkPVwiY2xvc2VfYnRuXCI+PC9idXR0b24+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5XCI+XG4gICAgPGZvcm0gJGlkPVwic2VhcmNoX2Zvcm1cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cbiAgICAgICAgICA8SW5wdXRfV2l0aF9WYWxpZGF0aW9uXG4gICAgICAgICAgICAkbGFiZWw9XCJLZXl3b3Jkc1wiXG4gICAgICAgICAgICAkcGxhY2Vob2xkZXI9XCJTZWFyY2gga2V5d29yZHMuLi5cIlxuICAgICAgICAgICAgJG5hbWU9XCJrZXl3b3Jkc1wiXG4gICAgICAgICAgICAkaWQ9XCJrZXl3b3Jkc1wiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICAgIDxTZWFyY2hhYmxlX1NlbGVjdFxuICAgICAgICAgICAgJGxhYmVsPVwiQ2F0ZWdvcnlcIlxuICAgICAgICAgICAgJHBsYWNlaG9sZGVyPVwiU2VsZWN0IGNhdGVnb3J5XCJcbiAgICAgICAgICAgICRpZD1cImNhdGVnb3J5XCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPE11bHRpX1NlbGVjdFxuICAgICAgICAgICAgJGxhYmVsPVwiVGFnc1wiXG4gICAgICAgICAgICAkcGxhY2Vob2xkZXI9XCJTZWxlY3QgdGFnc1wiXG4gICAgICAgICAgICAkaWQ9XCJ0YWdzXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPERhdGVfUGlja2VyXG4gICAgICAgICAgICAkbGFiZWw9XCJGcm9tIERhdGVcIlxuICAgICAgICAgICAgJGlkPVwiZnJvbV9kYXRlXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPERhdGVfUGlja2VyXG4gICAgICAgICAgICAkbGFiZWw9XCJUbyBEYXRlXCJcbiAgICAgICAgICAgICRpZD1cInRvX2RhdGVcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPlNvcnQgQnk8L2xhYmVsPlxuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiICRpZD1cInNvcnRfYnlcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJyZWxldmFuY2VcIj5SZWxldmFuY2U8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJkYXRlXCI+RGF0ZTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInRpdGxlXCI+VGl0bGU8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiICRpZD1cImV4YWN0X21hdGNoXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCI+XG4gICAgICAgICAgICAgIEV4YWN0IG1hdGNoIG9ubHlcbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9mb3JtPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtZm9vdGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxuICAgIDxCdXR0b25fU2Vjb25kYXJ5ICRpZD1cInJlc2V0X2J0blwiPlJlc2V0PC9CdXR0b25fU2Vjb25kYXJ5PlxuICAgIDxCdXR0b25fUHJpbWFyeSAkaWQ9XCJzZWFyY2hfYnRuXCI+U2VhcmNoPC9CdXR0b25fUHJpbWFyeT5cbiAgPC9kaXY+XG48L0RlZmluZTpBZHZhbmNlZF9TZWFyY2hfUGFuZWw+XG4iLCI8RGVmaW5lOkFsZXJ0X0Jhbm5lciBjbGFzcz1cImFsZXJ0IGFsZXJ0LWluZm8gYWxlcnQtZGlzbWlzc2libGUgZmFkZSBzaG93XCIgcm9sZT1cImFsZXJ0XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbiAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiBkYXRhLWJzLWRpc21pc3M9XCJhbGVydFwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPjwvYnV0dG9uPlxuPC9EZWZpbmU6QWxlcnRfQmFubmVyPlxuIiwiPERlZmluZTpBdmF0YXIgdGFnPVwiaW1nXCIgY2xhc3M9XCJyb3VuZGVkLWNpcmNsZVwiIGFsdD1cIlVzZXIgYXZhdGFyXCI+XG48L0RlZmluZTpBdmF0YXI+XG4iLCI8RGVmaW5lOkJsb2NrcXVvdGUgdGFnPVwiYmxvY2txdW90ZVwiIGNsYXNzPVwiYmxvY2txdW90ZVwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCbG9ja3F1b3RlPlxuIiwiPERlZmluZTpCcmVhZGNydW1icyB0YWc9XCJuYXZcIiBhcmlhLWxhYmVsPVwiYnJlYWRjcnVtYlwiPlxuICA8b2wgY2xhc3M9XCJicmVhZGNydW1iIG1iLTBcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvb2w+XG48L0RlZmluZTpCcmVhZGNydW1icz5cbiIsIjxEZWZpbmU6QnVsa19BY3Rpb25fQmFyIGNsYXNzPVwiYWxlcnQgYWxlcnQtcHJpbWFyeSBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTNcIiByb2xlPVwiYWxlcnRcIj5cbiAgPGRpdj5cbiAgICA8c3Ryb25nIGNsYXNzPVwiY291bnRcIj4wPC9zdHJvbmc+IGl0ZW1zIHNlbGVjdGVkXG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgJGlkPVwiY2xvc2VfYnRuXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+PC9idXR0b24+XG4gIDwvZGl2PlxuPC9EZWZpbmU6QnVsa19BY3Rpb25fQmFyPlxuIiwiPERlZmluZTpCdWxrX1NlbGVjdGlvbiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgJGlkPVwiY2hlY2tib3hcIlxuICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbGVjdCBhbGxcIiAvPlxuPC9EZWZpbmU6QnVsa19TZWxlY3Rpb24+XG4iLCI8RGVmaW5lOkJ1dHRvbl9Hcm91cCBjbGFzcz1cImJ0bi1ncm91cFwiIHJvbGU9XCJncm91cFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fR3JvdXA+XG4iLCI8RGVmaW5lOkJ1dHRvbl9QcmltYXJ5IHRhZz1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdHlwZT1cImJ1dHRvblwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fUHJpbWFyeT5cbiIsIjxEZWZpbmU6QnV0dG9uX1NlY29uZGFyeSB0YWc9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdHlwZT1cImJ1dHRvblwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fU2Vjb25kYXJ5PlxuIiwiPERlZmluZTpCdXR0b24gdGFnPVwiYnV0dG9uXCIgY2xhc3M9XCJidG5cIiB0eXBlPVwiYnV0dG9uXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkJ1dHRvbj5cbiIsIjxEZWZpbmU6Q2FsZW5kYXJfRXZlbnQgY2xhc3M9XCJjYXJkIG1iLTJcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTJcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLXN0YXJ0IGdhcC0yXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYmctPCU9IHRoaXMuYXJncy5jb2xvciB8fCAncHJpbWFyeScgJT4gcm91bmRlZFwiIHN0eWxlPVwid2lkdGg6IDRweDsgaGVpZ2h0OiAxMDAlOyBtaW4taGVpZ2h0OiA0MHB4O1wiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmdy1ib2xkIHNtYWxsXCI+PCU9IHRoaXMuYXJncy50aXRsZSAlPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2xvY2sgbWUtMVwiPjwvaT5cbiAgICAgICAgICA8JT0gdGhpcy5hcmdzLnRpbWUgJT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubG9jYXRpb24pIHsgJT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1nZW8tYWx0IG1lLTFcIj48L2k+XG4gICAgICAgICAgICA8JT0gdGhpcy5hcmdzLmxvY2F0aW9uICU+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIH0gJT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhbGVuZGFyX0V2ZW50PlxuIiwiPERlZmluZTpDYWxlbmRhcl9HcmlkIGNsYXNzPVwiY2FyZFwiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgJGlkPVwicHJldl9idG5cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLWxlZnRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiAkaWQ9XCJ0b2RheV9idG5cIj5Ub2RheTwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiICRpZD1cIm5leHRfYnRuXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1yaWdodFwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIiAkaWQ9XCJtb250aF90aXRsZVwiPjwvaDU+XG4gICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLXZpZXc9XCJtb250aFwiPk1vbnRoPC9idXR0b24+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS12aWV3PVwid2Vla1wiPldlZWs8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtYm9yZGVyZWQgbWItMFwiPlxuICAgICAgPHRoZWFkIGNsYXNzPVwidGFibGUtbGlnaHRcIj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+U3VuPC90aD5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPk1vbjwvdGg+XG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5UdWU8L3RoPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+V2VkPC90aD5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlRodTwvdGg+XG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5Gcmk8L3RoPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+U2F0PC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHkgJGlkPVwiY2FsZW5kYXJfYm9keVwiPlxuICAgICAgICA8IS0tIEdlbmVyYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG48L0RlZmluZTpDYWxlbmRhcl9HcmlkPlxuIiwiPERlZmluZTpDYXJkX0Zvb3RlciBjbGFzcz1cImNhcmQtZm9vdGVyIGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhcmRfRm9vdGVyPlxuIiwiPERlZmluZTpDYXJkX0hlYWRlciBjbGFzcz1cImNhcmQtaGVhZGVyIGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhcmRfSGVhZGVyPlxuIiwiPERlZmluZTpDYXJkX1RpdGxlIHRhZz1cImg1XCIgY2xhc3M9XCJtYi0wXCI+XG5cbiAgICA8JT0gY29udGVudCgpICU+XG5cbjwvRGVmaW5lOkNhcmRfVGl0bGU+IiwiPERlZmluZTpDYXJkIGNsYXNzPVwiY2FyZFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG5cbjwvRGVmaW5lOkNhcmQ+XG4iLCI8RGVmaW5lOkNoYXJ0X0NvbXBvbmVudCBjbGFzcz1cImNoYXJ0LXBsYWNlaG9sZGVyIGJnLWxpZ2h0IHJvdW5kZWQgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciB0ZXh0LW11dGVkIHAtNVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktZ3JhcGgtdXAgZnMtMSBkLWJsb2NrIG1iLTJcIj48L2k+XG4gICAgPHAgY2xhc3M9XCJtYi0wXCI+Q2hhcnQgQ29tcG9uZW50PC9wPlxuICAgIDxzbWFsbD5QbGFjZWhvbGRlciBmb3IgZnV0dXJlIGNoYXJ0IGludGVncmF0aW9uPC9zbWFsbD5cbiAgPC9kaXY+XG48L0RlZmluZTpDaGFydF9Db21wb25lbnQ+XG4iLCI8RGVmaW5lOkNoZWNrYm94IHRhZz1cImlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCI+XG48L0RlZmluZTpDaGVja2JveD5cbiIsIjxEZWZpbmU6Q29kZV9CbG9jayB0YWc9XCJwcmVcIiBjbGFzcz1cInAtMyBiZy1kYXJrIHRleHQtbGlnaHQgcm91bmRlZFwiPlxuICA8Y29kZT48JT0gY29udGVudCgpICU+PC9jb2RlPlxuPC9EZWZpbmU6Q29kZV9CbG9jaz5cbiIsIjxEZWZpbmU6Q29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGJ0bi1zbSBkcm9wZG93bi10b2dnbGVcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktY29sdW1uc1wiPjwvaT4gQ29sdW1uc1xuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiICRpZD1cIm1lbnVcIj5cbiAgICA8IS0tIER5bmFtaWNhbGx5IHBvcHVsYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgPC91bD5cbjwvRGVmaW5lOkNvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZT5cbiIsIjxEZWZpbmU6Q29tbWVudF9UaHJlYWQgY2xhc3M9XCJjYXJkXCI+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPGg1IGNsYXNzPVwibWItMFwiPkNvbW1lbnRzICg8c3BhbiAkaWQ9XCJjb21tZW50X2NvdW50XCI+PCU9ICh0aGlzLmRhdGEuY29tbWVudHMgfHwgW10pLmxlbmd0aCAlPjwvc3Bhbj4pPC9oNT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8ZGl2ICRpZD1cImNvbW1lbnRzXCI+XG4gICAgICA8JSBpZiAoT2JqZWN0LmtleXModGhpcy5kYXRhKS5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTRcIj5cbiAgICAgICAgICA8U3Bpbm5lciAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNvbW1lbnRzICYmIHRoaXMuZGF0YS5jb21tZW50cy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgPEVtcHR5X1N0YXRlXG4gICAgICAgICAgJGljb249XCJjaGF0LWxlZnQtdGV4dFwiXG4gICAgICAgICAgJHRpdGxlPVwiTm8gY29tbWVudHMgeWV0XCJcbiAgICAgICAgICAkbWVzc2FnZT1cIkJlIHRoZSBmaXJzdCB0byBjb21tZW50XCJcbiAgICAgICAgLz5cbiAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgIDwlIGZvciAobGV0IGNvbW1lbnQgb2YgdGhpcy5kYXRhLmNvbW1lbnRzIHx8IFtdKSB7ICU+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMyBtYi00XCIgZGF0YS1jb21tZW50LWlkPVwiPCU9IGNvbW1lbnQuaWQgJT5cIj5cbiAgICAgICAgICAgIDxBdmF0YXIgJHNyYz1jb21tZW50LmF2YXRhciAkbmFtZT1jb21tZW50LnVzZXJfbmFtZSAkc2l6ZT1cInNtXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmctbGlnaHQgcm91bmRlZCBwLTNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLXN0YXJ0IG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+PCU9IGNvbW1lbnQudXNlcl9uYW1lICU+PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IGNvbW1lbnQudGltZV9hZ28gJT48L3NtYWxsPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXY+PCU9IGNvbW1lbnQudGV4dCAlPjwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTJcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGJ0bi1zbSBwLTAgbWUtMyByZXBseS1idG5cIj5SZXBseTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwlIGlmIChjb21tZW50LmNhbl9lZGl0KSB7ICU+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGJ0bi1zbSBwLTAgbWUtMyBlZGl0LWJ0blwiPkVkaXQ8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNvbW1lbnQuY2FuX2RlbGV0ZSkgeyAlPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGluayBidG4tc20gcC0wIHRleHQtZGFuZ2VyIGRlbGV0ZS1idG5cIj5EZWxldGU8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8JSBpZiAoY29tbWVudC5yZXBsaWVzICYmIGNvbW1lbnQucmVwbGllcy5sZW5ndGggPiAwKSB7ICU+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1zLTQgbXQtM1wiPlxuICAgICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgcmVwbHkgb2YgY29tbWVudC5yZXBsaWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTMgbWItM1wiIGRhdGEtY29tbWVudC1pZD1cIjwlPSByZXBseS5pZCAlPlwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxBdmF0YXIgJHNyYz1yZXBseS5hdmF0YXIgJG5hbWU9cmVwbHkudXNlcl9uYW1lICRzaXplPVwieHNcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJnLWxpZ2h0IHJvdW5kZWQgcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtc3RhcnQgbWItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmcgY2xhc3M9XCJzbWFsbFwiPjwlPSByZXBseS51c2VyX25hbWUgJT48L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IHJlcGx5LnRpbWVfYWdvICU+PC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbWFsbFwiPjwlPSByZXBseS50ZXh0ICU+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8JSB9ICU+XG4gICAgICA8JSB9ICU+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE5ldyBjb21tZW50IGZvcm0gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm10LTQgcHQtNCBib3JkZXItdG9wXCIgJGlkPVwibmV3X2NvbW1lbnRfZm9ybVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtM1wiPlxuICAgICAgICA8QXZhdGFyICRzcmM9dGhpcy5hcmdzLmN1cnJlbnRfdXNlcl9hdmF0YXIgJG5hbWU9dGhpcy5hcmdzLmN1cnJlbnRfdXNlcl9uYW1lICRzaXplPVwic21cIiAvPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1ncm93LTFcIj5cbiAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2wgbWItMlwiIHJvd3M9XCIzXCIgcGxhY2Vob2xkZXI9XCJXcml0ZSBhIGNvbW1lbnQuLi5cIiAkaWQ9XCJjb21tZW50X2lucHV0XCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICA8QnV0dG9uX1ByaW1hcnkgJGlkPVwic3VibWl0X2J0blwiPlBvc3QgQ29tbWVudDwvQnV0dG9uX1ByaW1hcnk+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Q29tbWVudF9UaHJlYWQ+XG4iLCI8RGVmaW5lOkNvbnRhY3RfQWN0aW9ucyB0YWc9XCJ0ZFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpDb250YWN0X0FjdGlvbnM+XG4iLCI8RGVmaW5lOkNvbnRhY3RfUm93IHRhZz1cInRyXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkNvbnRhY3RfUm93PlxuIiwiPERlZmluZTpDb250YWN0c19EYXRhX1RhYmxlIHRhZz1cImRpdlwiIGNsYXNzPVwiY2FyZC1ib2R5IHAtMFwiPlxuICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWhvdmVyIG1iLTBcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiA0MHB4O1wiPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGg+XG4gICAgICAgICAgPHRoPklEPC90aD5cbiAgICAgICAgICA8dGg+TmFtZTwvdGg+XG4gICAgICAgICAgPHRoPkVtYWlsPC90aD5cbiAgICAgICAgICA8dGg+UGhvbmU8L3RoPlxuICAgICAgICAgIDx0aD5Db21wYW55PC90aD5cbiAgICAgICAgICA8dGg+Um9sZTwvdGg+XG4gICAgICAgICAgPHRoPlN0YXR1czwvdGg+XG4gICAgICAgICAgPHRoPkNyZWF0ZWQ8L3RoPlxuICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMDBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+PGEgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCI+I0NUMDAxPC9hPjwvdGQ+XG4gICAgICAgICAgPHRkPjxhIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiPkphbmUgU21pdGg8L2E+PC90ZD5cbiAgICAgICAgICA8dGQ+PGEgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCI+amFuZUBhY21lLmNvbTwvYT48L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSAxMjMtNDU2NzwvdGQ+XG4gICAgICAgICAgPHRkPkFjbWUgQ29ycG9yYXRpb248L3RkPlxuICAgICAgICAgIDx0ZD5DRU88L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE1LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDI8L3RkPlxuICAgICAgICAgIDx0ZD5Cb2IgSm9obnNvbjwvdGQ+XG4gICAgICAgICAgPHRkPmJvYkB0ZWNoc29sdXRpb25zLmlvPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgMjM0LTU2Nzg8L3RkPlxuICAgICAgICAgIDx0ZD5UZWNoIFNvbHV0aW9ucyBJbmM8L3RkPlxuICAgICAgICAgIDx0ZD5DVE88L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE4LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDM8L3RkPlxuICAgICAgICAgIDx0ZD5TYXJhaCBXaWxzb248L3RkPlxuICAgICAgICAgIDx0ZD5zYXJhaEBnbG9iYWxlbnQuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgMzQ1LTY3ODk8L3RkPlxuICAgICAgICAgIDx0ZD5HbG9iYWwgRW50ZXJwcmlzZXM8L3RkPlxuICAgICAgICAgIDx0ZD5Qcm9qZWN0IE1hbmFnZXI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5QZW5kaW5nPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkZlYiAwMiwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+I0NUMDA0PC90ZD5cbiAgICAgICAgICA8dGQ+TWljaGFlbCBCcm93bjwvdGQ+XG4gICAgICAgICAgPHRkPm1icm93bkBpbm5vdmF0aW9uLmNvPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgNDU2LTc4OTA8L3RkPlxuICAgICAgICAgIDx0ZD5TdGFydFVwIElubm92YXRpb25zPC90ZD5cbiAgICAgICAgICA8dGQ+RGV2ZWxvcGVyPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkZlYiAxMCwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+I0NUMDA1PC90ZD5cbiAgICAgICAgICA8dGQ+RW1pbHkgRGF2aXM8L3RkPlxuICAgICAgICAgIDx0ZD5lbWlseUB3aWxzb24uY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgNTY3LTg5MDE8L3RkPlxuICAgICAgICAgIDx0ZD5XaWxzb24gJiBBc3NvY2lhdGVzPC90ZD5cbiAgICAgICAgICA8dGQ+TWFya2V0aW5nIERpcmVjdG9yPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5TdXNwZW5kZWQ8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+RmViIDE1LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDY8L3RkPlxuICAgICAgICAgIDx0ZD5EYXZpZCBNYXJ0aW5lejwvdGQ+XG4gICAgICAgICAgPHRkPmRhdmlkQGRtcHByby5jb208L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSA2NzgtOTAxMjwvdGQ+XG4gICAgICAgICAgPHRkPkRpZ2l0YWwgTWFya2V0aW5nIFBybzwvdGQ+XG4gICAgICAgICAgPHRkPlNhbGVzIE1hbmFnZXI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+TWFyIDAxLCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDc8L3RkPlxuICAgICAgICAgIDx0ZD5KZW5uaWZlciBBbmRlcnNvbjwvdGQ+XG4gICAgICAgICAgPHRkPmplbm5pZmVyQGFuZGVyc29uaW5kLm5ldDwvdGQ+XG4gICAgICAgICAgPHRkPig1NTUpIDc4OS0wMTIzPC90ZD5cbiAgICAgICAgICA8dGQ+QW5kZXJzb24gSW5kdXN0cmllczwvdGQ+XG4gICAgICAgICAgPHRkPkNGTzwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXIgMDUsIDIwMjQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCIgdGl0bGU9XCJWaWV3XCI+PGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj48aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGQ+XG4gICAgICAgICAgPHRkPiNDVDAwODwvdGQ+XG4gICAgICAgICAgPHRkPlJvYmVydCBUaG9tcHNvbjwvdGQ+XG4gICAgICAgICAgPHRkPnJvYmVydEBjcmVhdGl2ZXN0dWRpb3MuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgODkwLTEyMzQ8L3RkPlxuICAgICAgICAgIDx0ZD5DcmVhdGl2ZSBTdHVkaW9zIExMQzwvdGQ+XG4gICAgICAgICAgPHRkPkFydCBEaXJlY3RvcjwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPlBlbmRpbmc8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+TWFyIDEyLCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDk8L3RkPlxuICAgICAgICAgIDx0ZD5MaXNhIEdhcmNpYTwvdGQ+XG4gICAgICAgICAgPHRkPmxpc2FAZ2FyY2lhY29uc3VsdC5jb208L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSA5MDEtMjM0NTwvdGQ+XG4gICAgICAgICAgPHRkPkdhcmNpYSBDb25zdWx0aW5nPC90ZD5cbiAgICAgICAgICA8dGQ+Q29uc3VsdGFudDwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXIgMTgsIDIwMjQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCIgdGl0bGU9XCJWaWV3XCI+PGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj48aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGQ+XG4gICAgICAgICAgPHRkPiNDVDAxMDwvdGQ+XG4gICAgICAgICAgPHRkPkNocmlzdG9waGVyIFdoaXRlPC90ZD5cbiAgICAgICAgICA8dGQ+Y2hyaXNAd2hpdGVwYXJ0bmVycy5vcmc8L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSAwMTItMzQ1NjwvdGQ+XG4gICAgICAgICAgPHRkPldoaXRlICYgUGFydG5lcnM8L3RkPlxuICAgICAgICAgIDx0ZD5QYXJ0bmVyPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPk1hciAyMiwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Q29udGFjdHNfRGF0YV9UYWJsZT5cbiIsIjxEZWZpbmU6Q29udGFjdHNfTGlzdF9DYXJkIHRhZz1cImRpdlwiIGNsYXNzPVwiY2FyZFwiPlxuXG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuXG48L0RlZmluZTpDb250YWN0c19MaXN0X0NhcmQ+XG4iLCI8RGVmaW5lOkRhdGVfUGlja2VyIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPjwlPSB0aGlzLmFyZ3MubGFiZWwgJT48L2xhYmVsPlxuICA8JSB9ICU+XG4gIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPlxuICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jYWxlbmRhclwiPjwvaT5cbiAgICA8L3NwYW4+XG4gICAgPGlucHV0XG4gICAgICB0eXBlPVwiZGF0ZVwiXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgJGlkPVwiaW5wdXRcIlxuICAgIC8+XG4gIDwvZGl2PlxuICA8JSBpZiAodGhpcy5hcmdzLmhlbHApIHsgJT5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+PCU9IHRoaXMuYXJncy5oZWxwICU+PC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkRhdGVfUGlja2VyPlxuIiwiPERlZmluZTpEcm9wZG93bl9NZW51IGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZVwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiXG4gICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICAkaWQ9XCJ0b2dnbGVcIj5cbiAgICA8JT0gdGhpcy5hcmdzLmxhYmVsIHx8ICdNZW51JyAlPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudVwiIGFyaWEtbGFiZWxsZWRieT1cInRvZ2dsZVwiICRpZD1cIm1lbnVcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvdWw+XG48L0RlZmluZTpEcm9wZG93bl9NZW51PlxuIiwiPERlZmluZTpFbXB0eV9TdGF0ZSBjbGFzcz1cInRleHQtY2VudGVyIHB5LTVcIj5cbiAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC1tdXRlZFwiIHN0eWxlPVwiZm9udC1zaXplOiAzcmVtO1wiPlxuICAgIDxJY29uICRuYW1lPSh0aGlzLmFyZ3MuaWNvbiB8fCAnaW5ib3gnKSAvPlxuICA8L2Rpdj5cbiAgPGg1IGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MudGl0bGUgfHwgJ05vIGl0ZW1zIGZvdW5kJyAlPjwvaDU+XG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MubWVzc2FnZSB8fCAnR2V0IHN0YXJ0ZWQgYnkgY3JlYXRpbmcgYSBuZXcgaXRlbS4nICU+PC9wPlxuICA8JSBpZiAodGhpcy5hcmdzLmFjdGlvbl9sYWJlbCkgeyAlPlxuICAgIDxCdXR0b25fUHJpbWFyeT48JT0gdGhpcy5hcmdzLmFjdGlvbl9sYWJlbCAlPjwvQnV0dG9uX1ByaW1hcnk+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkVtcHR5X1N0YXRlPlxuIiwiPERlZmluZTpFeHBvcnRfQnV0dG9uIGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tPCU9IHRoaXMuYXJncy52YXJpYW50IHx8ICdwcmltYXJ5JyAlPiBkcm9wZG93bi10b2dnbGVcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktZG93bmxvYWRcIj48L2k+XG4gICAgPCU9IHRoaXMuYXJncy5sYWJlbCB8fCAnRXhwb3J0JyAlPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudVwiPlxuICAgIDxsaT5cbiAgICAgIDxhIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIGhyZWY9XCIjXCIgZGF0YS1mb3JtYXQ9XCJjc3ZcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1jc3YgbWUtMlwiPjwvaT5cbiAgICAgICAgRXhwb3J0IGFzIENTVlxuICAgICAgPC9hPlxuICAgIDwvbGk+XG4gICAgPGxpPlxuICAgICAgPGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIiBkYXRhLWZvcm1hdD1cImV4Y2VsXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZmlsZXR5cGUteGxzeCBtZS0yXCI+PC9pPlxuICAgICAgICBFeHBvcnQgYXMgRXhjZWxcbiAgICAgIDwvYT5cbiAgICA8L2xpPlxuICAgIDxsaT5cbiAgICAgIDxhIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIGhyZWY9XCIjXCIgZGF0YS1mb3JtYXQ9XCJwZGZcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1wZGYgbWUtMlwiPjwvaT5cbiAgICAgICAgRXhwb3J0IGFzIFBERlxuICAgICAgPC9hPlxuICAgIDwvbGk+XG4gICAgPGxpPlxuICAgICAgPGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIiBkYXRhLWZvcm1hdD1cImpzb25cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1qc29uIG1lLTJcIj48L2k+XG4gICAgICAgIEV4cG9ydCBhcyBKU09OXG4gICAgICA8L2E+XG4gICAgPC9saT5cbiAgPC91bD5cbjwvRGVmaW5lOkV4cG9ydF9CdXR0b24+XG4iLCI8RGVmaW5lOkZpbGVfVXBsb2FkIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPjwlPSB0aGlzLmFyZ3MubGFiZWwgJT48L2xhYmVsPlxuICA8JSB9ICU+XG4gIDxkaXYgY2xhc3M9XCJib3JkZXIgcm91bmRlZCBwLTQgdGV4dC1jZW50ZXJcIiAkaWQ9XCJkcm9wX3pvbmVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjsgdHJhbnNpdGlvbjogYWxsIDAuMnM7XCI+XG4gICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJkLW5vbmVcIiAkaWQ9XCJmaWxlX2lucHV0XCIgLz5cbiAgICA8ZGl2ICRpZD1cInBsYWNlaG9sZGVyXCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLWNsb3VkLXVwbG9hZCBmcy0xIHRleHQtbXV0ZWRcIj48L2k+XG4gICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtcHJpbWFyeVwiPkNsaWNrIHRvIHVwbG9hZDwvc3Bhbj4gb3IgZHJhZyBhbmQgZHJvcFxuICAgICAgPC9kaXY+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLmFjY2VwdCkgeyAlPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtdC0xXCI+PCU9IHRoaXMuYXJncy5hY2NlcHQgJT48L2Rpdj5cbiAgICAgIDwlIH0gJT5cbiAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4X3NpemUpIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIj5NYXggc2l6ZTogPCU9IHRoaXMuYXJncy5tYXhfc2l6ZSAlPjwvZGl2PlxuICAgICAgPCUgfSAlPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgJGlkPVwiZmlsZV9pbmZvXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxlLWVhcm1hcmsgZnMtMSB0ZXh0LXN1Y2Nlc3NcIj48L2k+XG4gICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiICRpZD1cImZpbGVfbmFtZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIiAkaWQ9XCJmaWxlX3NpemVcIj48L2Rpdj5cbiAgICAgIDxCdXR0b25fU2Vjb25kYXJ5ICRpZD1cInJlbW92ZV9idG5cIiBjbGFzcz1cIm10LTJcIj5SZW1vdmU8L0J1dHRvbl9TZWNvbmRhcnk+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAkaWQ9XCJwcm9ncmVzc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgIDxQcm9ncmVzc19CYXIgJGlkPVwicHJvZ3Jlc3NfYmFyXCIgLz5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG10LTJcIj5VcGxvYWRpbmcuLi48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6RmlsZV9VcGxvYWQ+XG4iLCI8RGVmaW5lOkZpbHRlcl9CYXIgY2xhc3M9XCJjYXJkIG1iLTNcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxuICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zIGFsaWduLWl0ZW1zLWVuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgc21hbGwgdGV4dC1tdXRlZCBtYi0xXCI+U2VhcmNoPC9sYWJlbD5cbiAgICAgICAgPElucHV0X1dpdGhfSWNvbiAkaWNvbj1cInNlYXJjaFwiICRwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiICRpZD1cInNlYXJjaFwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIHRleHQtbXV0ZWQgbWItMVwiPlN0YXR1czwvbGFiZWw+XG4gICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiICRpZD1cInN0YXR1c1wiPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5BbGw8L29wdGlvbj5cbiAgICAgICAgPC9zZWxlY3Q+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIHRleHQtbXV0ZWQgbWItMVwiPkRhdGUgUmFuZ2U8L2xhYmVsPlxuICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiAkaWQ9XCJkYXRlX3JhbmdlXCI+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPkFsbCBUaW1lPC9vcHRpb24+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInRvZGF5XCI+VG9kYXk8L29wdGlvbj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwid2Vla1wiPlRoaXMgV2Vlazwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtb250aFwiPlRoaXMgTW9udGg8L29wdGlvbj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY3VzdG9tXCI+Q3VzdG9tIFJhbmdlPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLWF1dG9cIiAkaWQ9XCJjdXN0b21fZGF0ZXNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxEYXRlX1BpY2tlciAkaWQ9XCJzdGFydF9kYXRlXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCIgJGlkPVwiY3VzdG9tX2RhdGVzX2VuZFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPERhdGVfUGlja2VyICRpZD1cImVuZF9kYXRlXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvIG1zLWF1dG9cIj5cbiAgICAgICAgPEJ1dHRvbl9TZWNvbmRhcnkgJGlkPVwiY2xlYXJfYnRuXCI+Q2xlYXIgRmlsdGVyczwvQnV0dG9uX1NlY29uZGFyeT5cbiAgICAgICAgPEJ1dHRvbl9QcmltYXJ5ICRpZD1cImFwcGx5X2J0blwiIGNsYXNzPVwibXMtMlwiPkFwcGx5PC9CdXR0b25fUHJpbWFyeT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtdC0zXCIgJGlkPVwiYWN0aXZlX2ZpbHRlcnNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkIG1lLTJcIj5BY3RpdmUgZmlsdGVyczo8L3NtYWxsPlxuICAgICAgPGRpdiBjbGFzcz1cImQtaW5saW5lLWJsb2NrXCIgJGlkPVwiZmlsdGVyX3RhZ3NcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpGaWx0ZXJfQmFyPlxuIiwiPERlZmluZTpGb3JtX0FjdGlvbnNfQ29tcG9uZW50IHRhZz1cImRpdlwiIGNsYXNzPVwibXQtM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmNhbmNlbF91cmwpIHsgJT5cbiAgICA8YSBocmVmPVwiPCU9IHRoaXMuYXJncy5jYW5jZWxfdXJsICU+XCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiPjwlPSB0aGlzLmFyZ3MuY2FuY2VsX3RleHQgfHwgJ0NhbmNlbCcgJT48L2E+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHR5cGU9XCJzdWJtaXRcIj48JT0gdGhpcy5hcmdzLnN1Ym1pdF90ZXh0IHx8ICdTYXZlJyAlPjwvYnV0dG9uPlxuPC9EZWZpbmU6Rm9ybV9BY3Rpb25zX0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9GaWVsZF9Hcm91cCBjbGFzcz1cImNhcmQgbWItM1wiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXJcIj5cbiAgICA8aDUgY2xhc3M9XCJtYi0wXCI+PCU9IHRoaXMuYXJncy50aXRsZSB8fCAnRm9ybSBTZWN0aW9uJyAlPjwvaDU+XG4gICAgPCUgaWYgKHRoaXMuYXJncy5kZXNjcmlwdGlvbikgeyAlPlxuICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MuZGVzY3JpcHRpb24gJT48L3NtYWxsPlxuICAgIDwlIH0gJT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Rm9ybV9GaWVsZF9Hcm91cD5cbiIsIjxEZWZpbmU6Rm9ybV9Hcm91cF9Db21wb25lbnQgdGFnPVwiZGl2XCI+XG4gIDxkaXY+XG4gICAgPCUgaWYgKHRoaXMuYXJncy5sYWJlbCkgeyAlPlxuICAgICAgPGxhYmVsIGZvcj1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIj48JT0gdGhpcy5hcmdzLmxhYmVsICU+PC9sYWJlbD5cbiAgICA8JSB9ICU+XG4gICAgPCUgaWYgKHRoaXMuYXJncy50eXBlID09PSAnc2VsZWN0JykgeyAlPlxuICAgICAgPCUgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkgeyAlPlxuICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiByZXF1aXJlZD5cbiAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgaWQ9XCI8JT0gdGhpcy5hcmdzLmlkICU+XCI+XG4gICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgJT48L29wdGlvbj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwlIH0gJT5cbiAgICA8JSB9IGVsc2UgaWYgKHRoaXMuYXJncy50eXBlID09PSAndGV4dGFyZWEnKSB7ICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbFwiIGlkPVwiPCU9IHRoaXMuYXJncy5pZCAlPlwiIHJvd3M9XCI8JT0gdGhpcy5hcmdzLnJvd3MgfHwgNCAlPlwiIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiIHJlcXVpcmVkPjwvdGV4dGFyZWE+XG4gICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiByb3dzPVwiPCU9IHRoaXMuYXJncy5yb3dzIHx8IDQgJT5cIiBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIj48L3RleHRhcmVhPlxuICAgICAgPCUgfSAlPlxuICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbFwiIGlkPVwiPCU9IHRoaXMuYXJncy5pZCAlPlwiIHR5cGU9XCI8JT0gdGhpcy5hcmdzLnR5cGUgfHwgJ3RleHQnICU+XCIgcGxhY2Vob2xkZXI9XCI8JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICcnICU+XCIgcmVxdWlyZWQ+XG4gICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiB0eXBlPVwiPCU9IHRoaXMuYXJncy50eXBlIHx8ICd0ZXh0JyAlPlwiIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiPlxuICAgICAgPCUgfSAlPlxuICAgIDwlIH0gJT5cbiAgPC9kaXY+XG48L0RlZmluZTpGb3JtX0dyb3VwX0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9Sb3dfQ29tcG9uZW50IHRhZz1cImRpdlwiIGNsYXNzPVwicm93XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkZvcm1fUm93X0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkZvcm1fVmFsaWRhdGlvbl9NZXNzYWdlPlxuIiwiPERlZmluZTpHYW50dF9DaGFydCBjbGFzcz1cImNhcmRcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyXCI+XG4gICAgPGg1IGNsYXNzPVwibWItMFwiPjwlPSB0aGlzLmFyZ3MudGl0bGUgfHwgJ1Byb2plY3QgVGltZWxpbmUnICU+PC9oNT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWJvcmRlcmVkIG1iLTBcIiBzdHlsZT1cInRhYmxlLWxheW91dDogZml4ZWQ7XCI+XG4gICAgICAgIDx0aGVhZCBjbGFzcz1cInRhYmxlLWxpZ2h0XCI+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDIwMHB4O1wiPlRhc2s8L3RoPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgbW9udGggb2YgdGhpcy5kYXRhLm1vbnRocyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBzbWFsbFwiPjwlPSBtb250aCAlPjwvdGg+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCB0YXNrIG9mIHRoaXMuZGF0YS50YXNrcyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYWxpZ24tbWlkZGxlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctYm9sZFwiPjwlPSB0YXNrLm5hbWUgJT48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwlIGlmICh0YXNrLmFzc2lnbmVlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj48JT0gdGFzay5hc3NpZ25lZSAlPjwvc21hbGw+XG4gICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmRhdGEubW9udGhzIHx8IFtdKS5sZW5ndGg7IGkrKykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0xIGFsaWduLW1pZGRsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGFzay5zdGFydF9tb250aCA8PSBpICYmIHRhc2suZW5kX21vbnRoID49IGkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmctPCU9IHRhc2suY29sb3IgfHwgJ3ByaW1hcnknICU+IHJvdW5kZWQgcC0yIHRleHQtd2hpdGUgc21hbGwgdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlPSB0YXNrLnN0YXJ0X21vbnRoID09PSBpID8gdGFzay5uYW1lIDogJycgJT5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpHYW50dF9DaGFydD5cbiIsIjxEZWZpbmU6SWNvbl9CdXR0b24gdGFnPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHR5cGU9XCJidXR0b25cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6SWNvbl9CdXR0b24+XG4iLCI8RGVmaW5lOkljb25fV2l0aF9MYWJlbCBjbGFzcz1cImQtaW5saW5lLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gIDxJY29uICRuYW1lPSh0aGlzLmFyZ3MuaWNvbikgLz5cbiAgPHNwYW4+PCU9IGNvbnRlbnQoKSAlPjwvc3Bhbj5cbjwvRGVmaW5lOkljb25fV2l0aF9MYWJlbD5cbiIsIjxEZWZpbmU6SWNvbl9XaXRoX1RleHQgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIHB5LTJcIj5cbiAgPGkgY2xhc3M9XCJiaSBiaS1jaXJjbGUtZmlsbCBtZS0yIHRleHQtcHJpbWFyeVwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjVyZW07XCI+PC9pPlxuICA8c3BhbiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+PCU9IGNvbnRlbnQoKSAlPjwvc3Bhbj5cbjwvRGVmaW5lOkljb25fV2l0aF9UZXh0PlxuIiwiPERlZmluZTpJY29uIHRhZz1cInN2Z1wiIGNsYXNzPVwiaWNvbiBpY29uLXhzXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkljb24+XG4iLCI8RGVmaW5lOkluZm9fQm94IGNsYXNzPVwicC0zIG1iLTMgYmctbGlnaHQgYm9yZGVyLXN0YXJ0IGJvcmRlci1wcmltYXJ5IGJvcmRlci00XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkluZm9fQm94PlxuIiwiPERlZmluZTpJbmxpbmVfRWRpdF9GaWVsZCBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgPGRpdiAkaWQ9XCJkaXNwbGF5X21vZGVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICA8c3BhbiAkaWQ9XCJ2YWx1ZV9kaXNwbGF5XCI+PCU9IHRoaXMuYXJncy52YWx1ZSB8fCB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ0NsaWNrIHRvIGVkaXQnICU+PC9zcGFuPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsIHRleHQtbXV0ZWQgbXMtMlwiPjwvaT5cbiAgPC9kaXY+XG4gIDxkaXYgJGlkPVwiZWRpdF9tb2RlXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cCBpbnB1dC1ncm91cC1zbVwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiAkaWQ9XCJpbnB1dFwiIC8+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdHlwZT1cImJ1dHRvblwiICRpZD1cInNhdmVfYnRuXCIgdGl0bGU9XCJTYXZlXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hlY2stbGdcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHR5cGU9XCJidXR0b25cIiAkaWQ9XCJjYW5jZWxfYnRuXCIgdGl0bGU9XCJDYW5jZWxcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS14LWxnXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6SW5saW5lX0VkaXRfRmllbGQ+XG4iLCI8RGVmaW5lOklucHV0X1dpdGhfSWNvbiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaWNvbl9wb3NpdGlvbiAhPT0gJ2VuZCcpIHsgJT5cbiAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj5cbiAgICAgIDxpIGNsYXNzPVwiYmkgYmktPCU9IHRoaXMuYXJncy5pY29uIHx8ICdzZWFyY2gnICU+XCI+PC9pPlxuICAgIDwvc3Bhbj5cbiAgPCUgfSAlPlxuICA8aW5wdXRcbiAgICB0eXBlPVwiPCU9IHRoaXMuYXJncy50eXBlIHx8ICd0ZXh0JyAlPlwiXG4gICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgJGlkPVwiaW5wdXRcIlxuICAvPlxuICA8JSBpZiAodGhpcy5hcmdzLmljb25fcG9zaXRpb24gPT09ICdlbmQnKSB7ICU+XG4gICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLTwlPSB0aGlzLmFyZ3MuaWNvbiB8fCAnc2VhcmNoJyAlPlwiPjwvaT5cbiAgICA8L3NwYW4+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOklucHV0X1dpdGhfSWNvbj5cbiIsIjxEZWZpbmU6SW5wdXRfV2l0aF9WYWxpZGF0aW9uIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiICRpZD1cImxhYmVsXCI+XG4gICAgICA8JT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+PHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PCUgfSAlPlxuICAgIDwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGlucHV0XG4gICAgdHlwZT1cIjwlPSB0aGlzLmFyZ3MudHlwZSB8fCAndGV4dCcgJT5cIlxuICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICRpZD1cImlucHV0XCJcbiAgLz5cbiAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiAkaWQ9XCJlcnJvclwiPjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwidmFsaWQtZmVlZGJhY2tcIiAkaWQ9XCJzdWNjZXNzXCI+PC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6SW5wdXRfV2l0aF9WYWxpZGF0aW9uPlxuIiwiPERlZmluZTpJbnB1dCB0YWc9XCJpbnB1dFwiIHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbjwvRGVmaW5lOklucHV0PlxuIiwiPERlZmluZTpLYW5iYW5fQm9hcmQgY2xhc3M9XCJkLWZsZXggZ2FwLTNcIiBzdHlsZT1cIm92ZXJmbG93LXg6IGF1dG87XCI+XG4gIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJ3LTEwMCB0ZXh0LWNlbnRlciBweS01XCI+XG4gICAgICA8U3Bpbm5lciAvPlxuICAgIDwvZGl2PlxuICA8JSB9IGVsc2UgeyAlPlxuICAgIDwlIGZvciAobGV0IGNvbHVtbiBvZiB0aGlzLmRhdGEuY29sdW1ucyB8fCBbXSkgeyAlPlxuICAgICAgPGRpdiBjbGFzcz1cImNhcmRcIiBzdHlsZT1cIm1pbi13aWR0aDogMzAwcHg7IG1heC13aWR0aDogMzAwcHg7XCIgZGF0YS1jb2x1bW4taWQ9XCI8JT0gY29sdW1uLmlkICU+XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBiZy1saWdodFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8aDYgY2xhc3M9XCJtYi0wXCI+PCU9IGNvbHVtbi50aXRsZSAlPjwvaDY+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPjwlPSBjb2x1bW4uY2FyZHMubGVuZ3RoICU+PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTJcIiBzdHlsZT1cIm1pbi1oZWlnaHQ6IDQwMHB4OyBtYXgtaGVpZ2h0OiA2MDBweDsgb3ZlcmZsb3cteTogYXV0bztcIiBkYXRhLWNvbHVtbi1jYXJkcz1cIjwlPSBjb2x1bW4uaWQgJT5cIj5cbiAgICAgICAgICA8JSBmb3IgKGxldCBjYXJkIG9mIGNvbHVtbi5jYXJkcykgeyAlPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgbWItMlwiIGRyYWdnYWJsZT1cInRydWVcIiBkYXRhLWNhcmQtaWQ9XCI8JT0gY2FyZC5pZCAlPlwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IHAtM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy1ib2xkIG1iLTJcIj48JT0gY2FyZC50aXRsZSAlPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwlIGlmIChjYXJkLmRlc2NyaXB0aW9uKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtYi0yXCI+PCU9IGNhcmQuZGVzY3JpcHRpb24gJT48L2Rpdj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNhcmQudGFncyAmJiBjYXJkLnRhZ3MubGVuZ3RoID4gMCkgeyAlPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgdGFnIG9mIGNhcmQudGFncykgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctbGlnaHQgdGV4dC1kYXJrIG1lLTFcIj48JT0gdGFnICU+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNhcmQuYXNzaWduZWUpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxBdmF0YXIgJG5hbWU9Y2FyZC5hc3NpZ25lZSAkc2l6ZT1cInhzXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSBjYXJkLmFzc2lnbmVlICU+PC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuICA8JSB9ICU+XG48L0RlZmluZTpLYW5iYW5fQm9hcmQ+XG4iLCI8RGVmaW5lOkxpbmsgdGFnPVwiYVwiIGhyZWY9XCIjXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkxpbms+XG4iLCI8RGVmaW5lOkxpc3QgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6TGlzdD5cbiIsIjxEZWZpbmU6TG9hZGluZ19Ta2VsZXRvbiBjbGFzcz1cInBsYWNlaG9sZGVyLWdsb3dcIj5cbiAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBjb2wtMTJcIj48L3NwYW4+XG4gIDxzcGFuIGNsYXNzPVwicGxhY2Vob2xkZXIgY29sLTEwXCI+PC9zcGFuPlxuICA8c3BhbiBjbGFzcz1cInBsYWNlaG9sZGVyIGNvbC04XCI+PC9zcGFuPlxuPC9EZWZpbmU6TG9hZGluZ19Ta2VsZXRvbj5cbiIsIjxEZWZpbmU6TWV0cmljX0NhcmQgY2xhc3M9XCJjYXJkICBoLTEwMFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTRcIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpNZXRyaWNfQ2FyZD5cbiIsIjxEZWZpbmU6TW9iaWxlX0hlYWRlciB0YWc9XCJoZWFkZXJcIiBjbGFzcz1cIm5hdmJhciBuYXZiYXItbGlnaHQgYmctbGlnaHQgZC1sZy1ub25lXCI+XG4gIDxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwibmF2YmFyLXRvZ2dsZXJcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cIm9mZmNhbnZhc1wiXG4gICAgICAgICAgICBkYXRhLWJzLXRhcmdldD1cIiNtb2JpbGVTaWRlYmFyXCJcbiAgICAgICAgICAgIGFyaWEtY29udHJvbHM9XCJtb2JpbGVTaWRlYmFyXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm5hdmJhci10b2dnbGVyLWljb25cIj48L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJuYXZiYXItYnJhbmQgbWItMCBoMVwiPlBTTTwvc3Bhbj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvRGVmaW5lOk1vYmlsZV9IZWFkZXI+XG4iLCI8RGVmaW5lOk1vZGFsX0RpYWxvZyBjbGFzcz1cIm1vZGFsIGZhZGVcIiB0YWJpbmRleD1cIi0xXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1kaWFsb2dcIj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICA8aDUgY2xhc3M9XCJtb2RhbC10aXRsZVwiICRpZD1cInRpdGxlXCI+PCU9IHRoaXMuYXJncy50aXRsZSB8fCAnTW9kYWwnICU+PC9oNT5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiBkYXRhLWJzLWRpc21pc3M9XCJtb2RhbFwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiICRpZD1cImJvZHlcIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCIgJGlkPVwiZm9vdGVyXCI+XG4gICAgICAgIDxCdXR0b25fU2Vjb25kYXJ5IGRhdGEtYnMtZGlzbWlzcz1cIm1vZGFsXCI+Q2xvc2U8L0J1dHRvbl9TZWNvbmRhcnk+XG4gICAgICAgIDxCdXR0b25fUHJpbWFyeSAkaWQ9XCJjb25maXJtXCI+Q29uZmlybTwvQnV0dG9uX1ByaW1hcnk+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpNb2RhbF9EaWFsb2c+XG4iLCI8RGVmaW5lOk11bHRpX1NlbGVjdCBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZSB3LTEwMCB0ZXh0LXN0YXJ0XCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIiAkaWQ9XCJidXR0b25cIj5cbiAgICA8c3BhbiAkaWQ9XCJzZWxlY3RlZF90ZXh0XCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IG9wdGlvbnMnICU+PC9zcGFuPlxuICA8L2J1dHRvbj5cbiAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLW1lbnUgdy0xMDBcIiAkaWQ9XCJtZW51XCI+XG4gICAgPGRpdiBjbGFzcz1cInB4LTMgcHktMlwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJzZWFyY2hcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiBwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiICRpZD1cInNlYXJjaFwiPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1kaXZpZGVyXCI+PC9kaXY+XG4gICAgPGRpdiAkaWQ9XCJvcHRpb25zXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiAyNTBweDsgb3ZlcmZsb3cteTogYXV0bztcIj5cbiAgICAgIDwhLS0gT3B0aW9ucyBwb3B1bGF0ZWQgdmlhIEphdmFTY3JpcHQgLS0+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwicHgtMyBweS0yIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiICRpZD1cImNsZWFyX2FsbFwiPkNsZWFyIEFsbDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiICRpZD1cInNlbGVjdF9hbGxcIj5TZWxlY3QgQWxsPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6TXVsdGlfU2VsZWN0PlxuIiwiPERlZmluZTpOb3RpZmljYXRpb25fQmFkZ2UgdGFnPVwic3BhblwiIGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuICA8c3BhbiBjbGFzcz1cInBvc2l0aW9uLWFic29sdXRlIHRvcC0wIHN0YXJ0LTEwMCB0cmFuc2xhdGUtbWlkZGxlIGJhZGdlIHJvdW5kZWQtcGlsbCBiZy1kYW5nZXJcIlxuICAgICAgICAkaWQ9XCJjb3VudFwiXG4gICAgICAgIHN0eWxlPVwiPCU9ICh0aGlzLmFyZ3MuY291bnQgPiAwID8gJycgOiAnZGlzcGxheTogbm9uZTsnKSAlPlwiPlxuICAgIDwlPSB0aGlzLmFyZ3MuY291bnQgfHwgMCAlPlxuICA8L3NwYW4+XG48L0RlZmluZTpOb3RpZmljYXRpb25fQmFkZ2U+XG4iLCI8RGVmaW5lOk5vdGlmaWNhdGlvbl9Ecm9wZG93biBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmsgcG9zaXRpb24tcmVsYXRpdmVcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIlxuICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxJY29uICRuYW1lPVwiYmVsbFwiIC8+XG4gICAgPCUgaWYgKHRoaXMuYXJncy51bnJlYWRfY291bnQgPiAwKSB7ICU+XG4gICAgICA8c3BhbiBjbGFzcz1cInBvc2l0aW9uLWFic29sdXRlIHRvcC0wIHN0YXJ0LTEwMCB0cmFuc2xhdGUtbWlkZGxlIGJhZGdlIHJvdW5kZWQtcGlsbCBiZy1kYW5nZXJcIj5cbiAgICAgICAgPCU9IHRoaXMuYXJncy51bnJlYWRfY291bnQgJT5cbiAgICAgIDwvc3Bhbj5cbiAgICA8JSB9ICU+XG4gIDwvYnV0dG9uPlxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiIHN0eWxlPVwid2lkdGg6IDMyMHB4O1wiPlxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmdy1ib2xkXCI+Tm90aWZpY2F0aW9uczwvc3Bhbj5cbiAgICAgIDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzbWFsbFwiPk1hcmsgYWxsIHJlYWQ8L2E+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwib3ZlcmZsb3ctYXV0b1wiIHN0eWxlPVwibWF4LWhlaWdodDogNDAwcHg7XCI+XG4gICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Tm90aWZpY2F0aW9uX0Ryb3Bkb3duPlxuIiwiPERlZmluZTpPdmVyZHVlX0luZGljYXRvciB0YWc9XCJzcGFuXCIgY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nIHRleHQtZGFyayBkLWJsb2NrIG10LTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6T3ZlcmR1ZV9JbmRpY2F0b3I+XG4iLCI8RGVmaW5lOlBhZ2VfSGVhZGVyX0xlZnQ+XG4gIDxkaXY+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOlBhZ2VfSGVhZGVyX0xlZnQ+XG4iLCI8RGVmaW5lOlBhZ2VfSGVhZGVyX1JpZ2h0IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlBhZ2VfSGVhZGVyX1JpZ2h0PlxuIiwiPERlZmluZTpQYWdlX0hlYWRlciBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgbWItNFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpQYWdlX0hlYWRlcj5cbiIsIjxEZWZpbmU6UGFnZV9TZWN0aW9uIGNsYXNzPVwibWItNFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpQYWdlX1NlY3Rpb24+XG4iLCI8RGVmaW5lOlBhZ2VfU3VidGl0bGUgdGFnPVwicFwiIGNsYXNzPVwidGV4dC1tdXRlZCBtYi0wXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlBhZ2VfU3VidGl0bGU+XG4iLCI8RGVmaW5lOlBhZ2VfVGl0bGUgdGFnPVwiaDFcIiBjbGFzcz1cImgyIG1iLTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6UGFnZV9UaXRsZT5cbiIsIjxEZWZpbmU6UGFnZT5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6UGFnZT5cbiIsIjxEZWZpbmU6UGFnaW5hdGlvbl9Db250cm9scyB0YWc9XCJuYXZcIiBhcmlhLWxhYmVsPVwiVGFibGUgcGFnaW5hdGlvblwiPlxuICA8dWwgY2xhc3M9XCJwYWdpbmF0aW9uIHBhZ2luYXRpb24tc20gbWItMFwiPlxuICAgIDwlPSBjb250ZW50KCkgJT5cbiAgPC91bD5cbjwvRGVmaW5lOlBhZ2luYXRpb25fQ29udHJvbHM+XG4iLCI8RGVmaW5lOlBhZ2luYXRpb25fSW5mbz5cbiAgPGRpdj5cbiAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IGNvbnRlbnQoKSAlPjwvc21hbGw+XG4gIDwvZGl2PlxuPC9EZWZpbmU6UGFnaW5hdGlvbl9JbmZvPlxuIiwiPERlZmluZTpQb3BvdmVyIHRhZz1cImJ1dHRvblwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1icy10b2dnbGU9XCJwb3BvdmVyXCI+XG4gIDwlPSB0aGlzLmFyZ3MubGFiZWwgfHwgJ0luZm8nICU+XG48L0RlZmluZTpQb3BvdmVyPlxuIiwiPERlZmluZTpQcm9ncmVzc19CYXIgY2xhc3M9XCJwcm9ncmVzc1wiPlxuICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCJcbiAgICAgICByb2xlPVwicHJvZ3Jlc3NiYXJcIlxuICAgICAgIHN0eWxlPVwid2lkdGg6IDwlPSB0aGlzLmFyZ3MudmFsdWUgfHwgMCAlPiVcIlxuICAgICAgIGFyaWEtdmFsdWVub3c9XCI8JT0gdGhpcy5hcmdzLnZhbHVlIHx8IDAgJT5cIlxuICAgICAgIGFyaWEtdmFsdWVtaW49XCIwXCJcbiAgICAgICBhcmlhLXZhbHVlbWF4PVwiMTAwXCJcbiAgICAgICAkaWQ9XCJiYXJcIj5cbiAgPC9kaXY+XG48L0RlZmluZTpQcm9ncmVzc19CYXI+XG4iLCI8RGVmaW5lOlJhZGlvX0J1dHRvbiB0YWc9XCJpbnB1dFwiIHR5cGU9XCJyYWRpb1wiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiPlxuPC9EZWZpbmU6UmFkaW9fQnV0dG9uPlxuIiwiPERlZmluZTpSZWNvcmRfQ291bnRfRGlzcGxheSB0YWc9XCJzbWFsbFwiIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpSZWNvcmRfQ291bnRfRGlzcGxheT5cbiIsIjxEZWZpbmU6UmljaF9UZXh0X0VkaXRvciBjbGFzcz1cIm1iLTNcIj5cbiAgPCUgaWYgKHRoaXMuYXJncy5sYWJlbCkgeyAlPlxuICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWxcIj48JT0gdGhpcy5hcmdzLmxhYmVsICU+PC9sYWJlbD5cbiAgPCUgfSAlPlxuICA8ZGl2IGNsYXNzPVwiYm9yZGVyIHJvdW5kZWRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWJvdHRvbSBiZy1saWdodCBwLTJcIiAkaWQ9XCJ0b29sYmFyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbSBtZS0yXCIgcm9sZT1cImdyb3VwXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLWNvbW1hbmQ9XCJib2xkXCIgdGl0bGU9XCJCb2xkXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10eXBlLWJvbGRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwiaXRhbGljXCIgdGl0bGU9XCJJdGFsaWNcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXR5cGUtaXRhbGljXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cInVuZGVybGluZVwiIHRpdGxlPVwiVW5kZXJsaW5lXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10eXBlLXVuZGVybGluZVwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtIG1lLTJcIiByb2xlPVwiZ3JvdXBcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImluc2VydFVub3JkZXJlZExpc3RcIiB0aXRsZT1cIkJ1bGxldCBMaXN0XCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1saXN0LXVsXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImluc2VydE9yZGVyZWRMaXN0XCIgdGl0bGU9XCJOdW1iZXJlZCBMaXN0XCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1saXN0LW9sXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc20gbWUtMlwiIHJvbGU9XCJncm91cFwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwianVzdGlmeUxlZnRcIiB0aXRsZT1cIkFsaWduIExlZnRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtbGVmdFwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLWNvbW1hbmQ9XCJqdXN0aWZ5Q2VudGVyXCIgdGl0bGU9XCJBbGlnbiBDZW50ZXJcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtY2VudGVyXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImp1c3RpZnlSaWdodFwiIHRpdGxlPVwiQWxpZ24gUmlnaHRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtcmlnaHRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiIHJvbGU9XCJncm91cFwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwiY3JlYXRlTGlua1wiIHRpdGxlPVwiSW5zZXJ0IExpbmtcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWxpbmtcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwidW5saW5rXCIgdGl0bGU9XCJSZW1vdmUgTGlua1wiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktbGluay00NWRlZ1wiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICAgIGNsYXNzPVwicC0zXCJcbiAgICAgIHN0eWxlPVwibWluLWhlaWdodDogMjAwcHg7IG1heC1oZWlnaHQ6IDQwMHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiXG4gICAgICAkaWQ9XCJlZGl0b3JcIlxuICAgID48JT0gdGhpcy5hcmdzLnZhbHVlIHx8ICcnICU+PC9kaXY+XG4gIDwvZGl2PlxuICA8JSBpZiAodGhpcy5hcmdzLmhlbHApIHsgJT5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+PCU9IHRoaXMuYXJncy5oZWxwICU+PC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOlJpY2hfVGV4dF9FZGl0b3I+XG4iLCI8RGVmaW5lOlJvd19BY3Rpb25fTWVudSBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1saW5rIHRleHQtbXV0ZWQgZHJvcGRvd24tdG9nZ2xlXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cImRyb3Bkb3duXCJcbiAgICAgICAgICBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIj5cbiAgICDii65cbiAgPC9idXR0b24+XG4gIDx1bCBjbGFzcz1cImRyb3Bkb3duLW1lbnUgZHJvcGRvd24tbWVudS1lbmRcIiAkaWQ9XCJtZW51XCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3VsPlxuPC9EZWZpbmU6Um93X0FjdGlvbl9NZW51PlxuIiwiPCUtLVxuICBTYW1wbGUgRGF0YWdyaWQgQ29tcG9uZW50XG4gIERlbW9uc3RyYXRlcyBhIGZ1bGwtZmVhdHVyZWQgZGF0YSB0YWJsZSB3aXRoOlxuICAtIFNlbGVjdGFibGUgcm93c1xuICAtIENvbHVtbiBoZWFkZXJzXG4gIC0gQWN0aW9uIGJ1dHRvbnNcbiAgLSBQYWdpbmF0aW9uXG4gIC0gU3RhdHVzIGJhZGdlc1xuICAtIFVzaW5nIGxvb3BzIHRvIGF2b2lkIHJlcGV0aXRpb25cbi0tJT5cblxuPERlZmluZTpTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50IGNsYXNzPVwiY2FyZFwiPlxuICA8JS0tIENhcmQgSGVhZGVyIHdpdGggVGl0bGUgYW5kIENvdW50IC0tJT5cbiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIGJnLWxpZ2h0XCI+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgIDxoNSBjbGFzcz1cIm1iLTBcIj48JT0gdGhpcy5hcmdzLnRpdGxlIHx8ICdEYXRhIFRhYmxlJyAlPjwvaDU+XG4gICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgIFNob3dpbmcgPCU9IHRoaXMuYXJncy5zaG93aW5nIHx8IDEwICU+IG9mIDwlPSB0aGlzLmFyZ3MudG90YWwgfHwgMTAwICU+IDwlPSB0aGlzLmFyZ3MuZW50aXR5X25hbWUgfHwgJ2l0ZW1zJyAlPlxuICAgICAgPC9zbWFsbD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCUtLSBUYWJsZSAtLSU+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWhvdmVyIG1iLTBcIj5cbiAgICAgICAgPCUtLSBUYWJsZSBIZWFkZXIgLS0lPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zZWxlY3RhYmxlKTogJT5cbiAgICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiICRpZD1cInNlbGVjdF9hbGxcIiAvPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPCUgZW5kaWY7ICU+XG5cbiAgICAgICAgICAgIDwlLS0gQ29sdW1uIEhlYWRlcnMgKGZyb20gYXJncy5jb2x1bW5zIGFycmF5KSAtLSU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmNvbHVtbnMgJiYgdGhpcy5hcmdzLmNvbHVtbnMubGVuZ3RoID4gMCkgeyAlPlxuICAgICAgICAgICAgICA8JSBmb3IgKGxldCBjb2x1bW4gb2YgdGhpcy5hcmdzLmNvbHVtbnMpIHsgJT5cbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCI8JT0gKGNvbHVtbi53aWR0aCA/ICd3aWR0aDogJytjb2x1bW4ud2lkdGggOiAnJykgJT5cIj5cbiAgICAgICAgICAgICAgICAgIDwlPSBjb2x1bW4ubGFiZWwgJT5cbiAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICA8JS0tIERlZmF1bHQgY29sdW1ucyBpZiBub25lIHNwZWNpZmllZCAtLSU+XG4gICAgICAgICAgICAgIDx0aD5JRDwvdGg+XG4gICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cbiAgICAgICAgICAgICAgPHRoPkNvbXBhbnk8L3RoPlxuICAgICAgICAgICAgICA8dGg+RW1haWw8L3RoPlxuICAgICAgICAgICAgICA8dGg+UGhvbmU8L3RoPlxuICAgICAgICAgICAgICA8dGg+U3RhdHVzPC90aD5cbiAgICAgICAgICAgICAgPHRoPkNyZWF0ZWQ8L3RoPlxuICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTAwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cblxuICAgICAgICA8JS0tIFRhYmxlIEJvZHkgLS0lPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPCUtLSBDaGVjayBpZiB3ZSBoYXZlIHJlYWwgZGF0YSBsb2FkZWQgLS0lPlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPCUtLSBMb2FkaW5nIHN0YXRlIC0gZ2VuZXJhdGUgcGxhY2Vob2xkZXIgcm93cyAtLSU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmFyZ3MucGxhY2Vob2xkZXJfcm93cyB8fCAxMCk7IGkrKykgeyAlPlxuICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zZWxlY3RhYmxlKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIGRpc2FibGVkIC8+PC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgaiA9IDA7IGogPCAodGhpcy5hcmdzLmNvbHVtbnMgPyB0aGlzLmFyZ3MuY29sdW1ucy5sZW5ndGggOiA4KTsgaisrKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwbGFjZWhvbGRlci1nbG93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBjb2wtPCU9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDgpICsgNCAlPlwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSB9IGVsc2UgaWYgKHRoaXMuZGF0YS5yb3dzICYmIHRoaXMuZGF0YS5yb3dzLmxlbmd0aCA+IDApIHsgJT5cbiAgICAgICAgICAgIDwlLS0gUmVhbCBkYXRhIHJvd3MgLS0lPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgcm93IG9mIHRoaXMuZGF0YS5yb3dzKSB7ICU+XG4gICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnNlbGVjdGFibGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgZGF0YS1pZD1cIjwlPSByb3cuaWQgJT5cIiAvPjwvdGQ+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuXG4gICAgICAgICAgICAgICAgPCUtLSBSZW5kZXIgY2VsbHMgYmFzZWQgb24gY29sdW1ucyBkZWZpbml0aW9uIC0tJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmNvbHVtbnMpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDwlIGZvciAobGV0IGNvbHVtbiBvZiB0aGlzLmFyZ3MuY29sdW1ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgPCUgaWYgKGNvbHVtbi50eXBlID09PSAnYmFkZ2UnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JS0tIFJlbmRlciBhcyBiYWRnZSAtLSU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLTwlPSByb3dbY29sdW1uLmZpZWxkICsgJ19jb2xvciddIHx8ICdzZWNvbmRhcnknICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlPSByb3dbY29sdW1uLmZpZWxkXSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09ICdhY3Rpb25zJykgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCUtLSBBY3Rpb24gYnV0dG9ucyAtLSU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnZpZXdfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSB0aGlzLmFyZ3Mudmlld191cmwucmVwbGFjZSgne2lkfScsIHJvdy5pZCkgJT5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmVkaXRfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSB0aGlzLmFyZ3MuZWRpdF91cmwucmVwbGFjZSgne2lkfScsIHJvdy5pZCkgJT5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVsZXRlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtaWQ9XCI8JT0gcm93LmlkICU+XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpZD1cImRlbGV0ZV9idXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JS0tIFJlZ3VsYXIgdGV4dCBjZWxsIC0tJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlPSByb3dbY29sdW1uLmZpZWxkXSAlPlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgPCUtLSBEZWZhdWx0IGNlbGwgcmVuZGVyaW5nIHdpdGhvdXQgY29sdW1uIGRlZmluaXRpb25zIC0tJT5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93LmlkICU+PC90ZD5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93Lm5hbWUgJT48L3RkPlxuICAgICAgICAgICAgICAgICAgPHRkPjwlPSByb3cuY29tcGFueSAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvdy5lbWFpbCAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZSAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctPCU9IHJvdy5zdGF0dXNfY29sb3IgfHwgJ3N1Y2Nlc3MnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5zdGF0dXMgJT5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93LmNyZWF0ZWQgJT48L3RkPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlLS0gRW1wdHkgc3RhdGUgLS0lPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjwlPSAodGhpcy5hcmdzLnNlbGVjdGFibGUgPyAxIDogMCkgKyAodGhpcy5hcmdzLmNvbHVtbnMgPyB0aGlzLmFyZ3MuY29sdW1ucy5sZW5ndGggOiA4KSAlPlwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtY2VudGVyIHRleHQtbXV0ZWQgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktaW5ib3ggZnMtMSBkLWJsb2NrIG1iLTJcIj48L2k+XG4gICAgICAgICAgICAgICAgTm8gPCU9IHRoaXMuYXJncy5lbnRpdHlfbmFtZSB8fCAnaXRlbXMnICU+IGZvdW5kXG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwlLS0gUGFnaW5hdGlvbiBGb290ZXIgLS0lPlxuICA8JSBpZiAodGhpcy5hcmdzLnBhZ2luYXRpb24gIT09IGZhbHNlICYmIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubGVuZ3RoID4gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJjYXJkLWZvb3RlciBiZy1saWdodFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgICAgICBTaG93aW5nIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uZnJvbSB8fCAxICU+IHRvIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG8gfHwgMTAgJT5cbiAgICAgICAgICAgIG9mIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG90YWwgfHwgMTAwICU+IGVudHJpZXNcbiAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPG5hdj5cbiAgICAgICAgICA8dWwgY2xhc3M9XCJwYWdpbmF0aW9uIHBhZ2luYXRpb24tc20gbWItMFwiPlxuICAgICAgICAgICAgPCUtLSBQcmV2aW91cyBCdXR0b24gLS0lPlxuICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uY3VycmVudF9wYWdlID09PSAxID8gJ2Rpc2FibGVkJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiB0YWJpbmRleD1cIi0xXCIgJGlkPVwicHJldl9wYWdlXCI+UHJldmlvdXM8L2E+XG4gICAgICAgICAgICA8L2xpPlxuXG4gICAgICAgICAgICA8JS0tIFBhZ2UgTnVtYmVycyAtLSU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5kYXRhLnBhZ2luYXRpb24/LnBhZ2VzKSB7ICU+XG4gICAgICAgICAgICAgIDwlIGZvciAobGV0IHBhZ2Ugb2YgdGhpcy5kYXRhLnBhZ2luYXRpb24ucGFnZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAocGFnZSA9PT0gJy4uLicpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbSBkaXNhYmxlZFwiPjxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIj4uLi48L2E+PC9saT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSBwYWdlID09PSB0aGlzLmRhdGEucGFnaW5hdGlvbi5jdXJyZW50X3BhZ2UgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiBkYXRhLXBhZ2U9XCI8JT0gcGFnZSAlPlwiPjwlPSBwYWdlICU+PC9hPlxuICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgIDwlLS0gR2VuZXJhdGUgNSBwYWdlIGJ1dHRvbnMgaWYgcGFnaW5hdGlvbiBkYXRhIG5vdCBmdWxseSBsb2FkZWQgLS0lPlxuICAgICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMTsgaSA8PSA1OyBpKyspIHsgJT5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gPCU9IGkgPT09IDEgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IGkgJT5cIj48JT0gaSAlPjwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSB9ICU+XG5cbiAgICAgICAgICAgIDwlLS0gTmV4dCBCdXR0b24gLS0lPlxuICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uY3VycmVudF9wYWdlID09PSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG90YWxfcGFnZXMgPyAnZGlzYWJsZWQnIDogJycgJT5cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBocmVmPVwiI1wiICRpZD1cIm5leHRfcGFnZVwiPk5leHQ8L2E+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvdWw+XG4gICAgICAgIDwvbmF2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnQ+XG4iLCI8RGVmaW5lOlNlYXJjaF9CYXIgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj5cbiAgICA8SWNvbiAkbmFtZT1cInNlYXJjaFwiIC8+XG4gIDwvc3Bhbj5cbiAgPGlucHV0IHR5cGU9XCJzZWFyY2hcIlxuICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgcGxhY2Vob2xkZXI9XCI8JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdTZWFyY2guLi4nICU+XCJcbiAgICAgICAgICRpZD1cImlucHV0XCIgLz5cbjwvRGVmaW5lOlNlYXJjaF9CYXI+XG4iLCI8RGVmaW5lOlNlYXJjaF9CdXR0b24gdGFnPVwiYnV0dG9uXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIj5cbiAgPGkgY2xhc3M9XCJiaSBiaS1zZWFyY2hcIj48L2k+XG48L0RlZmluZTpTZWFyY2hfQnV0dG9uPlxuIiwiPERlZmluZTpTZWFyY2hfSW5wdXQgdGFnPVwiaW5wdXRcIiB0eXBlPVwic2VhcmNoXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaCBjb250YWN0cy4uLlwiIHN0eWxlPVwid2lkdGg6IDI1MHB4O1wiPlxuPC9EZWZpbmU6U2VhcmNoX0lucHV0PlxuIiwiPERlZmluZTpTZWFyY2hhYmxlX1NlbGVjdCBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZSB3LTEwMCB0ZXh0LXN0YXJ0XCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIiAkaWQ9XCJidXR0b25cIj5cbiAgICA8c3BhbiAkaWQ9XCJzZWxlY3RlZF90ZXh0XCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IGFuIG9wdGlvbicgJT48L3NwYW4+XG4gIDwvYnV0dG9uPlxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbWVudSB3LTEwMFwiICRpZD1cIm1lbnVcIj5cbiAgICA8ZGl2IGNsYXNzPVwicHgtMyBweS0yXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInNlYXJjaFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoLi4uXCIgJGlkPVwic2VhcmNoXCI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2ICRpZD1cIm9wdGlvbnNcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDI1MHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiPlxuICAgICAgPCEtLSBPcHRpb25zIHBvcHVsYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpTZWFyY2hhYmxlX1NlbGVjdD5cbiIsIjxEZWZpbmU6U2VsZWN0X0Ryb3Bkb3duIHRhZz1cInNlbGVjdFwiIGNsYXNzPVwiZm9ybS1zZWxlY3RcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6U2VsZWN0X0Ryb3Bkb3duPlxuIiwiPERlZmluZTpTaWRlYmFyX05hdiB0YWc9XCJuYXZcIiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBwLTMgYmctbGlnaHRcIiBzdHlsZT1cIndpZHRoOiAyNTBweDsgbWluLWhlaWdodDogMTAwdmg7XCI+XG4gIDxhIGhyZWY9XCIvXCIgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIG1iLTMgdGV4dC1kZWNvcmF0aW9uLW5vbmVcIj5cbiAgICA8c3BhbiBjbGFzcz1cImZzLTQgZnctYm9sZFwiPlBTTTwvc3Bhbj5cbiAgPC9hPlxuICA8aHIgLz5cbiAgPHVsIGNsYXNzPVwibmF2IG5hdi1waWxscyBmbGV4LWNvbHVtbiBtYi1hdXRvXCIgJGlkPVwibmF2X2l0ZW1zXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3VsPlxuPC9EZWZpbmU6U2lkZWJhcl9OYXY+XG4iLCI8RGVmaW5lOlNpbXBsZV9UYWJsZV9UZXN0PlxuICA8dGFibGUgY2xhc3M9XCJ0YWJsZVwiPlxuICAgIDx0cj5cbiAgICAgIDx0ZD5UZXN0PC90ZD5cbiAgICA8L3RyPlxuICA8L3RhYmxlPlxuPC9EZWZpbmU6U2ltcGxlX1RhYmxlX1Rlc3Q+XG4iLCI8RGVmaW5lOlNvcnRhYmxlX0NvbHVtbl9IZWFkZXIgdGFnPVwidGhcIiBjbGFzcz1cInVzZXItc2VsZWN0LW5vbmVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIj5cbiAgICA8c3Bhbj48JT0gY29udGVudCgpICU+PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwibXMtMlwiICRpZD1cInNvcnRfaWNvblwiPlxuICAgICAgPGkgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+4oeFPC9pPlxuICAgIDwvc3Bhbj5cbiAgPC9kaXY+XG48L0RlZmluZTpTb3J0YWJsZV9Db2x1bW5fSGVhZGVyPlxuIiwiPERlZmluZTpTcGlubmVyIGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XG4gIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+TG9hZGluZy4uLjwvc3Bhbj5cbjwvRGVmaW5lOlNwaW5uZXI+XG4iLCI8RGVmaW5lOlN0YXRfQ2FyZCBjbGFzcz1cImNhcmQgdGV4dC1jZW50ZXIgYm9yZGVyLTAgc2hhZG93LXNtXCI+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6U3RhdF9DYXJkPlxuIiwiPERlZmluZTpTdGF0dXNfQmFkZ2UgdGFnPVwic3BhblwiIGNsYXNzPVwiYmFkZ2VcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6U3RhdHVzX0JhZGdlPlxuIiwiPERlZmluZTpUYWJfQ29udGVudCBjbGFzcz1cInRhYi1jb250ZW50IG10LTNcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFiX0NvbnRlbnQ+XG4iLCI8RGVmaW5lOlRhYmxlX0JvZHkgdGFnPVwidGJvZHlcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFibGVfQm9keT5cbiIsIjxEZWZpbmU6VGFibGVfSGVhZGVycyB0YWc9XCJ0aGVhZFwiPlxuICA8dHI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3RyPlxuPC9EZWZpbmU6VGFibGVfSGVhZGVycz5cbiIsIjxEZWZpbmU6VGFibGVfUGFnaW5hdGlvbiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgbXQtM1wiPlxuICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiICRpZD1cImluZm9cIj5cbiAgICBTaG93aW5nIDwlPSB0aGlzLmFyZ3Muc3RhcnQgfHwgMSAlPiB0byA8JT0gdGhpcy5hcmdzLmVuZCB8fCAxMCAlPiBvZiA8JT0gdGhpcy5hcmdzLnRvdGFsIHx8IDAgJT4gZW50cmllc1xuICA8L2Rpdj5cbiAgPG5hdiBhcmlhLWxhYmVsPVwiVGFibGUgcGFnaW5hdGlvblwiPlxuICAgIDx1bCBjbGFzcz1cInBhZ2luYXRpb24gbWItMFwiICRpZD1cInBhZ2luYXRpb25cIj5cbiAgICAgIDwlPSBjb250ZW50KCkgJT5cbiAgICA8L3VsPlxuICA8L25hdj5cbjwvRGVmaW5lOlRhYmxlX1BhZ2luYXRpb24+XG4iLCI8RGVmaW5lOlRhYmxlIHRhZz1cInRhYmxlXCIgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ob3ZlclwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUYWJsZT5cbiIsIjxEZWZpbmU6VGFicyB0YWc9XCJ1bFwiIGNsYXNzPVwibmF2IG5hdi10YWJzXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRhYnM+XG4iLCI8RGVmaW5lOlRhZ19Hcm91cCBjbGFzcz1cImQtZmxleCBmbGV4LXdyYXAgZ2FwLTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFnX0dyb3VwPlxuIiwiPERlZmluZTpUYWcgdGFnPVwic3BhblwiIGNsYXNzPVwiYmFkZ2Ugcm91bmRlZC1waWxsIGJnLXNlY29uZGFyeSBtZS0xXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRhZz5cbiIsIjxEZWZpbmU6VGV4dF9EaXNwbGF5IHRhZz1cInNwYW5cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGV4dF9EaXNwbGF5PlxuIiwiPERlZmluZTpUZXh0YXJlYSB0YWc9XCJ0ZXh0YXJlYVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcm93cz1cIjRcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGV4dGFyZWE+XG4iLCI8RGVmaW5lOlRocmVlX0NvbHVtbl9MYXlvdXQgY2xhc3M9XCJyb3dcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGhyZWVfQ29sdW1uX0xheW91dD5cbiIsIjxEZWZpbmU6VGltZV9QaWNrZXIgY2xhc3M9XCJtYi0zXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLWNsb2NrXCI+PC9pPlxuICAgIDwvc3Bhbj5cbiAgICA8aW5wdXRcbiAgICAgIHR5cGU9XCJ0aW1lXCJcbiAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgICAkaWQ9XCJpbnB1dFwiXG4gICAgLz5cbiAgPC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6VGltZV9QaWNrZXI+XG4iLCI8RGVmaW5lOlRpbWVsaW5lIGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0zXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRpbWVsaW5lPlxuIiwiPERlZmluZTpUaW1lc3RhbXBfRGlzcGxheSB0YWc9XCJzbWFsbFwiIGNsYXNzPVwidGV4dC1tdXRlZCBkLWJsb2NrXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRpbWVzdGFtcF9EaXNwbGF5PlxuIiwiPERlZmluZTpUb29sdGlwIHRhZz1cInNwYW5cIiBkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIiBkYXRhLWJzLXBsYWNlbWVudD1cInRvcFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUb29sdGlwPlxuIiwiPERlZmluZTpUb3BfTmF2IHRhZz1cIm5hdlwiIGNsYXNzPVwibmF2YmFyIG5hdmJhci1leHBhbmQtbGcgbmF2YmFyLWxpZ2h0IGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIj5cbiAgICA8YSBjbGFzcz1cIm5hdmJhci1icmFuZFwiIGhyZWY9XCIvXCI+UFNNPC9hPlxuICAgIDxidXR0b24gY2xhc3M9XCJuYXZiYXItdG9nZ2xlclwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIlxuICAgICAgICAgICAgZGF0YS1icy10YXJnZXQ9XCIjbmF2YmFyTmF2XCJcbiAgICAgICAgICAgIGFyaWEtY29udHJvbHM9XCJuYXZiYXJOYXZcIlxuICAgICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJUb2dnbGUgbmF2aWdhdGlvblwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJuYXZiYXItdG9nZ2xlci1pY29uXCI+PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxkaXYgY2xhc3M9XCJjb2xsYXBzZSBuYXZiYXItY29sbGFwc2VcIiBpZD1cIm5hdmJhck5hdlwiPlxuICAgICAgPHVsIGNsYXNzPVwibmF2YmFyLW5hdiBtcy1hdXRvXCIgJGlkPVwibmF2X2l0ZW1zXCI+XG4gICAgICAgIDwlPSBjb250ZW50KCkgJT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6VG9wX05hdj5cbiIsIjxEZWZpbmU6VHJlbmRfSW5kaWNhdG9yIHRhZz1cInNwYW5cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VHJlbmRfSW5kaWNhdG9yPlxuIiwiPERlZmluZTpUd29fQ29sdW1uX0xheW91dCBjbGFzcz1cInJvd1wiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUd29fQ29sdW1uX0xheW91dD5cbiIsIjxEZWZpbmU6VXNlcl9BdmF0YXJfRHJvcGRvd24gY2xhc3M9XCJkcm9wZG93blwiPlxuICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGRyb3Bkb3duLXRvZ2dsZSBwLTAgYm9yZGVyLTBcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIlxuICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiXG4gICAgICAgICAgJGlkPVwidG9nZ2xlXCI+XG4gICAgPEF2YXRhciAkc3JjPSh0aGlzLmFyZ3MuYXZhdGFyX3NyYykgJG5hbWU9KHRoaXMuYXJncy51c2VyX25hbWUpICRzaXplPVwic21cIiAvPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiICRpZD1cIm1lbnVcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvdWw+XG48L0RlZmluZTpVc2VyX0F2YXRhcl9Ecm9wZG93bj5cbiIsIjxEZWZpbmU6VXNlcnNfRGF0YV9UYWJsZSB0YWc9XCJkaXZcIiBjbGFzcz1cImNhcmQtYm9keSBwLTBcIj5cbiAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ob3ZlciBtYi0wXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiBpZD1cInNlbGVjdC1hbGxcIj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5JRDwvdGg+XG4gICAgICAgICAgPHRoPk5hbWU8L3RoPlxuICAgICAgICAgIDx0aD5FbWFpbDwvdGg+XG4gICAgICAgICAgPHRoPlJvbGU8L3RoPlxuICAgICAgICAgIDx0aD5EZXBhcnRtZW50PC90aD5cbiAgICAgICAgICA8dGg+U3RhdHVzPC90aD5cbiAgICAgICAgICA8dGg+TGFzdCBMb2dpbjwvdGg+XG4gICAgICAgICAgPHRoPkpvaW5lZDwvdGg+XG4gICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDEwMHB4O1wiPkFjdGlvbnM8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDE8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+SkQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBKb2huIERvZVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+am9obi5kb2VAZXhhbXBsZS5jb208L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPkFkbWluPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkVuZ2luZWVyaW5nPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjIgaG91cnMgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE1LCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDI8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+SlM8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBKYW5lIFNtaXRoXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5qYW5lLnNtaXRoQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWFuYWdlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXJrZXRpbmc8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MSBkYXkgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+RmViIDIwLCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+TUI8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBNaWtlIEJyb3duXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5taWtlLmJyb3duQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zZWNvbmRhcnlcIj5Vc2VyPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPlNhbGVzPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nXCI+SW5hY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+NSBkYXlzIGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPk1hciAxMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3NcIiB0aXRsZT1cIkFjdGl2YXRlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jaGVjay1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+U1c8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBTYXJhaCBXaWxzb25cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkPnNhcmFoLndpbHNvbkBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPk1hbmFnZXI8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SFI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MyBob3VycyBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5BcHIgMDUsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0aXRsZT1cIlN1c3BlbmRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgdXNlci1zZWxlY3RcIj48L3RkPlxuICAgICAgICAgIDx0ZD4jVTAwNTwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImF2YXRhci1zbSBtZS0yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdmF0YXItaW5pdGlhbHNcIj5USjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIFRvbSBKb2huc29uXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD50b20uakBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5TdXBwb3J0PC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5TdXNwZW5kZWQ8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MiB3ZWVrcyBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5NYXkgMTIsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdGl0bGU9XCJSZWFjdGl2YXRlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1hcnJvdy1jbG9ja3dpc2VcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDY8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+RUQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBFbWlseSBEYXZpc1xuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+ZW1pbHkuZEBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+QWRtaW48L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SVQ8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SnVzdCBub3c8L3RkPlxuICAgICAgICAgIDx0ZD5KdW4gMDEsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0aXRsZT1cIlN1c3BlbmRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgdXNlci1zZWxlY3RcIj48L3RkPlxuICAgICAgICAgIDx0ZD4jVTAwNzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImF2YXRhci1zbSBtZS0yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdmF0YXItaW5pdGlhbHNcIj5DRzwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIENocmlzIEdhcmNpYVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+Y2hyaXMuZ0BleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5GaW5hbmNlPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjYgaG91cnMgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+SnVsIDE1LCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDg8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+QU08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBBc2hsZXkgTWFydGluZXpcbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkPmFzaGxleS5tQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWFuYWdlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5PcGVyYXRpb25zPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEyIGhvdXJzIGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPkF1ZyAyMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiU3VzcGVuZFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCB1c2VyLXNlbGVjdFwiPjwvdGQ+XG4gICAgICAgICAgPHRkPiNVMDA5PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXZhdGFyLXNtIG1lLTJcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF2YXRhci1pbml0aWFsc1wiPktMPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgS2V2aW4gTGVlXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5rZXZpbi5sZWVAZXhhbXBsZS5jb208L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPlVzZXI8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+RGVzaWduPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEgZGF5IGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPlNlcCAxMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiU3VzcGVuZFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCB1c2VyLXNlbGVjdFwiPjwvdGQ+XG4gICAgICAgICAgPHRkPiNVMDEwPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXZhdGFyLXNtIG1lLTJcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF2YXRhci1pbml0aWFsc1wiPlJXPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgUmFjaGVsIFdoaXRlXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5yYWNoZWwud0BleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5MZWdhbDwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPkluYWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEgd2VlayBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5PY3QgMDUsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdGl0bGU9XCJBY3RpdmF0ZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hlY2stY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6VXNlcnNfRGF0YV9UYWJsZT5cbiIsIjwhLS1cblJzeF9Nb2RhbCBDb21wb25lbnRcblxuQmFzZSBtb2RhbCBjb21wb25lbnQgZm9yIGRpc3BsYXlpbmcgZGlhbG9ncywgZm9ybXMsIGFuZCBjdXN0b20gY29udGVudC5cblVzZXMgQm9vdHN0cmFwIDUgbW9kYWwgYXMgZm91bmRhdGlvbiB3aXRoIGN1c3RvbSBzaXppbmcgYW5kIGJlaGF2aW9yLlxuXG5BcmdzOlxuLSAkdGl0bGU6IE1vZGFsIHRpdGxlIHRleHRcbi0gJGNsb3NhYmxlOiBBbGxvdyBFU0MvYmFja2Ryb3AvWCB0byBjbG9zZSAoZGVmYXVsdDogdHJ1ZSlcbi0gJG1heF93aWR0aDogTWF4aW11bSB3aWR0aCBpbiBwaXhlbHMgKGRlZmF1bHQ6IDgwMClcblxuVGhlIG1vZGFsIGJvZHkgYW5kIGZvb3RlciBhcmUgcG9wdWxhdGVkIGR5bmFtaWNhbGx5IHZpYSB0aGUgTW9kYWwuanMgQVBJLlxuLS0+XG48RGVmaW5lOlJzeF9Nb2RhbD5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwgZmFkZSByc3gtbW9kYWxcIiB0YWJpbmRleD1cIi0xXCIgJGlkPVwibW9kYWxcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWRpYWxvZ1wiICRpZD1cImRpYWxvZ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCIgJGlkPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoNSBjbGFzcz1cIm1vZGFsLXRpdGxlXCIgJGlkPVwidGl0bGVcIj48L2g1PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZVwiICRpZD1cImNsb3NlX2J0blwiIGRhdGEtYnMtZGlzbWlzcz1cIm1vZGFsXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIiAkaWQ9XCJib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5LWNvbnRlbnRcIiAkaWQ9XCJib2R5X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRHluYW1pYyBjb250ZW50IGluc2VydGVkIGhlcmUgLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIiAkaWQ9XCJmb290ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEeW5hbWljIGJ1dHRvbnMgaW5zZXJ0ZWQgaGVyZSAtLT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYmFja2Ryb3AgZmFkZVwiICRpZD1cImJhY2tkcm9wXCI+PC9kaXY+XG48L0RlZmluZTpSc3hfTW9kYWw+XG4iLCI8IS0tXG5CcmVhZGNydW1iXG5cbkJyZWFkY3J1bWIgbmF2aWdhdGlvbiBjb21wb25lbnQgZm9sbG93aW5nIEJvb3RzdHJhcCA1IHN0eWxpbmcuXG5Vc2VzIHRyYW5zcGFyZW50IGJhY2tncm91bmQgYW5kIG5vIHBhZGRpbmcgZm9yIGNsZWFuIGludGVncmF0aW9uIHdpdGggUGFnZV9IZWFkZXIuXG5cblVzYWdlOlxuPEJyZWFkY3J1bWI+XG4gIDxCcmVhZGNydW1iX0l0ZW0gaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0Rhc2hib2FyZF9Db250cm9sbGVyJykgJT5cIj5EYXNoYm9hcmQ8L0JyZWFkY3J1bWJfSXRlbT5cbiAgPEJyZWFkY3J1bWJfSXRlbSBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyJykgJT5cIj5DbGllbnRzPC9CcmVhZGNydW1iX0l0ZW0+XG4gIDxCcmVhZGNydW1iX0l0ZW0gYWN0aXZlPlZpZXc8L0JyZWFkY3J1bWJfSXRlbT5cbjwvQnJlYWRjcnVtYj5cbi0tPlxuPERlZmluZTpCcmVhZGNydW1iIHRhZz1cIm5hdlwiIGFyaWEtbGFiZWw9XCJicmVhZGNydW1iXCI+XG4gIDxvbCBjbGFzcz1cImJyZWFkY3J1bWIgYmctdHJhbnNwYXJlbnQgcC0wIG1iLTBcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvb2w+XG48L0RlZmluZTpCcmVhZGNydW1iPlxuIiwiPCEtLVxuQnJlYWRjcnVtYl9JdGVtXG5cbkluZGl2aWR1YWwgYnJlYWRjcnVtYiBpdGVtLiBDYW4gYmUgYSBsaW5rIG9yIGFjdGl2ZSAoY3VycmVudCBwYWdlKS5cblxuJGhyZWYgLSBPcHRpb25hbCBsaW5rIFVSTC4gSWYgb21pdHRlZCwgcmVuZGVycyBhcyBwbGFpbiB0ZXh0LlxuJGFjdGl2ZSAtIEJvb2xlYW4uIElmIHRydWUsIHJlbmRlcnMgYXMgYWN0aXZlIGl0ZW0gKGN1cnJlbnQgcGFnZSkuXG5cblVzYWdlOlxuPEJyZWFkY3J1bWJfSXRlbSBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfRGFzaGJvYXJkX0NvbnRyb2xsZXInKSAlPlwiPkRhc2hib2FyZDwvQnJlYWRjcnVtYl9JdGVtPlxuPEJyZWFkY3J1bWJfSXRlbSBhY3RpdmU+Q3VycmVudCBQYWdlPC9CcmVhZGNydW1iX0l0ZW0+XG4tLT5cbjxEZWZpbmU6QnJlYWRjcnVtYl9JdGVtIHRhZz1cImxpXCIgY2xhc3M9XCJicmVhZGNydW1iLWl0ZW1cIj5cbiAgPCUgaWYgKHRoaXMuYXJncy5hY3RpdmUpIHsgJT5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwlIH0gZWxzZSBpZiAodGhpcy5hcmdzLmhyZWYpIHsgJT5cbiAgICA8YSBocmVmPVwiPCU9IHRoaXMuYXJncy5ocmVmICU+XCI+PCU9IGNvbnRlbnQoKSAlPjwvYT5cbiAgPCUgfSBlbHNlIHsgJT5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkJyZWFkY3J1bWJfSXRlbT5cbiIsIjwhLS1cbkRpc3BsYXlzIGEgY2xpZW50IG5hbWUuXG5Mb2FkcyBjbGllbnQgZGF0YSB2aWEgQWpheCBhbmQgc2hvd3MgdGhlIG5hbWUgb25jZSBsb2FkZWQuXG5cbiRjbGllbnRfaWQgLSBDbGllbnQgSUQgdG8gZGlzcGxheVxuJHBsYWNlaG9sZGVyIC0gVGV4dCB0byBzaG93IHdoaWxlIGxvYWRpbmcgKGRlZmF1bHQ6IFwiLS0tLS0tXCIpXG5cbldpZGdldCBpbnRlcmZhY2U6XG4tIHZhbCgpIC0gR2V0IGN1cnJlbnQgY2xpZW50X2lkXG4tIHZhbChpZCkgLSBTZXQgbmV3IGNsaWVudF9pZCBhbmQgcmVsb2FkXG4tLT5cbjxEZWZpbmU6Q2xpZW50X0xhYmVsIHRhZz1cInNwYW5cIiBjbGFzcz1cIldpZGdldFwiPlxuXG4gICAgPGkgY2xhc3M9XCJiaSBiaS1idWlsZGluZ1wiPjwvaT5cbiAgICA8JSBpZiAodGhpcy5kYXRhLmxvYWRpbmcpIHsgJT5cbiAgICAgICAgPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnLS0tLS0tJyAlPlxuICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNsaWVudCkgeyAlPlxuICAgICAgICA8JT0gdGhpcy5kYXRhLmNsaWVudC5uYW1lICU+IGNhZGZkc2FcbiAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj5Vbmtub3duIENsaWVudDwvc3Bhbj5cbiAgICA8JSB9ICU+XG5cbjwvRGVmaW5lOkNsaWVudF9MYWJlbD4iLCI8IS0tXG5DbGllbnRfTGFiZWxfTGlua1xuXG5EaXNwbGF5cyBhIGNsaWNrYWJsZSBjbGllbnQgbmFtZSB0aGF0IGxpbmtzIHRvIHRoZSBjbGllbnQgdmlldyBwYWdlLlxuTG9hZHMgY2xpZW50IGRhdGEgdmlhIEFqYXggYW5kIHNob3dzIHRoZSBuYW1lIG9uY2UgbG9hZGVkLlxuXG4kY2xpZW50X2lkIC0gQ2xpZW50IElEIHRvIGRpc3BsYXlcbiRwbGFjZWhvbGRlciAtIFRleHQgdG8gc2hvdyB3aGlsZSBsb2FkaW5nIChkZWZhdWx0OiBcIi0tLS0tLVwiKVxuXG5XaWRnZXQgaW50ZXJmYWNlOlxuLSB2YWwoKSAtIEdldCBjdXJyZW50IGNsaWVudF9pZFxuLSB2YWwoaWQpIC0gU2V0IG5ldyBjbGllbnRfaWQgYW5kIHJlbG9hZFxuLS0+XG48RGVmaW5lOkNsaWVudF9MYWJlbF9MaW5rIHRhZz1cImFcIiBjbGFzcz1cIldpZGdldFwiPlxuXG4gICAgPGkgY2xhc3M9XCJiaSBiaS1idWlsZGluZ1wiPjwvaT5cbiAgICA8JSBpZiAodGhpcy5kYXRhLmxvYWRpbmcpIHsgJT5cbiAgICAgICAgPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnLS0tLS0tJyAlPlxuICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNsaWVudCkgeyAlPlxuICAgICAgICA8JT0gdGhpcy5kYXRhLmNsaWVudC5uYW1lICU+XG4gICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+VW5rbm93biBDbGllbnQ8L3NwYW4+XG4gICAgPCUgfSAlPlxuXG48L0RlZmluZTpDbGllbnRfTGFiZWxfTGluaz4iLCI8IS0tXG5UZXh0X0lucHV0XG5cbkJhc2ljIHRleHQgaW5wdXQgd2lkZ2V0LiBTdXBwb3J0cyB2YXJpb3VzIGlucHV0IHR5cGVzICh0ZXh0LCBlbWFpbCwgdXJsLCB0ZWwsIG51bWJlciwgdGV4dGFyZWEpLlxuXG4kdHlwZSAtIElucHV0IHR5cGUgKGRlZmF1bHQ6IHRleHQpLiBVc2UgXCJ0ZXh0YXJlYVwiIGZvciBtdWx0aWxpbmUgdGV4dC5cbiRyb3dzIC0gTnVtYmVyIG9mIHJvd3MgZm9yIHRleHRhcmVhIChkZWZhdWx0OiAzKVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dFxuJHByZWZpeCAtIFRleHQgdG8gcHJlcGVuZCBiZWZvcmUgaW5wdXQgKGNyZWF0ZXMgaW5wdXQtZ3JvdXApXG4kc3VmZml4IC0gVGV4dCB0byBhcHBlbmQgYWZ0ZXIgaW5wdXQgKGNyZWF0ZXMgaW5wdXQtZ3JvdXApXG4kbWluIC0gTWluaW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0c1xuJG1heCAtIE1heGltdW0gdmFsdWUgZm9yIG51bWJlciBpbnB1dHNcbiRtYXhsZW5ndGggLSBNYXhpbXVtIGxlbmd0aCBmb3IgdGV4dCBpbnB1dHNcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgaW5wdXQgKHN0aWxsIHJldHVybnMgdmFsdWUgdmlhIHZhbCgpKVxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIChlLmcuLCBcImZpcnN0X25hbWVcIiBjYWxscyBSc3hfUmFuZG9tX1ZhbHVlcy5maXJzdF9uYW1lKCkpXG5cblVzYWdlOlxuPFRleHRfSW5wdXQgJHR5cGU9XCJlbWFpbFwiICRwbGFjZWhvbGRlcj1cInVzZXJAZXhhbXBsZS5jb21cIiAvPlxuPFRleHRfSW5wdXQgJHR5cGU9XCJ1cmxcIiAkcGxhY2Vob2xkZXI9XCJodHRwczovL2V4YW1wbGUuY29tXCIgLz5cbjxUZXh0X0lucHV0ICR0eXBlPVwidGV4dGFyZWFcIiAkcm93cz01IC8+XG48VGV4dF9JbnB1dCAkcHJlZml4PVwiQFwiICRwbGFjZWhvbGRlcj1cInVzZXJuYW1lXCIgLz5cbjxUZXh0X0lucHV0ICRzZWVkZXI9XCJjb21wYW55X25hbWVcIiAvPlxuLS0+XG48RGVmaW5lOlRleHRfSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8JSBpZiAodGhpcy5hcmdzLnR5cGUgPT09ICd0ZXh0YXJlYScpIHsgJT5cbiAgICAgICAgPHRleHRhcmVhICRpZD1cImlucHV0XCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgIHJvd3M9XCI8JT0gdGhpcy5hcmdzLnJvd3MgfHwgMyAlPlwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj48JT0gdGhpcy5kYXRhLnZhbHVlICU+PC90ZXh0YXJlYT5cbiAgICA8JSB9IGVsc2UgaWYgKHRoaXMuYXJncy5wcmVmaXggfHwgdGhpcy5hcmdzLnN1ZmZpeCkgeyAlPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucHJlZml4KSB7ICU+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+PCU9IHRoaXMuYXJncy5wcmVmaXggJT48L3NwYW4+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgIHR5cGU9XCI8JT0gdGhpcy5hcmdzLnR5cGUgfHwgJ3RleHQnICU+XCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgdmFsdWU9XCI8JT0gdGhpcy5kYXRhLnZhbHVlICU+XCJcbiAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWluICE9PSB1bmRlZmluZWQpIHsgJT5taW49XCI8JT0gdGhpcy5hcmdzLm1pbiAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4ICE9PSB1bmRlZmluZWQpIHsgJT5tYXg9XCI8JT0gdGhpcy5hcmdzLm1heCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4bGVuZ3RoKSB7ICU+bWF4bGVuZ3RoPVwiPCU9IHRoaXMuYXJncy5tYXhsZW5ndGggJT5cIjwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+IC8+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnN1ZmZpeCkgeyAlPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPjwlPSB0aGlzLmFyZ3Muc3VmZml4ICU+PC9zcGFuPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L2Rpdj5cbiAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIlxuICAgICAgICAgICAgICAgdHlwZT1cIjwlPSB0aGlzLmFyZ3MudHlwZSB8fCAndGV4dCcgJT5cIlxuICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgdmFsdWU9XCI8JT0gdGhpcy5kYXRhLnZhbHVlICU+XCJcbiAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLm1pbiAhPT0gdW5kZWZpbmVkKSB7ICU+bWluPVwiPCU9IHRoaXMuYXJncy5taW4gJT5cIjwlIH0gJT5cbiAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4ICE9PSB1bmRlZmluZWQpIHsgJT5tYXg9XCI8JT0gdGhpcy5hcmdzLm1heCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5tYXhsZW5ndGgpIHsgJT5tYXhsZW5ndGg9XCI8JT0gdGhpcy5hcmdzLm1heGxlbmd0aCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPiAvPlxuICAgIDwlIH0gJT5cbjwvRGVmaW5lOlRleHRfSW5wdXQ+XG4iLCI8IS0tXG5TZWxlY3RfSW5wdXRcblxuRHJvcGRvd24gc2VsZWN0IHdpZGdldCBmb3IgZm9ybXMuXG5cbiRvcHRpb25zIC0gQXJyYXkgb2Ygb3B0aW9uczogW3t2YWx1ZTogJ3ZhbCcsIGxhYmVsOiAnTGFiZWwnfSwgLi4uXSBvciBzaW1wbGUgYXJyYXkgWyd2YWwxJywgJ3ZhbDInXVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgb3B0aW9uIHRleHQgKGNyZWF0ZXMgZW1wdHkgb3B0aW9uIGF0IHRvcClcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgc2VsZWN0IChzdGlsbCByZXR1cm5zIHZhbHVlIHZpYSB2YWwoKSlcbiRzZWVkZXIgLSBTZWVkZXIgZnVuY3Rpb24gbmFtZSBmb3IgdGVzdCBkYXRhXG5cbldpZGdldCBpbnRlcmZhY2U6XG4tIHZhbCgpIC0gR2V0L3NldCBzZWxlY3RlZCB2YWx1ZVxuLSBzZWVkKCkgLSBGaWxscyB3aXRoIHJhbmRvbSB2YWx1ZVxuLS0+XG48RGVmaW5lOlNlbGVjdF9JbnB1dCBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxzZWxlY3QgJGlkPVwiaW5wdXRcIiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwlIGlmICh0aGlzLmFyZ3Mub3B0aW9ucykgeyAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuYXJncy5vcHRpb25zKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6U2VsZWN0X0lucHV0PlxuIiwiPCEtLVxuQWpheF9TZWxlY3RfSW5wdXRcblxuRHJvcGRvd24gc2VsZWN0IHdpZGdldCB0aGF0IGxvYWRzIG9wdGlvbnMgdmlhIEFqYXguXG5FeHRlbmRzIFNlbGVjdF9JbnB1dCB3aXRoIEFqYXggZGF0YSBsb2FkaW5nIGNhcGFiaWxpdHkuXG5cbiRkYXRhIC0gQWpheCBlbmRwb2ludCBVUkwgdGhhdCByZXR1cm5zIGFycmF5IG9mIG9wdGlvbnNcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIG9wdGlvbiB0ZXh0IChkZWZhdWx0OiBcIlBsZWFzZSB3YWl0Li4uXCIpXG4kZGlzYWJsZWQgLSBCb29sZWFuIHRvIGRpc2FibGUgdGhlIHNlbGVjdFxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIGZvciB0ZXN0IGRhdGFcblxuV2lkZ2V0IGludGVyZmFjZTpcbi0gdmFsKCkgLSBHZXQvc2V0IHNlbGVjdGVkIHZhbHVlIChoYW5kbGVzIHByZS1pbml0aWFsaXphdGlvbiBjYWxscylcbi0gc2VlZCgpIC0gRmlsbHMgd2l0aCByYW5kb20gdmFsdWVcblxuRmVhdHVyZXM6XG4tIExvYWRzIG9wdGlvbnMgYXN5bmNocm9ub3VzbHkgZnJvbSBlbmRwb2ludCBkdXJpbmcgb25fbG9hZCgpXG4tIFNob3dzIFwiUGxlYXNlIHdhaXQuLi5cIiB3aGlsZSBsb2FkaW5nXG4tIEhhbmRsZXMgdmFsKCkgY2FsbHMgYmVmb3JlIGluaXRpYWxpemF0aW9uIGNvbXBsZXRlc1xuLSBSZS1yZW5kZXJzIHdpdGggYWN0dWFsIG9wdGlvbnMgb25jZSBsb2FkZWRcbi0tPlxuPERlZmluZTpBamF4X1NlbGVjdF9JbnB1dCBleHRlbmRzPVwiU2VsZWN0X0lucHV0XCIgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8c2VsZWN0ICRpZD1cImlucHV0XCIgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj5cbiAgICAgICAgPCUgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdQbGVhc2Ugd2FpdC4uLicgJT48L29wdGlvbj5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHsgJT5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6QWpheF9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5DaGVja2JveF9JbnB1dFxuXG5DaGVja2JveCB3aWRnZXQgZm9yIGZvcm1zLlxuXG4kbGFiZWwgLSBMYWJlbCB0ZXh0IHRvIGRpc3BsYXkgbmV4dCB0byBjaGVja2JveFxuJGNoZWNrZWRfdmFsdWUgLSBWYWx1ZSB3aGVuIGNoZWNrZWQgKGRlZmF1bHQ6IFwiMVwiKVxuJHVuY2hlY2tlZF92YWx1ZSAtIFZhbHVlIHdoZW4gdW5jaGVja2VkIChkZWZhdWx0OiBcIjBcIilcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgY2hlY2tib3ggKHN0aWxsIHJldHVybnMgdmFsdWUgdmlhIHZhbCgpKVxuXG5XaWRnZXQgaW50ZXJmYWNlOlxuLSB2YWwoKSAtIEdldC9zZXQgY2hlY2tlZCBzdGF0ZSAocmV0dXJucyBjaGVja2VkX3ZhbHVlIG9yIHVuY2hlY2tlZF92YWx1ZSlcbi0gc2VlZCgpIC0gUmFuZG9tbHkgY2hlY2tzL3VuY2hlY2tzXG4tLT5cbjxEZWZpbmU6Q2hlY2tib3hfSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiA8JSBpZiAodGhpcy5kYXRhLmNoZWNrZWQpIHsgJT5jaGVja2VkPCUgfSAlPiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgICAgICAgICA8bGFiZWwgJGlkPVwibGFiZWxcIiBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIj5cbiAgICAgICAgICAgICAgICA8JT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9kaXY+XG48L0RlZmluZTpDaGVja2JveF9JbnB1dD5cbiIsIjwhLS1cbld5c2l3eWdfSW5wdXRcblxuV1lTSVdZRyBlZGl0b3Igd2lkZ2V0IGZvciBmb3JtcyB1c2luZyBRdWlsbC5cblxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dFxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIGZvciB0ZXN0IGRhdGFcblxuV2lkZ2V0IGludGVyZmFjZTpcbi0gdmFsKCkgLSBHZXQvc2V0IEhUTUwgY29udGVudFxuLSBzZWVkKCkgLSBGaWxscyB3aXRoIHJhbmRvbSBjb250ZW50XG4tLT5cbjxEZWZpbmU6V3lzaXd5Z19JbnB1dCBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxkaXYgJGlkPVwiZWRpdG9yXCIgc3R5bGU9XCJtaW4taGVpZ2h0OiAyMDBweDsgYmFja2dyb3VuZDogd2hpdGU7XCI+PC9kaXY+XG4gICAgPGlucHV0IHR5cGU9XCJoaWRkZW5cIiAkaWQ9XCJoaWRkZW5faW5wdXRcIiAvPlxuPC9EZWZpbmU6V3lzaXd5Z19JbnB1dD5cbiIsIjwhLS1cbkNvdW50cnlfU2VsZWN0X0lucHV0XG5cblNwZWNpYWxpemVkIHNlbGVjdCBmb3IgY291bnRyeSBkcm9wZG93bnMgd2l0aCBkZWZhdWx0IGNvdW50cnkgc3VwcG9ydC5cbkV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQgd2l0aCBjb3VudHJ5LXNwZWNpZmljIGJlaGF2aW9yLlxuXG4kZGF0YSAtIEFqYXggZW5kcG9pbnQgZm9yIGNvdW50cnkgZGF0YSAob3B0aW9uYWwsIGRlZmF1bHRzIHRvIFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLmNvdW50cmllcygpKVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dCAoZGVmYXVsdDogXCJTZWxlY3QgQ291bnRyeS4uLlwiKVxuJGRlZmF1bHRfY291bnRyeSAtIERlZmF1bHQgY291bnRyeSBjb2RlIChlLmcuIFwiVVNcIikgdG8gcHJlLXNlbGVjdCBhbmQgbW92ZSB0byB0b3BcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgc2VsZWN0XG5cbkZlYXR1cmVzOlxuLSBMb2FkcyBjb3VudHJ5IGxpc3QgdmlhIEFqYXggYXV0b21hdGljYWxseVxuLSBQcmUtc2VsZWN0cyBkZWZhdWx0IGNvdW50cnkgaWYgbm8gdmFsdWUgc2V0XG4tIE1vdmVzIGRlZmF1bHQgY291bnRyeSB0byB0b3Agb2YgbGlzdFxuLSBJbmhlcml0cyBhbGwgQWpheF9TZWxlY3RfSW5wdXQgYmVoYXZpb3IgKFRvbSBTZWxlY3QsIHNlYXJjaCwgbG9hZGluZyBzdGF0ZXMsIGV0Yy4pXG4tLT5cbjxEZWZpbmU6Q291bnRyeV9TZWxlY3RfSW5wdXQgZXh0ZW5kcz1cIkFqYXhfU2VsZWN0X0lucHV0XCIgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8c2VsZWN0ICRpZD1cImlucHV0XCIgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj5cbiAgICAgICAgPCUgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdQbGVhc2Ugd2FpdC4uLicgJT48L29wdGlvbj5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHsgJT5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6Q291bnRyeV9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5TdGF0ZV9TZWxlY3RfSW5wdXRcblxuU3BlY2lhbGl6ZWQgc2VsZWN0IGZvciBzdGF0ZS9wcm92aW5jZS9yZWdpb24gZHJvcGRvd25zIHdpdGggY291bnRyeS1zcGVjaWZpYyBsaXN0cy5cbkV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQgd2l0aCBzdGF0ZS1zcGVjaWZpYyBiZWhhdmlvci5cblxuJGRhdGEgLSBBamF4IGVuZHBvaW50IGZvciBzdGF0ZSBkYXRhIChvcHRpb25hbCwgZGVmYXVsdHMgdG8gUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIuc3RhdGVzKCkpXG4kcGxhY2Vob2xkZXIgLSBQbGFjZWhvbGRlciB0ZXh0IChkZWZhdWx0OiBcIlNlbGVjdCBTdGF0ZS4uLlwiKVxuJGNvdW50cnlfY29kZSAtIEluaXRpYWwgY291bnRyeSBjb2RlIChlLmcuIFwiVVNcIikgdG8gbG9hZCBzdGF0ZXMgZm9yXG4kZGlzYWJsZWQgLSBCb29sZWFuIHRvIGRpc2FibGUgdGhlIHNlbGVjdFxuXG5GZWF0dXJlczpcbi0gTG9hZHMgc3RhdGUgbGlzdCB2aWEgQWpheCBiYXNlZCBvbiBjb3VudHJ5IGNvZGVcbi0gc2V0X2NvdW50cnlfY29kZShjb2RlKSBtZXRob2QgdG8gY2hhbmdlIGNvdW50cnkgYW5kIHJlbG9hZCBzdGF0ZXNcbi0gUmVtYWlucyBkaXNhYmxlZCB1bnRpbCBjb3VudHJ5IGNvZGUgaXMgc2V0XG4tIFJldGFpbnMgdmFsdWUgc2V0IHZpYSB2YWwoKSB1bnRpbCBzdGF0ZXMgbG9hZFxuLSBJbmhlcml0cyBhbGwgQWpheF9TZWxlY3RfSW5wdXQgYmVoYXZpb3IgKFRvbSBTZWxlY3QsIHNlYXJjaCwgbG9hZGluZyBzdGF0ZXMsIGV0Yy4pXG4tLT5cbjxEZWZpbmU6U3RhdGVfU2VsZWN0X0lucHV0IGV4dGVuZHM9XCJBamF4X1NlbGVjdF9JbnB1dFwiIGNsYXNzPVwiV2lkZ2V0XCI+XG4gICAgPHNlbGVjdCAkaWQ9XCJpbnB1dFwiIDwlIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQgfHwgIXRoaXMuZGF0YS5jb3VudHJ5X2NvZGUpIHsgJT5kaXNhYmxlZDwlIH0gJT4+XG4gICAgICAgIDwlIGlmICghdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgfHwgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMubGVuZ3RoID09PSAwKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IFN0YXRlLi4uJyAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyICU+PC9vcHRpb24+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBvcHQgb2YgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQudmFsdWUgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdC52YWx1ZSkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0LmxhYmVsICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdCkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0ICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9zZWxlY3Q+XG48L0RlZmluZTpTdGF0ZV9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5Qcm9maWxlX1Bob3RvX0lucHV0XG5cblByb2ZpbGUgcGhvdG8gdXBsb2FkIHdpZGdldCB0aGF0IGRpc3BsYXlzIGEgdGh1bWJuYWlsIGFuZCBwcm92aWRlcyB1cGxvYWQgZnVuY3Rpb25hbGl0eS5cblxuJHdpZHRoIC0gVGh1bWJuYWlsIHdpZHRoIGluIHBpeGVscyAoZGVmYXVsdDogOTYpXG4kaGVpZ2h0IC0gVGh1bWJuYWlsIGhlaWdodCBpbiBwaXhlbHMgKGRlZmF1bHQ6IDk2KVxuJGFjY2VwdCAtIEZpbGUgdHlwZXMgdG8gYWNjZXB0IChkZWZhdWx0OiBpbWFnZS9qcGVnLGltYWdlL3BuZyxpbWFnZS9naWYpXG4kbWF4X3NpemUgLSBNYXhpbXVtIGZpbGUgc2l6ZSBpbiBNQiAoZGVmYXVsdDogMilcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIGltYWdlIFVSTCB3aGVuIG5vIHBob3RvIGlzIHNldFxuJHNob3dfcmVtb3ZlIC0gU2hvdyByZW1vdmUgYnV0dG9uIChkZWZhdWx0OiBmYWxzZSlcblxuVGhlIHdpZGdldCB2YWx1ZSAodmlhIHZhbCgpIGdldHRlci9zZXR0ZXIpIGlzIHRoZSBhdHRhY2htZW50IGtleS5cblxuVXNhZ2U6XG48Rm9ybV9GaWVsZCAkbmFtZT1cInByb2ZpbGVfcGhvdG9cIiAkbGFiZWw9XCJQcm9maWxlIFBob3RvXCI+XG4gICAgPFByb2ZpbGVfUGhvdG9fSW5wdXQgLz5cbjwvRm9ybV9GaWVsZD5cblxuPFByb2ZpbGVfUGhvdG9fSW5wdXQgJHdpZHRoPTEyOCAkaGVpZ2h0PTEyOCAkc2hvd19yZW1vdmU9dHJ1ZSAvPlxuLS0+XG48RGVmaW5lOlByb2ZpbGVfUGhvdG9fSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cblxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1yZWxhdGl2ZVwiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50aHVtYm5haWxfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgPGltZyAkaWQ9XCJwaG90b1wiXG4gICAgICAgICAgICAgICAgICAgIHNyYz1cIjwlPSB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCAlPlwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicm91bmRlZC1jaXJjbGUgbWUtM1wiXG4gICAgICAgICAgICAgICAgICAgIGFsdD1cIlByb2ZpbGUgUGhvdG9cIlxuICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjwlPSB0aGlzLmFyZ3Mud2lkdGggfHwgOTYgJT5cIlxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCI8JT0gdGhpcy5hcmdzLmhlaWdodCB8fCA5NiAlPlwiXG4gICAgICAgICAgICAgICAgc3R5bGU9XCJvcGFjaXR5OiAxO1wiPlxuICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICA8ZGl2ICRpZD1cInBob3RvXCIgY2xhc3M9XCJ1c2VyLXByb2ZpbGUtaWNvbiBtZS0zXCIgc3R5bGU9XCJ3aWR0aDogPCU9IHRoaXMuYXJncy53aWR0aCB8fCA5NiAlPnB4OyBoZWlnaHQ6IDwlPSB0aGlzLmFyZ3MuaGVpZ2h0IHx8IDk2ICU+cHg7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyO1wiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlcnNvbi1jaXJjbGVcIiBzdHlsZT1cImZvbnQtc2l6ZTogPCU9IE1hdGgucm91bmQoKHRoaXMuYXJncy53aWR0aCB8fCA5NikgKiAwLjc1KSAlPnB4O1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDxkaXYgJGlkPVwic3Bpbm5lclwiIGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGUgdG9wLTUwIHN0YXJ0LTUwIHRyYW5zbGF0ZS1taWRkbGUgZC1ub25lXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHRleHQtcHJpbWFyeVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5VcGxvYWRpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiAkaWQ9XCJmaWxlX2lucHV0XCIgY2xhc3M9XCJkLW5vbmVcIiBhY2NlcHQ9XCI8JT0gdGhpcy5hcmdzLmFjY2VwdCB8fCAnaW1hZ2UvanBlZyxpbWFnZS9wbmcsaW1hZ2UvZ2lmJyAlPlwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgJGlkPVwidXBsb2FkX2J0blwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tcHJpbWFyeSBtZS0yXCI+VXBsb2FkIE5ldyBQaG90bzwvYnV0dG9uPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zaG93X3JlbW92ZSAmJiB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkpIHsgJT5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAkaWQ9XCJyZW1vdmVfYnRuXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1kYW5nZXJcIj5SZW1vdmU8L2J1dHRvbj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHQgbXQtMlwiPkpQRywgUE5HIG9yIEdJRi4gTWF4IHNpemUgPCU9IHRoaXMuYXJncy5tYXhfc2l6ZSB8fCAyICU+TUIuPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpQcm9maWxlX1Bob3RvX0lucHV0PiIsIjwhLS1cblJzeF9UYWJzXG5cbkZvcm0tYXdhcmUgdGFiIGNvbnRhaW5lciB0aGF0IG1hbmFnZXMgdGFiIG5hdmlnYXRpb24gYW5kIGVycm9yIHN0YXRlcy5cblxuRmVhdHVyZXM6XG4tIEF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBlcnJvcnMgaW4gY2hpbGQgUnN4X1RhYiBjb21wb25lbnRzXG4tIFN3aXRjaGVzIHRvIGZpcnN0IHRhYiB3aXRoIGVycm9ycyBvbiB2YWxpZGF0aW9uIGZhaWx1cmVcbi0gU2hvd3MgZXJyb3IgYmFkZ2VzIG9uIHRhYiBsYWJlbHNcbi0gUGVyc2lzdHMgYWN0aXZlIHRhYiB0byBVUkwgaGFzaFxuXG5Vc2FnZTpcbjxSc3hfVGFicz5cbiAgICA8UnN4X1RhYiAkaWQ9XCJiYXNpYy1pbmZvXCIgJGxhYmVsPVwiQmFzaWMgSW5mb3JtYXRpb25cIiAkaWNvbj1cImJpLWJ1aWxkaW5nXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwibmFtZVwiPi4uLjwvRm9ybV9GaWVsZD5cbiAgICA8L1JzeF9UYWI+XG4gICAgPFJzeF9UYWIgJGlkPVwiYWRkcmVzc1wiICRsYWJlbD1cIkFkZHJlc3NcIiAkaWNvbj1cImJpLWdlby1hbHRcIj5cbiAgICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJzdHJlZXRcIj4uLi48L0Zvcm1fRmllbGQ+XG4gICAgPC9Sc3hfVGFiPlxuPC9Sc3hfVGFicz5cbi0tPlxuPERlZmluZTpSc3hfVGFicz5cbiAgICA8IS0tIFRhYiBOYXZpZ2F0aW9uIC0tPlxuICAgIDx1bCBjbGFzcz1cIm5hdiBuYXYtdGFic1wiIHJvbGU9XCJ0YWJsaXN0XCIgJGlkPVwibmF2XCI+XG4gICAgICAgIDwhLS0gVGFiIGhlYWRlcnMgd2lsbCBiZSByZW5kZXJlZCBieSBSc3hfVGFiIGNvbXBvbmVudHMgLS0+XG4gICAgPC91bD5cblxuICAgIDwhLS0gVGFiIENvbnRlbnQgQ29udGFpbmVyIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudCBtdC00XCIgJGlkPVwiY29udGVudFwiPlxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG48L0RlZmluZTpSc3hfVGFicz5cbiIsIjwhLS1cblJzeF9UYWJcblxuSW5kaXZpZHVhbCB0YWIgY29tcG9uZW50IHRoYXQgaW50ZWdyYXRlcyB3aXRoIFJzeF9UYWJzIGZvciBmb3JtLWF3YXJlIGVycm9yIGhhbmRsaW5nLlxuXG4kaWQgLSBUYWIgaWRlbnRpZmllciAodXNlZCBmb3IgVVJMIGhhc2ggYW5kIHRhcmdldGluZylcbiRsYWJlbCAtIFRhYiBsYWJlbCB0ZXh0XG4kaWNvbiAtIE9wdGlvbmFsIEJvb3RzdHJhcCBpY29uIGNsYXNzIChlLmcuLCBcImJpLWJ1aWxkaW5nXCIpXG5cbkZlYXR1cmVzOlxuLSBBdXRvbWF0aWNhbGx5IHJlZ2lzdGVycyB3aXRoIHBhcmVudCBSc3hfVGFicyBjb21wb25lbnRcbi0gQ291bnRzIHZhbGlkYXRpb24gZXJyb3JzIGluIGNoaWxkIEZvcm1fRmllbGQgY29tcG9uZW50c1xuLSBSZW5kZXJzIGFzIEJvb3RzdHJhcCB0YWIgcGFuZVxuLSBXb3JrcyBpbmRlcGVuZGVudGx5IG9yIHdpdGhpbiBSc3hfVGFicyBjb250YWluZXJcblxuVXNhZ2U6XG48UnN4X1RhYnM+XG4gICAgPFJzeF9UYWIgJGlkPVwiYmFzaWMtaW5mb1wiICRsYWJlbD1cIkJhc2ljIEluZm9ybWF0aW9uXCIgJGljb249XCJiaS1idWlsZGluZ1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cIm5hbWVcIj4uLi48L0Zvcm1fRmllbGQ+XG4gICAgPC9Sc3hfVGFiPlxuICAgIDxSc3hfVGFiICRpZD1cImFkZHJlc3NcIiAkbGFiZWw9XCJBZGRyZXNzXCIgJGljb249XCJiaS1nZW8tYWx0XCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwic3RyZWV0XCI+Li4uPC9Gb3JtX0ZpZWxkPlxuICAgIDwvUnN4X1RhYj5cbjwvUnN4X1RhYnM+XG4tLT5cbjxEZWZpbmU6UnN4X1RhYiBjbGFzcz1cInRhYi1wYW5lIGZhZGVcIiByb2xlPVwidGFicGFuZWxcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpSc3hfVGFiPlxuIiwiPCEtLVxuUnN4X0Zvcm1cblxuTWFpbiBmb3JtIGNvbnRhaW5lciB0aGF0IG1hbmFnZXMgd2lkZ2V0IGRpc2NvdmVyeSwgdmFsdWUgY29sbGVjdGlvbiwgYW5kIHN1Ym1pc3Npb24uXG5cbiRkYXRhIC0gT2JqZWN0IHdpdGggaW5pdGlhbCBmb3JtIHZhbHVlcyAoZm9yIGVkaXQgbW9kZSlcbiRhY3Rpb24gLSBBamF4IFVSTCBvciBjb250cm9sbGVyIG1ldGhvZCByZWZlcmVuY2UgKGUuZy4sIEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5zYXZlKVxuXG5Vc2FnZTpcbjxSc3hfRm9ybSAkZGF0YT0kY2xpZW50ICRhY3Rpb249RnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLnNhdmU+XG4gICAgPEZvcm1fRmllbGQgJG5hbWU9XCJuYW1lXCIgJGxhYmVsPVwiQ29tcGFueSBOYW1lXCI+XG4gICAgICAgIDxUZXh0X0lucHV0IC8+XG4gICAgPC9Gb3JtX0ZpZWxkPlxuPC9Sc3hfRm9ybT5cbi0tPlxuPERlZmluZTpSc3hfRm9ybSB0YWc9XCJmb3JtXCI+XG5cbiAgICA8ZGl2ICRpZD1cImxvYWRlclwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXIgdGV4dC1wcmltYXJ5IG1iLTNcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPkxvYWRpbmcuLi48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cInRleHQtbXV0ZWRcIj5Mb2FkaW5nIGZvcm0uLi48L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICRpZD1cImZvcm1fY29udGVudFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPCUgaWYgKHdpbmRvdy5yc3hhcHAuZGVidWcpIHsgJT5cbiAgICAgICAgICAgIDwlLS0gPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgJGlkPVwic2VlZF9idG5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1zaHVmZmxlXCI+PC9pPiBGaWxsIFRlc3QgRGF0YVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+IC0tJT5cbiAgICAgICAgPCUgfSAlPlxuXG4gICAgICAgIDxkaXYgJGlkPVwiZXJyb3JcIj48L2Rpdj5cblxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG5cbjwvRGVmaW5lOlJzeF9Gb3JtPiIsIjwhLS1cbkZvcm1fRmllbGRfQWJzdHJhY3RcblxuQWJzdHJhY3QgYmFzZSBjb21wb25lbnQgZm9yIGZvcm0gZmllbGQgd3JhcHBlcnMuIFByb3ZpZGVzIGNvcmUgZnVuY3Rpb25hbGl0eSB3aXRob3V0IHZpc3VhbCBmb3JtYXR0aW5nLlxuRXh0ZW5kIHRoaXMgdG8gY3JlYXRlIGN1c3RvbSBmb3JtIGZpZWxkIHdyYXBwZXJzIHdpdGggZGlmZmVyZW50IHZpc3VhbCBzdHlsZXMuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uIGFuZCBlcnJvciBkaXNwbGF5XG4kbGFiZWwgLSBMYWJlbCB0ZXh0IChvcHRpb25hbCkgLSBhdmFpbGFibGUgZm9yIGNoaWxkIGNsYXNzZXMgdG8gZGlzcGxheVxuJHJlcXVpcmVkIC0gQm9vbGVhbiAob3B0aW9uYWwpIC0gYXZhaWxhYmxlIGZvciBjaGlsZCBjbGFzc2VzIHRvIGluZGljYXRlIHJlcXVpcmVkIGZpZWxkc1xuJGhlbHAgLSBIZWxwIHRleHQgKG9wdGlvbmFsKSAtIGF2YWlsYWJsZSBmb3IgY2hpbGQgY2xhc3NlcyB0byBkaXNwbGF5XG5cbkNoaWxkIGNvbnRlbnQgaXMgdGhlIGZvcm0gd2lkZ2V0IChUZXh0X0lucHV0LCBTZWxlY3RfSW5wdXQsIGV0Yy4pXG5cbk5vdGU6IFRoaXMgaXMgYW4gYWJzdHJhY3QgY29tcG9uZW50LiBVc2UgRm9ybV9GaWVsZCBmb3Igc3RhbmRhcmQgZm9ybWF0dGVkIGZpZWxkcyxcbm9yIGV4dGVuZCB0aGlzIHRvIGNyZWF0ZSBjdXN0b20gZmllbGQgd3JhcHBlcnMuXG4tLT5cbjxEZWZpbmU6Rm9ybV9GaWVsZF9BYnN0cmFjdD5cbiAgICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpGb3JtX0ZpZWxkX0Fic3RyYWN0PiIsIjwhLS1cbkZvcm1fRmllbGRcblxuV3JhcHBlciBjb21wb25lbnQgdGhhdCBwcm92aWRlcyBjb25zaXN0ZW50IGxhYmVsLCBoZWxwIHRleHQsIGFuZCBlcnJvciBkaXNwbGF5IGZvciBmb3JtIHdpZGdldHMuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uIGFuZCBlcnJvciBkaXNwbGF5XG4kbGFiZWwgLSBMYWJlbCB0ZXh0IHRvIGRpc3BsYXkgYWJvdmUgdGhlIGZpZWxkXG4kcmVxdWlyZWQgLSBCb29sZWFuIC0gaWYgdHJ1ZSwgc2hvd3MgcmVkIGFzdGVyaXNrIG5leHQgdG8gbGFiZWxcbiRoZWxwIC0gSGVscCB0ZXh0IHRvIGRpc3BsYXkgYmVsb3cgdGhlIGZpZWxkXG5cblVzYWdlOlxuPEZvcm1fRmllbGQgJG5hbWU9XCJlbWFpbFwiICRsYWJlbD1cIkVtYWlsIEFkZHJlc3NcIiAkcmVxdWlyZWQ9dHJ1ZSAkaGVscD1cIldlJ2xsIG5ldmVyIHNoYXJlIHlvdXIgZW1haWxcIj5cbiAgICA8VGV4dF9JbnB1dCAkcGxhY2Vob2xkZXI9XCJ1c2VyQGV4YW1wbGUuY29tXCIgLz5cbjwvRm9ybV9GaWVsZD5cbi0tPlxuPERlZmluZTpGb3JtX0ZpZWxkIGV4dGVuZHM9XCJGb3JtX0ZpZWxkX0Fic3RyYWN0XCIgdGFnPVwiZGl2XCIgY2xhc3M9XCJmb3JtLWdyb3VwIG1iLTNcIj5cblxuICAgIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiICRpZD1cImZvcm1fbGFiZWxcIj5cbiAgICAgICAgICAgIDwlIT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgPCUgfSAlPlxuXG4gICAgPGRpdiBjbGFzcz1cIjwlPSB0aGlzLmhhc19lcnJvcigpID8gJ2lzLWludmFsaWQnIDogJycgJT5cIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG4gICAgPCUgaWYgKHRoaXMuaGFzX2Vycm9yKCkpIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgZC1ibG9ja1wiPlxuICAgICAgICAgICAgPCU9IHRoaXMuZ2V0X2Vycm9yKCkgJT5cbiAgICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuXG4gICAgPCUgaWYgKHRoaXMuYXJncy5oZWxwKSB7ICU+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cImZvcm0tdGV4dCB0ZXh0LW11dGVkIGQtYmxvY2sgbXQtMVwiPlxuICAgICAgICAgICAgPCU9IHRoaXMuYXJncy5oZWxwICU+XG4gICAgICAgIDwvc21hbGw+XG4gICAgPCUgfSAlPlxuXG48L0RlZmluZTpGb3JtX0ZpZWxkPlxuIiwiPCEtLVxuRm9ybV9IaWRkZW5fRmllbGRcblxuSGlkZGVuIGlucHV0IGZpZWxkIGNvbXBvbmVudC4gVW5saWtlIG90aGVyIEZvcm1fRmllbGRfKiBjb21wb25lbnRzLCB0aGlzIGNvbXBvbmVudFxuSVMgYm90aCB0aGUgZmllbGQgd3JhcHBlciBBTkQgdGhlIGhpZGRlbiBpbnB1dCBpdHNlbGYuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uXG5cblVzYWdlOlxuPEZvcm1fSGlkZGVuX0ZpZWxkICRuYW1lPVwiaWRcIiAvPlxuXG5SZXBsYWNlcyB0aGUgcGF0dGVybjpcbjxGb3JtX0ZpZWxkX0Fic3RyYWN0ICRuYW1lPVwiaWRcIj5cbiAgPEhpZGRlbl9JbnB1dCAvPlxuPC9Gb3JtX0ZpZWxkX0Fic3RyYWN0PlxuLS0+XG48RGVmaW5lOkZvcm1fSGlkZGVuX0ZpZWxkIGV4dGVuZHM9XCJGb3JtX0ZpZWxkX0Fic3RyYWN0XCIgdGFnPVwiaW5wdXRcIiB0eXBlPVwiaGlkZGVuXCIgY2xhc3M9XCJXaWRnZXRcIj5cbjwvRGVmaW5lOkZvcm1fSGlkZGVuX0ZpZWxkPlxuIiwiPCEtLVxuUGluX1ZlcmlmaWNhdGlvbl9Gb3JtXG5cbjYtZGlnaXQgUElOIGVudHJ5IGZvcm0gd2l0aCBhdXRvbWF0aWMgbmF2aWdhdGlvbiBiZXR3ZWVuIGJveGVzLlxuXG5GZWF0dXJlczpcbi0gQXV0by1hZHZhbmNlIHRvIG5leHQgYm94IHdoZW4gZGlnaXQgaXMgZW50ZXJlZFxuLSBCYWNrc3BhY2UgY2xlYXJzIGN1cnJlbnQgYm94IGFuZCBtb3ZlcyB0byBwcmV2aW91c1xuLSBQYXN0ZSBzdXBwb3J0OiBkaXN0cmlidXRlcyBkaWdpdHMgYWNyb3NzIGJveGVzXG4tIFZhbGlkYXRlcyBudW1lcmljIGlucHV0IG9ubHlcblxuVXNhZ2UgaW4gbW9kYWw6XG5jb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAgICB0aXRsZTogXCJFbnRlciBQSU5cIixcbiAgICBjb21wb25lbnQ6IFwiUGluX1ZlcmlmaWNhdGlvbl9Gb3JtXCIsXG4gICAgb25fc3VibWl0OiBhc3luYyAoZm9ybSkgPT4ge1xuICAgICAgICBjb25zdCBwaW4gPSBmb3JtLnZhbCgpO1xuICAgICAgICBpZiAocGluLmxlbmd0aCAhPT0gNikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBLZWVwIG1vZGFsIG9wZW5cbiAgICAgICAgfVxuICAgICAgICAvLyBWZXJpZnkgUElOLi4uXG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHBpbjogcGluIH07XG4gICAgfVxufSk7XG4tLT5cbjxEZWZpbmU6UGluX1ZlcmlmaWNhdGlvbl9Gb3JtIGV4dGVuZHM9XCJSc3hfRm9ybVwiPlxuICAgIDxkaXYgY2xhc3M9XCJwaW4tdmVyaWZpY2F0aW9uLWZvcm1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBpbi1pbnB1dHMgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgZ2FwLTIgbWItM1wiPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzBcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjBcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzFcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjFcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzJcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjJcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzNcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjNcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzRcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjRcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjVcIiAvPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2ICRpZD1cImVycm9yX2NvbnRhaW5lclwiIGRhdGEtaWQ9XCJlcnJvcl9jb250YWluZXJcIiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj48L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgdGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgICAgRW50ZXIgdGhlIDYtZGlnaXQgUElOIGNvZGVcbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L0RlZmluZTpQaW5fVmVyaWZpY2F0aW9uX0Zvcm0+XG4iLCIvLyBKYXZhU2NyaXB0IE1hbmlmZXN0IC0gR2VuZXJhdGVkIGJ5IEJ1bmRsZUNvbXBpbGVyXG4vLyBSZWdpc3RlcnMgYWxsIGNsYXNzZXMgaW4gdGhpcyBidW5kbGUgZm9yIHJ1bnRpbWUgaW50cm9zcGVjdGlvblxuTWFuaWZlc3QuX2RlZmluZShbXG4gICAgW01hbmlmZXN0LCBcIk1hbmlmZXN0XCIsIG51bGxdLFxuICAgIFtSc3hfQmVoYXZpb3JzLCBcIlJzeF9CZWhhdmlvcnNcIiwgbnVsbF0sXG4gICAgW1JzeF9DYWNoZSwgXCJSc3hfQ2FjaGVcIiwgbnVsbF0sXG4gICAgW1JzeF9Jbml0LCBcIlJzeF9Jbml0XCIsIG51bGxdLFxuICAgIFtSc3hfSnNfTW9kZWwsIFwiUnN4X0pzX01vZGVsXCIsIG51bGxdLFxuICAgIFtSc3hfVmlld19UcmFuc2l0aW9ucywgXCJSc3hfVmlld19UcmFuc2l0aW9uc1wiLCBudWxsXSxcbiAgICBbUmVhZFdyaXRlTG9jaywgXCJSZWFkV3JpdGVMb2NrXCIsIG51bGxdLFxuICAgIFtGb3JtX1V0aWxzLCBcIkZvcm1fVXRpbHNcIiwgbnVsbF0sXG4gICAgW0RlYnVnZ2VyLCBcIkRlYnVnZ2VyXCIsIG51bGxdLFxuICAgIFtSc3hfSnFfSGVscGVycywgXCJSc3hfSnFfSGVscGVyc1wiLCBudWxsXSxcbiAgICBbUnN4LCBcIlJzeFwiLCBudWxsXSxcbiAgICBbQWpheCwgXCJBamF4XCIsIG51bGxdLFxuICAgIFtKcWh0bWxfQ29tcG9uZW50LCBcIkpxaHRtbF9Db21wb25lbnRcIiwgX0Jhc2VfSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0pxaHRtbF9JbnRlZ3JhdGlvbiwgXCJKcWh0bWxfSW50ZWdyYXRpb25cIiwgbnVsbF0sXG4gICAgW1Rlc3RfTW9kYWxfRm9ybSwgXCJUZXN0X01vZGFsX0Zvcm1cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Rldl9Nb2RhbHMsIFwiRGV2X01vZGFsc1wiLCBudWxsXSxcbiAgICBbRGV2X0F0dGFjaG1lbnRzLCBcIkRldl9BdHRhY2htZW50c1wiLCBudWxsXSxcbiAgICBbRGV2X0luZGV4LCBcIkRldl9JbmRleFwiLCBudWxsXSxcbiAgICBbRGF0YUdyaWRfQWJzdHJhY3QsIFwiRGF0YUdyaWRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0FjdGl2aXR5X0ZlZWQsIFwiQWN0aXZpdHlfRmVlZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWN0b3JfUmVmZXJlbmNlLCBcIkFjdG9yX1JlZmVyZW5jZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWR2YW5jZWRfU2VhcmNoX1BhbmVsLCBcIkFkdmFuY2VkX1NlYXJjaF9QYW5lbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWxlcnRfQmFubmVyLCBcIkFsZXJ0X0Jhbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQXZhdGFyLCBcIkF2YXRhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQmxvY2txdW90ZSwgXCJCbG9ja3F1b3RlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCcmVhZGNydW1icywgXCJCcmVhZGNydW1ic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19BY3Rpb25fQmFyLCBcIkJ1bGtfQWN0aW9uX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19TZWxlY3Rpb24sIFwiQnVsa19TZWxlY3Rpb25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9Hcm91cCwgXCJCdXR0b25fR3JvdXBcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9QcmltYXJ5LCBcIkJ1dHRvbl9QcmltYXJ5XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCdXR0b25fU2Vjb25kYXJ5LCBcIkJ1dHRvbl9TZWNvbmRhcnlcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbiwgXCJCdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhbGVuZGFyX0V2ZW50LCBcIkNhbGVuZGFyX0V2ZW50XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDYWxlbmRhcl9HcmlkLCBcIkNhbGVuZGFyX0dyaWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhcmQsIFwiQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hhcnRfQ29tcG9uZW50LCBcIkNoYXJ0X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hlY2tib3gsIFwiQ2hlY2tib3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NvZGVfQmxvY2ssIFwiQ29kZV9CbG9ja1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlLCBcIkNvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29tbWVudF9UaHJlYWQsIFwiQ29tbWVudF9UaHJlYWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0RhdGVfUGlja2VyLCBcIkRhdGVfUGlja2VyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtEcm9wZG93bl9NZW51LCBcIkRyb3Bkb3duX01lbnVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0VtcHR5X1N0YXRlLCBcIkVtcHR5X1N0YXRlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtFeHBvcnRfQnV0dG9uLCBcIkV4cG9ydF9CdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ZpbGVfVXBsb2FkLCBcIkZpbGVfVXBsb2FkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGaWx0ZXJfQmFyLCBcIkZpbHRlcl9CYXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fQWN0aW9uc19Db21wb25lbnQsIFwiRm9ybV9BY3Rpb25zX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9GaWVsZF9Hcm91cCwgXCJGb3JtX0ZpZWxkX0dyb3VwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGb3JtX0dyb3VwX0NvbXBvbmVudCwgXCJGb3JtX0dyb3VwX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9Sb3dfQ29tcG9uZW50LCBcIkZvcm1fUm93X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UsIFwiRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0dhbnR0X0NoYXJ0LCBcIkdhbnR0X0NoYXJ0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJY29uX0J1dHRvbiwgXCJJY29uX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX0xhYmVsLCBcIkljb25fV2l0aF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX1RleHQsIFwiSWNvbl9XaXRoX1RleHRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ljb24sIFwiSWNvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSW5mb19Cb3gsIFwiSW5mb19Cb3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0lubGluZV9FZGl0X0ZpZWxkLCBcIklubGluZV9FZGl0X0ZpZWxkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX0ljb24sIFwiSW5wdXRfV2l0aF9JY29uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX1ZhbGlkYXRpb24sIFwiSW5wdXRfV2l0aF9WYWxpZGF0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dCwgXCJJbnB1dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbS2FuYmFuX0JvYXJkLCBcIkthbmJhbl9Cb2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTGluaywgXCJMaW5rXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtMaXN0LCBcIkxpc3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0xvYWRpbmdfU2tlbGV0b24sIFwiTG9hZGluZ19Ta2VsZXRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTWV0cmljX0NhcmQsIFwiTWV0cmljX0NhcmRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vYmlsZV9IZWFkZXIsIFwiTW9iaWxlX0hlYWRlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfRGlhbG9nLCBcIk1vZGFsX0RpYWxvZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTXVsdGlfU2VsZWN0LCBcIk11bHRpX1NlbGVjdFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0JhZGdlLCBcIk5vdGlmaWNhdGlvbl9CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0Ryb3Bkb3duLCBcIk5vdGlmaWNhdGlvbl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbT3ZlcmR1ZV9JbmRpY2F0b3IsIFwiT3ZlcmR1ZV9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BhZ2VfSGVhZGVyLCBcIlBhZ2VfSGVhZGVyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlX1NlY3Rpb24sIFwiUGFnZV9TZWN0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlLCBcIlBhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BvcG92ZXIsIFwiUG9wb3ZlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUHJvZ3Jlc3NfQmFyLCBcIlByb2dyZXNzX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmFkaW9fQnV0dG9uLCBcIlJhZGlvX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmljaF9UZXh0X0VkaXRvciwgXCJSaWNoX1RleHRfRWRpdG9yXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtSb3dfQWN0aW9uX01lbnUsIFwiUm93X0FjdGlvbl9NZW51XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LCBcIlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlYXJjaF9CYXIsIFwiU2VhcmNoX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU2VhcmNoYWJsZV9TZWxlY3QsIFwiU2VhcmNoYWJsZV9TZWxlY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlbGVjdF9Ecm9wZG93biwgXCJTZWxlY3RfRHJvcGRvd25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NpZGViYXJfTmF2LCBcIlNpZGViYXJfTmF2XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTb3J0YWJsZV9Db2x1bW5fSGVhZGVyLCBcIlNvcnRhYmxlX0NvbHVtbl9IZWFkZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NwaW5uZXIsIFwiU3Bpbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdF9DYXJkLCBcIlN0YXRfQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdHVzX0JhZGdlLCBcIlN0YXR1c19CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFiX0NvbnRlbnQsIFwiVGFiX0NvbnRlbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYmxlX1BhZ2luYXRpb24sIFwiVGFibGVfUGFnaW5hdGlvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFibGUsIFwiVGFibGVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYnMsIFwiVGFic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnX0dyb3VwLCBcIlRhZ19Hcm91cFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnLCBcIlRhZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dF9EaXNwbGF5LCBcIlRleHRfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dGFyZWEsIFwiVGV4dGFyZWFcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RocmVlX0NvbHVtbl9MYXlvdXQsIFwiVGhyZWVfQ29sdW1uX0xheW91dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGltZV9QaWNrZXIsIFwiVGltZV9QaWNrZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RpbWVsaW5lLCBcIlRpbWVsaW5lXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUaW1lc3RhbXBfRGlzcGxheSwgXCJUaW1lc3RhbXBfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVG9vbHRpcCwgXCJUb29sdGlwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUb3BfTmF2LCBcIlRvcF9OYXZcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RyZW5kX0luZGljYXRvciwgXCJUcmVuZF9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1R3b19Db2x1bW5fTGF5b3V0LCBcIlR3b19Db2x1bW5fTGF5b3V0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtVc2VyX0F2YXRhcl9Ecm9wZG93biwgXCJVc2VyX0F2YXRhcl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfQWJzdHJhY3QsIFwiTW9kYWxfQWJzdHJhY3RcIiwgbnVsbF0sXG4gICAgW1JzeF9Nb2RhbCwgXCJSc3hfTW9kYWxcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vZGFsLCBcIk1vZGFsXCIsIG51bGxdLFxuICAgIFtCcmVhZGNydW1iX0l0ZW0sIFwiQnJlYWRjcnVtYl9JdGVtXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDbGllbnRfTGFiZWxfTGluaywgXCJDbGllbnRfTGFiZWxfTGlua1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2xpZW50X0xhYmVsLCBcIkNsaWVudF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9JbnB1dF9BYnN0cmFjdCwgXCJGb3JtX0lucHV0X0Fic3RyYWN0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUZXh0X0lucHV0LCBcIlRleHRfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0NoZWNrYm94X0lucHV0LCBcIkNoZWNrYm94X0lucHV0XCIsIEZvcm1fSW5wdXRfQWJzdHJhY3RdLFxuICAgIFtXeXNpd3lnX0lucHV0LCBcIld5c2l3eWdfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW1NlbGVjdF9JbnB1dCwgXCJTZWxlY3RfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0FqYXhfU2VsZWN0X0lucHV0LCBcIkFqYXhfU2VsZWN0X0lucHV0XCIsIFNlbGVjdF9JbnB1dF0sXG4gICAgW0N1cnJlbmN5X0lucHV0LCBcIkN1cnJlbmN5X0lucHV0XCIsIFRleHRfSW5wdXRdLFxuICAgIFtQaG9uZV9UZXh0X0lucHV0LCBcIlBob25lX1RleHRfSW5wdXRcIiwgVGV4dF9JbnB1dF0sXG4gICAgW1N0YXRlX1NlbGVjdF9JbnB1dCwgXCJTdGF0ZV9TZWxlY3RfSW5wdXRcIiwgQWpheF9TZWxlY3RfSW5wdXRdLFxuICAgIFtDb3VudHJ5X1NlbGVjdF9JbnB1dCwgXCJDb3VudHJ5X1NlbGVjdF9JbnB1dFwiLCBBamF4X1NlbGVjdF9JbnB1dF0sXG4gICAgW1Byb2ZpbGVfUGhvdG9fSW5wdXQsIFwiUHJvZmlsZV9QaG90b19JbnB1dFwiLCBGb3JtX0lucHV0X0Fic3RyYWN0XSxcbiAgICBbUnN4X1RhYnMsIFwiUnN4X1RhYnNcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1JzeF9UYWIsIFwiUnN4X1RhYlwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUnN4X0Zvcm0sIFwiUnN4X0Zvcm1cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1Bpbl9WZXJpZmljYXRpb25fRm9ybSwgXCJQaW5fVmVyaWZpY2F0aW9uX0Zvcm1cIiwgUnN4X0Zvcm1dLFxuICAgIFtGb3JtX0ZpZWxkX0Fic3RyYWN0LCBcIkZvcm1fRmllbGRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fRmllbGQsIFwiRm9ybV9GaWVsZFwiLCBGb3JtX0ZpZWxkX0Fic3RyYWN0XSxcbiAgICBbRm9ybV9IaWRkZW5fRmllbGQsIFwiRm9ybV9IaWRkZW5fRmllbGRcIiwgRm9ybV9GaWVsZF9BYnN0cmFjdF1cbl0pO1xuXG4iLCIvLyBSU1ggUm91dGUgRGVmaW5pdGlvbnMgLSBHZW5lcmF0ZWQgYnkgQnVuZGxlQ29tcGlsZXJcbi8vIFByb3ZpZGVzIHJvdXRlIHBhdHRlcm5zIGZvciB0eXBlLXNhZmUgVVJMIGdlbmVyYXRpb25cblJzeC5fZGVmaW5lX3JvdXRlcyh7XG4gICAgXCJEZXZfSW5kZXhfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZGV2XCJcbiAgICB9LFxuICAgIFwiRGV2X01vZGFsc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9kZXYvbW9kYWxzXCJcbiAgICB9LFxuICAgIFwiRGV2X0F0dGFjaG1lbnRzX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Rldi9hdHRhY2htZW50c1wiXG4gICAgfVxufSk7XG4iLCIkKGRvY3VtZW50KS5yZWFkeShhc3luYyBmdW5jdGlvbigpIHtcbnRyeSB7XG5jb25zb2xlX2RlYnVnKCdSU1hfSU5JVCcsICdEb2N1bWVudCByZWFkeSwgc3RhcnRpbmcgUnN4Ll9yc3hfY29yZV9ib290Jyk7XG5hd2FpdCBSc3guX3JzeF9jb3JlX2Jvb3QoKTtcbmNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgJ0luaXRpYWxpemF0aW9uIGNvbXBsZXRlJyk7XG59IGNhdGNoIChlcnJvcikge1xuY29uc29sZS5lcnJvcignW1JTWF9JTklUXSBJbml0aWFsaXphdGlvbiBmYWlsZWQ6JywgZXJyb3IpO1xuY29uc29sZS5lcnJvcignW1JTWF9JTklUXSBTdGFjazonLCBlcnJvci5zdGFjayk7XG50aHJvdyBlcnJvcjtcbn1cbn0pOyJdLCJzb3VyY2VSb290IjoiIn0=
|