Standardize settings file naming and relocate documentation files Fix code quality violations from rsx:check Reorganize user_management directory into logical subdirectories Move Quill Bundle to core and align with Tom Select pattern Simplify Site Settings page to focus on core site information Complete Phase 5: Multi-tenant authentication with login flow and site selection Add route query parameter rule and synchronize filename validation logic Fix critical bug in UpdateNpmCommand causing missing JavaScript stubs Implement filename convention rule and resolve VS Code auto-rename conflict Implement js-sanitizer RPC server to eliminate 900+ Node.js process spawns Implement RPC server architecture for JavaScript parsing WIP: Add RPC server infrastructure for JS parsing (partial implementation) Update jqhtml terminology from destroy to stop, fix datagrid DOM preservation Add JQHTML-CLASS-01 rule and fix redundant class names Improve code quality rules and resolve violations Remove legacy fatal error format in favor of unified 'fatal' error type Filter internal keys from window.rsxapp output Update button styling and comprehensive form/modal documentation Add conditional fly-in animation for modals Fix non-deterministic bundle compilation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
22029 lines
2.1 MiB
22029 lines
2.1 MiB
/* === storage/rsx-tmp/bundle_config_Frontend_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);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/edit/save_client.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Save client handler for Form component
|
|
* @param {Object} values - Serialized form values
|
|
* @returns {Promise<Object>} Response {success: bool, errors?: {}, redirect?: string}
|
|
*/
|
|
async function save_client(values) {
|
|
// Check if editing existing client
|
|
const client_id = $('#client-id').val();
|
|
if (client_id) {
|
|
values.id = client_id;
|
|
}
|
|
|
|
// TODO: Collect additional fields not yet in Form component (tags, etc.)
|
|
// For now, just submit the basic fields from the Form component
|
|
|
|
try {
|
|
const response = await Frontend_Clients_Controller.save(values);
|
|
if (response.success) {
|
|
// Redirect to clients list on success
|
|
return {
|
|
success: true,
|
|
redirect: Rsx.Route('Frontend_Clients_Controller', 'index')
|
|
};
|
|
} else {
|
|
// Return validation errors
|
|
return {
|
|
success: false,
|
|
errors: response.errors || {
|
|
_general: response.message || 'An error occurred'
|
|
}
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('Save error:', error);
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
_general: 'An error occurred while saving. Please try again.'
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/save_contact.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Save contact handler for Form component
|
|
* @param {Object} values - Serialized form values
|
|
* @returns {Promise<Object>} Response {success: bool, errors?: {}, redirect?: string}
|
|
*/
|
|
async function save_contact(values) {
|
|
// Check if editing existing contact
|
|
const contact_id = $('#contact-id').val();
|
|
if (contact_id) {
|
|
values.id = contact_id;
|
|
}
|
|
try {
|
|
const response = await Frontend_Contacts_Controller.save(values);
|
|
if (response.success) {
|
|
// Redirect to contact view or list on success
|
|
return {
|
|
success: true,
|
|
redirect: response.redirect || Rsx.Route('Frontend_Contacts_Controller', 'index')
|
|
};
|
|
} else {
|
|
// Return validation errors
|
|
return {
|
|
success: false,
|
|
errors: response.errors || {
|
|
_general: response.message || 'An error occurred'
|
|
}
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('Save error:', error);
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
_general: 'An error occurred while saving. Please try again.'
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === 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/Jqhtml_Component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Jqhtml_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 Jqhtml_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 Jqhtml_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('Jqhtml_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('.Jqhtml_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 Jqhtml_Component_Init class - skip nested components
|
|
let parent = $element[0].parentElement;
|
|
while (parent) {
|
|
if (parent.classList.contains('Jqhtml_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('Jqhtml_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/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 Jqhtml_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.$id('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.$id('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.$id('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.$id('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 Jqhtml_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 Jqhtml_Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Advanced_Search_Panel.js (babel) === */
|
|
"use strict";
|
|
|
|
class Advanced_Search_Panel extends Jqhtml_Component {
|
|
on_ready() {
|
|
// Populate dropdowns if provided
|
|
if (this.args.categories) {
|
|
this.$id('category').set_options(this.args.categories);
|
|
}
|
|
if (this.args.tags) {
|
|
this.$id('tags').set_options(this.args.tags);
|
|
}
|
|
|
|
// Search button
|
|
this.$id('search_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
|
|
// Reset button
|
|
this.$id('reset_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.reset();
|
|
});
|
|
|
|
// Close button
|
|
this.$id('close_btn').on('click', () => {
|
|
if (this.args.on_close) {
|
|
this.args.on_close();
|
|
} else {
|
|
this.$.hide();
|
|
}
|
|
});
|
|
|
|
// Form submit
|
|
this.$id('search_form').on('submit', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
}
|
|
perform_search() {
|
|
const criteria = {
|
|
keywords: this.$id('keywords').get_value(),
|
|
category: this.$id('category').get_value(),
|
|
tags: this.$id('tags').get_value(),
|
|
from_date: this.$id('from_date').get_value(),
|
|
to_date: this.$id('to_date').get_value(),
|
|
sort_by: this.$id('sort_by').val(),
|
|
exact_match: this.$id('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.$id('keywords').set_value('');
|
|
this.$id('category').set_value('');
|
|
this.$id('tags').set_value([]);
|
|
this.$id('from_date').set_value('');
|
|
this.$id('to_date').set_value('');
|
|
this.$id('sort_by').val('relevance');
|
|
this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Breadcrumbs.js (babel) === */
|
|
"use strict";
|
|
|
|
class Breadcrumbs extends Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Clear selection on close
|
|
this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $checkbox = this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
this.current_date = new Date();
|
|
this.render_calendar();
|
|
this.$id('prev_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() - 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$id('next_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() + 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$id('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.$id('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.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Build column checkboxes
|
|
if (this.args.columns) {
|
|
this.build_menu(this.args.columns);
|
|
}
|
|
}
|
|
build_menu(columns) {
|
|
const $menu = this.$id('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 Jqhtml_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.$id('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.$id('comment_input').val().trim();
|
|
if (!text) return;
|
|
if (this.args.on_submit) {
|
|
const result = await this.args.on_submit(text);
|
|
if (result) {
|
|
this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $input = this.$id('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.$id('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$id('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$id('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Dropdown_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dropdown_Menu extends Jqhtml_Component {
|
|
on_ready() {
|
|
// Wrap bare text children in <li><a> structure
|
|
const $menu = this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Export_Button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Export_Button extends Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $input = this.$id('file_input');
|
|
const $drop_zone = this.$id('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.$id('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.$id('placeholder').hide();
|
|
this.$id('file_info').show();
|
|
this.$id('file_name').text(file.name);
|
|
this.$id('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.$id('file_info').hide();
|
|
this.$id('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.$id('progress').hide();
|
|
this.$id('file_info').show();
|
|
if (this.args.on_upload) {
|
|
this.args.on_upload(result);
|
|
}
|
|
} catch (error) {
|
|
alert('Upload failed: ' + error.message);
|
|
this.$id('progress').hide();
|
|
this.$id('placeholder').show();
|
|
}
|
|
}
|
|
clear() {
|
|
this.selected_file = null;
|
|
this.$id('file_input').val('');
|
|
this.$id('file_info').hide();
|
|
this.$id('progress').hide();
|
|
this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
this.active_filters = {};
|
|
|
|
// Populate status options if provided
|
|
if (this.args.status_options) {
|
|
const $status = this.$id('status');
|
|
this.args.status_options.forEach(opt => {
|
|
$status.append($('<option>').val(opt.value).text(opt.label));
|
|
});
|
|
}
|
|
|
|
// Date range change handler
|
|
this.$id('date_range').on('change', e => {
|
|
if (e.target.value === 'custom') {
|
|
this.$id('custom_dates').show();
|
|
this.$id('custom_dates_end').show();
|
|
} else {
|
|
this.$id('custom_dates').hide();
|
|
this.$id('custom_dates_end').hide();
|
|
}
|
|
});
|
|
|
|
// Search with debounce
|
|
let search_timeout;
|
|
this.$id('search').$.find('input').on('input', e => {
|
|
clearTimeout(search_timeout);
|
|
search_timeout = setTimeout(() => {
|
|
this.add_filter('search', e.target.value);
|
|
}, 500);
|
|
});
|
|
|
|
// Apply button
|
|
this.$id('apply_btn').on('click', () => {
|
|
this.apply_filters();
|
|
});
|
|
|
|
// Clear button
|
|
this.$id('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.$id('search').get_value();
|
|
const status = this.$id('status').val();
|
|
const date_range = this.$id('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.$id('start_date').get_value();
|
|
const end_date = this.$id('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.$id('search').set_value('');
|
|
this.$id('status').val('');
|
|
this.$id('date_range').val('');
|
|
this.$id('custom_dates').hide();
|
|
this.$id('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.$id('active_filters');
|
|
const $tags = this.$id('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 Jqhtml_Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$id('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.$id('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.$id('inner_html').hide();
|
|
this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$id('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.$id('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.$id('inner_html').hide();
|
|
this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Icon_With_Text.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_With_Text extends Jqhtml_Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/icon.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon extends Jqhtml_Component {
|
|
// SVG icon container with size variants
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Info_Box.js (babel) === */
|
|
"use strict";
|
|
|
|
class Info_Box extends Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
this.current_value = this.args.value || '';
|
|
|
|
// Enter edit mode
|
|
this.$id('display_mode').on('click', () => {
|
|
this.enter_edit_mode();
|
|
});
|
|
|
|
// Save
|
|
this.$id('save_btn').on('click', () => {
|
|
this.save();
|
|
});
|
|
|
|
// Cancel
|
|
this.$id('cancel_btn').on('click', () => {
|
|
this.cancel();
|
|
});
|
|
|
|
// Save on Enter, cancel on Escape
|
|
this.$id('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.$id('input');
|
|
$input.val(this.current_value);
|
|
this.$id('display_mode').hide();
|
|
this.$id('edit_mode').show();
|
|
$input.focus();
|
|
$input.select();
|
|
}
|
|
exit_edit_mode() {
|
|
this.$id('edit_mode').hide();
|
|
this.$id('display_mode').show();
|
|
}
|
|
save() {
|
|
const new_value = this.$id('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.$id('value_display').text(display);
|
|
}
|
|
show_saving() {
|
|
this.$id('save_btn').prop('disabled', true).html('<span class="spinner-border spinner-border-sm"></span>');
|
|
this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $input = this.$id('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.$id('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$id('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$id('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input_With_Validation.js (babel) === */
|
|
"use strict";
|
|
|
|
class Input_With_Validation extends Jqhtml_Component {
|
|
on_ready() {
|
|
const $input = this.$id('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.$id('input').val();
|
|
const $input = this.$id('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.$id('input');
|
|
const $error = this.$id('error');
|
|
$input.removeClass('is-valid').addClass('is-invalid');
|
|
$error.text(message).css('display', 'block');
|
|
this.$id('success').css('display', 'none');
|
|
}
|
|
set_valid(message) {
|
|
const $input = this.$id('input');
|
|
const $success = this.$id('success');
|
|
$input.removeClass('is-invalid').addClass('is-valid');
|
|
this.$id('error').css('display', 'none');
|
|
if (message) {
|
|
$success.text(message).css('display', 'block');
|
|
} else {
|
|
$success.css('display', 'none');
|
|
}
|
|
}
|
|
clear_validation() {
|
|
const $input = this.$id('input');
|
|
$input.removeClass('is-valid is-invalid');
|
|
this.$id('error').css('display', 'none');
|
|
this.$id('success').css('display', 'none');
|
|
this.$.removeClass('was-validated');
|
|
}
|
|
get_value() {
|
|
return this.$id('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$id('input').val(value);
|
|
if (this.$.hasClass('was-validated')) {
|
|
this.validate();
|
|
}
|
|
}
|
|
focus() {
|
|
this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
// Pure container - children already styled
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Mobile_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
class Mobile_Header extends Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Modal_Dialog.js (babel) === */
|
|
"use strict";
|
|
|
|
class Modal_Dialog extends Jqhtml_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 Jqhtml_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.$id('search');
|
|
$search.on('input', e => {
|
|
this.filter_options(e.target.value);
|
|
});
|
|
|
|
// Prevent dropdown close when clicking inside
|
|
this.$id('menu').on('click', e => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Clear/Select all buttons
|
|
this.$id('clear_all').on('click', () => {
|
|
this.clear_all();
|
|
});
|
|
this.$id('select_all').on('click', () => {
|
|
this.select_all();
|
|
});
|
|
|
|
// Update display
|
|
this.update_display();
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$id('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.$id('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.$id('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.$id('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.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $count = this.$id('count');
|
|
// Update count dynamically
|
|
if (this.args.count === 0 || this.args.count === '0') {
|
|
$count.hide();
|
|
}
|
|
}
|
|
set_count(count) {
|
|
const $count = this.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Overdue_Indicator.js (babel) === */
|
|
"use strict";
|
|
|
|
class Overdue_Indicator extends Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
// Content section with spacing - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/page.js (babel) === */
|
|
"use strict";
|
|
|
|
class Page extends Jqhtml_Component {
|
|
// Semantic page container - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Popover.js (babel) === */
|
|
"use strict";
|
|
|
|
class Popover extends Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $bar = this.$id('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.$id('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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $editor = this.$id('editor');
|
|
|
|
// Toolbar button handlers
|
|
this.$id('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.$id('editor').html();
|
|
}
|
|
get_text() {
|
|
return this.$id('editor').text();
|
|
}
|
|
set_value(html) {
|
|
this.$id('editor').html(html);
|
|
}
|
|
clear() {
|
|
this.$id('editor').empty();
|
|
}
|
|
focus() {
|
|
this.$id('editor').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Row_Action_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Row_Action_Menu extends Jqhtml_Component {
|
|
on_ready() {
|
|
// Wrap children in dropdown structure
|
|
const $menu = this.$id('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 Jqhtml_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.$id('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.$id('prev_page').on('click', e => {
|
|
e.preventDefault();
|
|
that.go_to_page(that.data.pagination.current_page - 1);
|
|
});
|
|
that.$id('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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Bind search event
|
|
const $input = this.$id('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 Jqhtml_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.$id('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.$id('selected_text').text(selected_option.label);
|
|
}
|
|
}
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$id('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.$id('selected_text').text(option.label);
|
|
|
|
// Update active state
|
|
this.$id('options').find('.dropdown-item').removeClass('active');
|
|
this.$id('options').find(`[data-value="${option.value}"]`).addClass('active');
|
|
|
|
// Close dropdown
|
|
const dropdown = bootstrap.Dropdown.getInstance(this.$id('button')[0]);
|
|
if (dropdown) {
|
|
dropdown.hide();
|
|
}
|
|
|
|
// Clear search
|
|
this.$id('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.$id('selected_text').text(option.label);
|
|
this.$id('options').find('.dropdown-item').removeClass('active');
|
|
this.$id('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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Auto-wrap children in nav structure if needed
|
|
const $nav_items = this.$id('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 Jqhtml_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.$id('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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Status_Badge.js (babel) === */
|
|
"use strict";
|
|
|
|
class Status_Badge extends Jqhtml_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 Jqhtml_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 Jqhtml_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.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// No special behavior needed
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tag.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tag extends Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
const $input = this.$id('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.$id('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$id('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$id('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timeline.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timeline extends Jqhtml_Component {
|
|
// Pure Bootstrap flexbox - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timestamp_Display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timestamp_Display extends Jqhtml_Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tooltip.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tooltip extends Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Wrap children in nav structure
|
|
const $nav = this.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_Component {
|
|
on_ready() {
|
|
// Ensure proper dropdown item structure
|
|
const $menu = this.$id('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 Jqhtml_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.$id('close_btn').on('click', function (e) {
|
|
e.preventDefault();
|
|
if (that.data.closable) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up backdrop click handler
|
|
this.$id('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.$id('title'));
|
|
|
|
// Set title
|
|
this.$id('title').text(this.data.title);
|
|
|
|
// Show/hide close button based on closable
|
|
if (this.data.closable) {
|
|
this.$id('close_btn').show();
|
|
} else {
|
|
this.$id('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.$id('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.$id('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.$id('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.$id('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.$id('dialog').css('max-width', max_width + 'px');
|
|
|
|
// Check if content exceeds 80% height
|
|
const content_height = this.$id('dialog').outerHeight();
|
|
const max_height = viewport_height * 0.8;
|
|
if (content_height > max_height) {
|
|
// Enable scrolling
|
|
this.$id('dialog').css('max-height', max_height + 'px');
|
|
this.$id('body').css({
|
|
'overflow-y': 'auto',
|
|
'max-height': max_height - 150 + 'px' // Account for header/footer
|
|
});
|
|
} else {
|
|
// Reset scrolling
|
|
this.$id('dialog').css('max-height', '');
|
|
this.$id('body').css({
|
|
'overflow-y': '',
|
|
'max-height': ''
|
|
});
|
|
}
|
|
|
|
// Mobile edge spacing
|
|
if (is_mobile) {
|
|
this.$id('dialog').css('margin', '5%');
|
|
} else {
|
|
this.$id('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.$id('modal').css({
|
|
'transform': 'translate(0, -50px)',
|
|
'opacity': '0'
|
|
});
|
|
this.$id('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow
|
|
this.$id('modal')[0].offsetHeight;
|
|
|
|
// Trigger animation
|
|
this.$id('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.$id('dialog').css('transition', 'none');
|
|
|
|
// Show modal and backdrop instantly
|
|
this.$.css('display', 'flex').css('opacity', '1');
|
|
this.$id('modal').addClass('show').css('opacity', '1');
|
|
this.$id('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow to apply the no-transition state
|
|
this.$id('dialog')[0].offsetHeight;
|
|
|
|
// Re-enable transitions for future animations
|
|
this.$id('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.$id('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.$id('backdrop').hide();
|
|
|
|
// Remove from DOM
|
|
this.$.remove();
|
|
this.$id('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.$id('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.$id('title').length,
|
|
body: modal_instance.$id('body').length,
|
|
footer: modal_instance.$id('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 Jqhtml_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 Jqhtml_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 Jqhtml_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 Jqhtml_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.$id('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.$id('input').exists()) {
|
|
this.$id('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.$id('input');
|
|
const $label = this.$id('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.$id('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.$id('input').exists()) {
|
|
this.$id('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.$id('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.$id('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.$id('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.$id('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.$id('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.tom_select) {
|
|
this.tom_select.setValue(this.data.value, true);
|
|
} else if (this.$id('input').exists()) {
|
|
this.$id('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.$id('input').exists()) {
|
|
this.$id('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.$id('input').val();
|
|
return this._get_numeric_value(raw);
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$id('input').exists()) {
|
|
this.$id('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.$id('input').exists()) {
|
|
this.$id('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$id('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.$id('input').val() || '';
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$id('input').exists()) {
|
|
this.$id('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.$id('input').exists()) {
|
|
this.$id('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.$id('input').exists()) {
|
|
this.$id('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$id('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.$id('upload_btn').on('click', () => {
|
|
this.$id('file_input').click();
|
|
});
|
|
|
|
// Handle file selection
|
|
this.$id('file_input').on('change', () => {
|
|
const file = this.$id('file_input')[0].files[0];
|
|
if (!file) return;
|
|
this.upload_photo(file);
|
|
});
|
|
|
|
// Handle remove button
|
|
if (this.args.show_remove) {
|
|
this.$id('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.$id('file_input').val(''); // Clear selection
|
|
return;
|
|
}
|
|
|
|
// Show spinner, dim image
|
|
this.$id('spinner').removeClass('d-none');
|
|
this.$id('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.$id('spinner').addClass('d-none');
|
|
this.$id('photo').css('opacity', '1');
|
|
|
|
// Clear file input for future uploads
|
|
this.$id('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.$id('spinner').addClass('d-none');
|
|
this.$id('photo').css('opacity', '1');
|
|
|
|
// Clear file input
|
|
this.$id('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 Jqhtml_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.$id('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.$id('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.$id('nav').find('a[data-bs-toggle="tab"]').removeClass('active').attr('aria-selected', 'false');
|
|
this.$id('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.$id('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.$id('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 Jqhtml_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 Jqhtml_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.$id('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.$id('seed_btn').exists()) {
|
|
that.$id('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.$id('loader').hide();
|
|
this.$id('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.$id('error'));
|
|
}
|
|
async submit() {
|
|
// Clear any previous errors
|
|
Form_Utils.reset_form_errors(this.$);
|
|
this.$id('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.$id(`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.$id(`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.$id(`digit_${first_empty}`)[0].focus();
|
|
} else {
|
|
this.$id(`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.$id(`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.$id(`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.$id(`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.$id(`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.$id(`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.$id('error_container').hide().empty();
|
|
|
|
// Validate PIN is 6 digits
|
|
if (pin.length !== this.pin_length) {
|
|
this.$id('error_container').text('Please enter all 6 digits').show();
|
|
|
|
// Mark inputs as invalid
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
if (!this.$id(`digit_${i}`).val()) {
|
|
this.$id(`digit_${i}`).addClass('is-invalid');
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Remove invalid class from all inputs
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
this.$id(`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 Jqhtml_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.$id('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 || '');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/dashboard/frontend_dashboard.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Dashboard {
|
|
static init() {
|
|
if (!$(".Frontend_Dashboard").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Dashboard initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Dashboard.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/frontend/clients/index/clients_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Clients_DataGrid Component
|
|
*
|
|
* Concrete implementation for clients datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Clients_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/edit/frontend_clients_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients_Edit {
|
|
static init() {
|
|
if (!$('.Frontend_Clients_Edit').exists()) return;
|
|
|
|
// Handle dynamic tag addition
|
|
$('#add-tag').on('click', function () {
|
|
const tag_html = `
|
|
<div class="input-group mb-2">
|
|
<input type="text" class="form-control" name="tags[]" placeholder="e.g., VIP, Enterprise, Strategic Partner">
|
|
<button class="btn btn-danger remove-tag" type="button">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
`;
|
|
$('#tags-container').append(tag_html);
|
|
});
|
|
|
|
// Handle tag removal
|
|
$(document).on('click', '.remove-tag', function (e) {
|
|
const $button = $(e.currentTarget);
|
|
// Only remove if more than one tag field exists
|
|
if ($('#tags-container .input-group').length > 1) {
|
|
$button.closest('.input-group').remove();
|
|
} else {
|
|
// Clear the value of the last remaining field
|
|
$button.closest('.input-group').find('input').val('');
|
|
}
|
|
});
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/view/frontend_clients_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients_View {
|
|
static init() {
|
|
if (!$(".Frontend_Clients_View").exists()) return;
|
|
console_debug('CLIENT', 'Frontend_Clients_View initialized');
|
|
|
|
// Handle delete button
|
|
$('#delete-client-btn').on('click', async function () {
|
|
const $element = $(this);
|
|
const client_id = $element.data('client-id');
|
|
const confirmed = await Modal.confirm('Delete Client', 'Are you sure you want to delete this client?\n\nThis action can be undone by restoring the client.', 'Delete', 'Cancel');
|
|
if (confirmed) {
|
|
const result = await Frontend_Clients_Controller.delete({
|
|
id: client_id
|
|
});
|
|
if (result.success) {
|
|
// Reload the page to show deleted status
|
|
location.reload();
|
|
} else {
|
|
alert(result.message || 'Failed to delete client');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle restore button
|
|
$('#restore-client-btn').on('click', async function () {
|
|
const $element = $(this);
|
|
const client_id = $element.data('client-id');
|
|
const confirmed = await Modal.confirm('Restore Client', 'Are you sure you want to restore this client?', 'Restore', 'Cancel');
|
|
if (confirmed) {
|
|
const result = await Frontend_Clients_Controller.restore({
|
|
id: client_id
|
|
});
|
|
if (result.success) {
|
|
// Reload the page to show restored status
|
|
location.reload();
|
|
} else {
|
|
alert(result.message || 'Failed to restore client');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients_View.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/frontend_clients.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients {
|
|
static init() {
|
|
if (!$('.Frontend_Clients').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Clients initialized');
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/team/frontend_settings_team.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Team {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Team").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Team initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Team.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/frontend/settings/notifications/frontend_settings_notifications.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Notifications {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Notifications").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Notifications initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Notifications.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/frontend/settings/billing/frontend_settings_billing.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Billing {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Billing").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Billing initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Billing.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/frontend/settings/import/frontend_settings_import.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Import {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Import").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Import initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Import.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/frontend/settings/api/frontend_settings_api.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Api {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Api").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Api initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Api.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/frontend/settings/templates/frontend_settings_templates.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Templates {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Templates").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Templates initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Templates.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/frontend/settings/audit/frontend_settings_audit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Audit {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Audit").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Audit initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Audit.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/frontend/settings/profile_display/frontend_settings_profile_display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Profile_Display {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Profile_Display").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Profile_Display initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Profile_Display.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/frontend/settings/user_settings/frontend_settings_user_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Settings {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_User_Settings").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_User_Settings initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Settings.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/frontend/settings/password_security/frontend_settings_password_security.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Password_Security {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Password_Security").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Password_Security initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Password_Security.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/frontend/settings/api_keys/frontend_settings_api_keys.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Api_Keys {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Api_Keys").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Api_Keys initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Api_Keys.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/frontend/settings/user_management/users_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Users_DataGrid Component
|
|
*
|
|
* Concrete implementation for clients datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Users_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/add_user_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Add_User_Form
|
|
*
|
|
* Modal form component for inviting users to the current site.
|
|
* See add_user_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Implements vals() method for form data extraction
|
|
* - Provides default role_id (Member = 3)
|
|
*/
|
|
class Add_User_Form extends Jqhtml_Component {
|
|
/**
|
|
* Get or set form values
|
|
* @param {Object} [values] - If provided, populates form with these values
|
|
* @returns {Object|null} - Form values if getting, null if setting
|
|
*/
|
|
// vals(values) {
|
|
// const form = this.$.find('form');
|
|
// if (values) {
|
|
// // Setter - populate form
|
|
// form.find('[name="email"]').val(values.email || '');
|
|
// form.find('[name="first_name"]').val(values.first_name || '');
|
|
// form.find('[name="last_name"]').val(values.last_name || '');
|
|
// form.find('[name="role_id"]').val(values.role_id || 3); // Default to Member
|
|
// form.find('[name="phone"]').val(values.phone || '');
|
|
// return null;
|
|
// } else {
|
|
// // Getter - extract form values
|
|
// return {
|
|
// email: form.find('[name="email"]').val(),
|
|
// first_name: form.find('[name="first_name"]').val(),
|
|
// last_name: form.find('[name="last_name"]').val(),
|
|
// role_id: parseInt(form.find('[name="role_id"]').val()) || 3,
|
|
// phone: form.find('[name="phone"]').val()
|
|
// };
|
|
// }
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/add_user_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Add_User_Modal - Modal for adding/inviting new users to site
|
|
*
|
|
* Displays form to collect user information and create pending invitation.
|
|
* Uses Add_User_Modal_Form component for UI and validation.
|
|
*
|
|
* Returns created user record on success, false on cancel.
|
|
*/
|
|
class Add_User_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show add user modal
|
|
*
|
|
* @returns {Promise<Object|false>} User record on success, false on cancel
|
|
*/
|
|
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 Frontend_Settings_User_Management_Controller.add_user(values);
|
|
return result; // Close modal, return user data
|
|
} catch (error) {
|
|
// Render error (form handles both validation and generic errors)
|
|
await form.render_error(error);
|
|
return false; // Keep modal open
|
|
}
|
|
}
|
|
});
|
|
return result || false;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/send_user_invite_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Send_User_Invite_Modal - Modal for sending/resending user invitations
|
|
*
|
|
* Handles both initial invitation sending (after user creation) and resending
|
|
* expired/pending invitations. Calls backend endpoint to generate new invite
|
|
* code and displays URL for testing (until email system implemented).
|
|
*
|
|
* Returns invite data on success, false on error.
|
|
*/
|
|
class Send_User_Invite_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show send invite modal and trigger backend invite
|
|
*
|
|
* @param {number} user_id - User ID to send invite to
|
|
* @returns {Promise<Object|false>} Invite data on success, false on error
|
|
*/
|
|
static async show(user_id) {
|
|
try {
|
|
// Call backend to send/resend invite
|
|
const result = await Frontend_Settings_User_Management_Controller.send_invite({
|
|
user_id
|
|
});
|
|
|
|
// Show invite URL for testing (until email system implemented)
|
|
if (result.invite_url) {
|
|
await Modal.alert('User Invited Successfully', `Invitation sent!\n\nTest invitation URL:\n${result.invite_url}`);
|
|
}
|
|
return result;
|
|
} catch (error) {
|
|
// Show error to user
|
|
await Modal.error(error, 'Failed to Send Invitation');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/frontend_settings_user_management.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Management {
|
|
static init() {
|
|
if (!$('.Frontend_Settings_User_Management').exists()) return;
|
|
|
|
// Handle Add User button click
|
|
$('#btn_add_user').on('click', async function () {
|
|
await Frontend_Settings_User_Management.handle_add_user();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add user workflow: show add modal, refresh grid, show invite modal
|
|
*/
|
|
static async handle_add_user() {
|
|
// Show add user modal
|
|
const user = await Add_User_Modal.show();
|
|
if (user) {
|
|
// Refresh the user list
|
|
$('.Users_DataGrid').component().reload();
|
|
|
|
// Show send invite modal
|
|
await Send_User_Invite_Modal.show(user.id);
|
|
}
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Management.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/edit_user_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Edit_User_Modal - Modal for editing existing user information
|
|
*
|
|
* Displays form to update user profile information.
|
|
* Uses Edit_User_Modal_Form component for UI and validation.
|
|
*
|
|
* Returns updated user record on success, false on cancel.
|
|
*/
|
|
class Edit_User_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show edit user modal
|
|
*
|
|
* @param {number} user_id - ID of user to edit
|
|
* @returns {Promise<Object|false>} Updated user record on success, false on cancel
|
|
*/
|
|
static async show(user_id) {
|
|
// Load user data for editing
|
|
let user_data;
|
|
try {
|
|
user_data = await Frontend_Settings_User_Management_Controller.get_user_for_edit({
|
|
user_id
|
|
});
|
|
} catch (error) {
|
|
await Modal.error(error, 'Failed to Load User');
|
|
return false;
|
|
}
|
|
const result = await Modal.form({
|
|
title: 'Edit User',
|
|
component: 'Edit_User_Modal_Form',
|
|
component_args: {
|
|
data: user_data
|
|
},
|
|
on_submit: async form => {
|
|
try {
|
|
const values = form.vals();
|
|
const result = await Frontend_Settings_User_Management_Controller.save_user(values);
|
|
return result; // Close modal, return user data
|
|
} catch (error) {
|
|
// Render error (form handles both validation and generic errors)
|
|
await form.render_error(error);
|
|
return false; // Keep modal open
|
|
}
|
|
}
|
|
});
|
|
return result || false;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/frontend_settings_user_management_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Management_View {
|
|
static init() {
|
|
if (!$('.Frontend_Settings_User_Management_View').exists()) return;
|
|
|
|
// Handle Edit User button click
|
|
$('#btn_edit_user').on('click', async function () {
|
|
await Frontend_Settings_User_Management_View.handle_edit_user();
|
|
});
|
|
|
|
// Handle Resend Invite button click
|
|
$('#btn_resend_invite').on('click', async function () {
|
|
await Frontend_Settings_User_Management_View.handle_resend_invite();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Edit user workflow: show edit modal, refresh page on save
|
|
*/
|
|
static async handle_edit_user() {
|
|
var _window$rsxapp$page_d;
|
|
// Get user ID from page data
|
|
const user_id = (_window$rsxapp$page_d = window.rsxapp.page_data) === null || _window$rsxapp$page_d === void 0 ? void 0 : _window$rsxapp$page_d.user_id;
|
|
if (!user_id) {
|
|
await Modal.error('User ID not found');
|
|
return;
|
|
}
|
|
|
|
// Show edit user modal
|
|
const result = await Edit_User_Modal.show(user_id);
|
|
if (result) {
|
|
// Refresh page to show updated user information
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resend invite workflow: call send invite modal
|
|
*/
|
|
static async handle_resend_invite() {
|
|
var _window$rsxapp$page_d2;
|
|
// Get user ID from page data
|
|
const user_id = (_window$rsxapp$page_d2 = window.rsxapp.page_data) === null || _window$rsxapp$page_d2 === void 0 ? void 0 : _window$rsxapp$page_d2.user_id;
|
|
if (!user_id) {
|
|
await Modal.error('User ID not found');
|
|
return;
|
|
}
|
|
|
|
// Show send invite modal
|
|
const result = await Send_User_Invite_Modal.show(user_id);
|
|
if (result) {
|
|
// Refresh page to show updated invite status
|
|
location.reload();
|
|
}
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Management_View.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/site_settings/frontend_settings_site_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Site_Settings {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Site_Settings").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Site_Settings initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Site_Settings.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/frontend/settings/frontend_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Settings Page JavaScript
|
|
*/
|
|
class Frontend_Settings {
|
|
/**
|
|
* Initialize the settings page
|
|
*/
|
|
static on_app_ready() {
|
|
// Only initialize if we're on the settings page
|
|
if (!$(".Frontend_Settings").exists()) {
|
|
return;
|
|
}
|
|
Debugger.console_debug("JS_INIT", "Settings page initialized");
|
|
|
|
// Handle sidebar navigation
|
|
$('.sidebar .nav-link').on('click', function (e) {
|
|
const $link = $(this);
|
|
if ($link.attr('href') === '#') {
|
|
e.preventDefault();
|
|
// Remove active from all links
|
|
$('.sidebar .nav-link').removeClass('active');
|
|
// Add active to clicked
|
|
$link.addClass('active');
|
|
const section = $link.text().trim();
|
|
Debugger.console_debug("UI", "Settings section clicked:", section);
|
|
}
|
|
});
|
|
|
|
// Handle form submissions
|
|
$('form').on('submit', function (e) {
|
|
e.preventDefault();
|
|
const $form = $(this);
|
|
const formData = $form.serialize();
|
|
Debugger.console_debug("FORM", "Settings form submitted", formData);
|
|
|
|
// Show success message (mock)
|
|
const $alert = $('<div class="alert alert-success alert-dismissible fade show" role="alert">').html('Settings saved successfully! <button type="button" class="btn-close" data-bs-dismiss="alert"></button>');
|
|
$form.closest('.card-body').prepend($alert);
|
|
|
|
// Auto-dismiss after 3 seconds
|
|
// setTimeout(() => {
|
|
// $alert.fadeOut(() => $alert.remove());
|
|
// }, 3000);
|
|
});
|
|
|
|
// Quick action buttons
|
|
$('.card-body .btn-primary').on('click', function () {
|
|
const $button = $(this);
|
|
const action = $button.text().trim();
|
|
Debugger.console_debug("UI", "Quick action:", action);
|
|
|
|
// Simulate action
|
|
const originalText = $button.html();
|
|
$button.html('<span class="spinner-border spinner-border-sm me-1"></span> Processing...');
|
|
$button.prop('disabled', true);
|
|
setTimeout(() => {
|
|
$button.html(originalText);
|
|
$button.prop('disabled', false);
|
|
}, 1500);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/index/contacts_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Contacts_DataGrid Component
|
|
*
|
|
* Concrete implementation for contacts datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Contacts_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/_data_table_qq/Data_Table.js (babel) === */
|
|
"use strict";
|
|
|
|
class Data_Table extends Jqhtml_Component {
|
|
on_render() {
|
|
// Hide until data loads to prevent visual glitches
|
|
if (Object.keys(this.data).length === 0) {
|
|
this.$id('footer').css('opacity', '0');
|
|
}
|
|
}
|
|
async on_load() {
|
|
// If data_source provided, fetch data
|
|
if (this.args.data_source) {
|
|
this.data = await this.fetch_data();
|
|
} else if (this.args.columns && this.args.rows) {
|
|
// Use provided static data
|
|
this.data = {
|
|
columns: this.args.columns,
|
|
rows: this.args.rows,
|
|
total: this.args.rows.length,
|
|
start: 1,
|
|
end: this.args.rows.length,
|
|
current_page: 1,
|
|
total_pages: 1
|
|
};
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Show footer after render
|
|
this.$id('footer').css('opacity', '1');
|
|
|
|
// Build column headers with sorting
|
|
if (this.data.columns) {
|
|
this.build_headers(this.data.columns);
|
|
}
|
|
|
|
// Setup search if enabled
|
|
if (this.args.searchable) {
|
|
this.setup_search();
|
|
}
|
|
|
|
// Setup column visibility toggle if enabled
|
|
if (this.args.column_toggle) {
|
|
this.setup_column_toggle();
|
|
}
|
|
|
|
// Setup bulk actions
|
|
if (this.args.bulk_actions) {
|
|
this.setup_bulk_actions();
|
|
}
|
|
|
|
// Attach row checkbox listeners
|
|
this.$.find('.row-checkbox').on('change', () => {
|
|
this.update_bulk_selection();
|
|
});
|
|
|
|
// Setup pagination click handlers
|
|
const $pagination = this.$id('pagination');
|
|
$pagination.$.find('.page-link').on('click', e => {
|
|
e.preventDefault();
|
|
const page_text = $(e.target).text();
|
|
if (page_text === 'Previous') {
|
|
this.load_page(this.data.current_page - 1);
|
|
} else if (page_text === 'Next') {
|
|
this.load_page(this.data.current_page + 1);
|
|
} else {
|
|
const page = int(page_text);
|
|
if (!isNaN(page)) {
|
|
this.load_page(page);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
build_headers(columns) {
|
|
const $header_row = this.$id('header_row');
|
|
|
|
// Skip first cell if bulk actions (already has Bulk_Selection)
|
|
const offset = this.args.bulk_actions ? 1 : 0;
|
|
columns.forEach((col, index) => {
|
|
const $th = $('<th>');
|
|
if (col.sortable !== false) {
|
|
// Create sortable column header
|
|
const $sortable = $('<div>').addClass('Sortable_Column_Header').attr({
|
|
'data-column': col.field,
|
|
'data-sort': 'none'
|
|
});
|
|
const $text = $('<span>').text(col.label || col.field);
|
|
const $icon = $('<span>').attr('data-id', 'sort_icon').html('<i class="text-muted">⇅</i>');
|
|
$sortable.append($text).append(' ').append($icon);
|
|
$sortable.css('cursor', 'pointer');
|
|
$sortable.on('click', () => {
|
|
this.handle_sort(col.field);
|
|
});
|
|
$th.append($sortable);
|
|
} else {
|
|
$th.text(col.label || col.field);
|
|
}
|
|
if (col.width) {
|
|
$th.css('width', col.width);
|
|
}
|
|
$header_row.append($th);
|
|
});
|
|
|
|
// Add actions column header if row_actions enabled
|
|
if (this.args.row_actions) {
|
|
const $th = $('<th>').text('Actions').css('width', '100px');
|
|
$header_row.append($th);
|
|
}
|
|
}
|
|
setup_search() {
|
|
const $container = this.$id('search_container');
|
|
const $search = $('<input>').attr({
|
|
type: 'search',
|
|
placeholder: 'Search...',
|
|
class: 'form-control form-control-sm'
|
|
}).css('width', '200px');
|
|
$container.append($search);
|
|
let timeout;
|
|
$search.on('input', e => {
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(() => {
|
|
this.search_query = e.target.value;
|
|
this.reload_data();
|
|
}, 300);
|
|
});
|
|
}
|
|
setup_column_toggle() {
|
|
const $container = this.$id('column_toggle_container');
|
|
const $toggle = $('<div>').addClass('Column_Visibility_Toggle');
|
|
$container.append($toggle);
|
|
|
|
// Initialize component manually
|
|
const toggle_component = $toggle.component();
|
|
if (toggle_component) {
|
|
toggle_component.args.columns = this.data.columns;
|
|
toggle_component.args.table = this.$id('table').$;
|
|
toggle_component.build_menu(this.data.columns);
|
|
}
|
|
}
|
|
setup_bulk_actions() {
|
|
const $bulk_selection = this.$id('bulk_selection');
|
|
$bulk_selection.$.find('input[type="checkbox"]').on('change', e => {
|
|
const checked = e.target.checked;
|
|
this.$.find('.row-checkbox').prop('checked', checked);
|
|
this.update_bulk_selection();
|
|
});
|
|
}
|
|
update_bulk_selection() {
|
|
const checked = this.$.find('.row-checkbox:checked').length;
|
|
const $bulk_bar = this.$id('bulk_bar');
|
|
if (checked > 0) {
|
|
$bulk_bar.$.show();
|
|
$bulk_bar.set_count(checked);
|
|
} else {
|
|
$bulk_bar.$.hide();
|
|
}
|
|
}
|
|
async handle_sort(field) {
|
|
// Toggle sort direction
|
|
const current = this.sort_field === field ? this.sort_direction : 'none';
|
|
this.sort_direction = current === 'none' ? 'asc' : current === 'asc' ? 'desc' : 'asc';
|
|
this.sort_field = field;
|
|
|
|
// Update sort icon
|
|
this.$id('header_row').find('[data-column]').each(function () {
|
|
const $sortable = $(this);
|
|
const col = $sortable.attr('data-column');
|
|
const $icon = $sortable.find('[data-id="sort_icon"]');
|
|
if (col === field) {
|
|
$sortable.attr('data-sort', this.sort_direction);
|
|
if (this.sort_direction === 'asc') {
|
|
$icon.html('<i class="text-primary">↑</i>');
|
|
} else if (this.sort_direction === 'desc') {
|
|
$icon.html('<i class="text-primary">↓</i>');
|
|
} else {
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
} else {
|
|
$sortable.attr('data-sort', 'none');
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
}.bind(this));
|
|
await this.reload_data();
|
|
}
|
|
async load_page(page) {
|
|
if (page < 1 || page > this.data.total_pages) return;
|
|
this.current_page = page;
|
|
await this.reload_data();
|
|
}
|
|
async fetch_data() {
|
|
const params = {
|
|
page: this.current_page || 1,
|
|
per_page: this.args.per_page || 20,
|
|
sort_field: this.sort_field,
|
|
sort_direction: this.sort_direction,
|
|
search: this.search_query
|
|
};
|
|
|
|
// Call data source (can be URL or function)
|
|
if (typeof this.args.data_source === 'function') {
|
|
return await this.args.data_source(params);
|
|
} else {
|
|
const url = new URL(this.args.data_source, window.location.origin);
|
|
Object.keys(params).forEach(key => {
|
|
if (params[key]) url.searchParams.append(key, params[key]);
|
|
});
|
|
const response = await fetch(url);
|
|
return await response.json();
|
|
}
|
|
}
|
|
get_selected_ids() {
|
|
const ids = [];
|
|
this.$.find('.row-checkbox:checked').each(function () {
|
|
ids.push($(this).val());
|
|
});
|
|
return ids;
|
|
}
|
|
async reload_data() {
|
|
// Show loading state
|
|
const $tbody = this.$id('tbody');
|
|
$tbody.html(`
|
|
<tr>
|
|
<td colspan="100" class="text-center py-5">
|
|
<div class="spinner-border spinner-border-sm" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
<div class="mt-2 text-muted">Loading data...</div>
|
|
</td>
|
|
</tr>
|
|
`);
|
|
|
|
// Fetch new data
|
|
this.data = await this.fetch_data();
|
|
|
|
// Re-render entire component
|
|
this.render();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/form/client_selector_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Selector_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Load clients via Ajax endpoint if data not provided
|
|
if (!this.args.data) {
|
|
this.data.select_values = await Frontend_Contacts_Controller.get_clients();
|
|
} else {
|
|
// Use parent on_load for custom data endpoints
|
|
await super.on_load();
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select Client...';
|
|
}
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/frontend_contacts_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts_Edit {
|
|
static init() {
|
|
// No initialization needed - submit button automatically wired by Rsx_Form
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/view/frontend_contacts_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts_View {
|
|
static init() {
|
|
if (!$('.Frontend_Contacts_View').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Contacts_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts_View.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/frontend/contacts/frontend_contacts.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts {
|
|
static init() {
|
|
if (!$('.Frontend_Contacts').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Contacts initialized');
|
|
|
|
// // Example: Handle button clicks
|
|
// $('.btn-action').on('click', function() {
|
|
// // Handle action
|
|
// });
|
|
|
|
// // Example: Initialize tooltips
|
|
// $('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts.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/frontend/projects/index/projects_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Projects_DataGrid Component
|
|
*
|
|
* Concrete implementation for projects datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Projects_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/edit/frontend_projects_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_Edit {
|
|
static init() {
|
|
// No initialization needed - submit button automatically wired by Rsx_Form
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/frontend_projects_list.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_List {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_List").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_List initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_List.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/frontend/projects/frontend_projects_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_View {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_View.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/frontend/projects/frontend_projects_add.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_Add {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_Add").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_Add initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_Add.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/frontend/projects/frontend_projects.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects {
|
|
static init() {
|
|
if (!$(".Frontend_Projects").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects initialized');
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/tasks/frontend_tasks.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks.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/frontend/tasks/frontend_tasks_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks_View {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks_View.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/frontend/tasks/frontend_tasks_add.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks_Add {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks_Add").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks_Add initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks_Add.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/frontend/calendar/frontend_calendar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Calendar {
|
|
static init() {
|
|
if (!$(".Frontend_Calendar").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Calendar initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Calendar.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/frontend/calendar/frontend_calendar_event.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Calendar_Event {
|
|
static init() {
|
|
if (!$(".Frontend_Calendar_Event").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Calendar_Event initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Calendar_Event.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/frontend/invoices/frontend_invoices.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Invoices {
|
|
static init() {
|
|
if (!$(".Frontend_Invoices").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Invoices initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Invoices.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/frontend/invoices/frontend_invoices_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Invoices_View {
|
|
static init() {
|
|
if (!$(".Frontend_Invoices_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Invoices_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Invoices_View.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/frontend/invoices/frontend_invoices_add.js (babel) === */
|
|
"use strict";
|
|
|
|
function _72eab514_defineProperty(e, r, t) { return (r = _72eab514_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _72eab514_toPropertyKey(t) { var i = _72eab514_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _72eab514_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); }
|
|
/**
|
|
* Frontend_Invoices_Add Component
|
|
*
|
|
* Handles dynamic line items and invoice calculations
|
|
*/
|
|
class Frontend_Invoices_Add {
|
|
static async on_app_ready() {
|
|
if (!$(".Frontend_Invoices_Add").exists()) return;
|
|
|
|
// Add line item button
|
|
$('#addLineItem').on('click', () => {
|
|
Frontend_Invoices_Add.add_line_item();
|
|
});
|
|
|
|
// Initial calculation
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
|
|
// Attach event handlers to existing line items
|
|
Frontend_Invoices_Add.attach_line_item_handlers();
|
|
|
|
// Tax rate change
|
|
$('#tax_rate').on('input', () => {
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
});
|
|
}
|
|
static attach_line_item_handlers() {
|
|
// Quantity and rate changes
|
|
$('.item-quantity, .item-rate').off('input').on('input', function () {
|
|
Frontend_Invoices_Add.update_line_item_amount($(this).closest('tr'));
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
});
|
|
|
|
// Remove item buttons
|
|
$('.remove-item').off('click').on('click', function () {
|
|
const $row = $(this).closest('tr');
|
|
if ($('#lineItemsBody tr').length > 1) {
|
|
$row.remove();
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
} else {
|
|
alert('Invoice must have at least one line item');
|
|
}
|
|
});
|
|
}
|
|
static add_line_item() {
|
|
const index = Frontend_Invoices_Add.line_item_count++;
|
|
const $row = $(`
|
|
<tr class="line-item">
|
|
<td>
|
|
<input type="text" class="form-control form-control-sm" name="items[${index}][description]"
|
|
placeholder="Item description" required>
|
|
</td>
|
|
<td>
|
|
<input type="number" class="form-control form-control-sm text-end item-quantity"
|
|
name="items[${index}][quantity]" value="1" min="0" step="0.01" required>
|
|
</td>
|
|
<td>
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text">$</span>
|
|
<input type="number" class="form-control text-end item-rate"
|
|
name="items[${index}][rate]" value="0.00" min="0" step="0.01" required>
|
|
</div>
|
|
</td>
|
|
<td class="text-end">
|
|
<div class="fw-bold item-amount">$0.00</div>
|
|
</td>
|
|
<td class="text-center">
|
|
<button type="button" class="btn btn-sm btn-danger remove-item">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`);
|
|
$('#lineItemsBody').append($row);
|
|
Frontend_Invoices_Add.attach_line_item_handlers();
|
|
}
|
|
static update_line_item_amount(row) {
|
|
const quantity = float(row.find('.item-quantity').val()) || 0;
|
|
const rate = float(row.find('.item-rate').val()) || 0;
|
|
const amount = quantity * rate;
|
|
row.find('.item-amount').text(`$${amount.toFixed(2)}`);
|
|
}
|
|
static calculate_totals() {
|
|
let subtotal = 0;
|
|
|
|
// Calculate subtotal from all line items
|
|
$('#lineItemsBody tr').each(function () {
|
|
const quantity = float($(this).find('.item-quantity').val()) || 0;
|
|
const rate = float($(this).find('.item-rate').val()) || 0;
|
|
subtotal += quantity * rate;
|
|
});
|
|
|
|
// Calculate tax
|
|
const tax_rate = float($('#tax_rate').val()) || 0;
|
|
const tax_amount = subtotal * (tax_rate / 100);
|
|
const total = subtotal + tax_amount;
|
|
|
|
// Update displays
|
|
$('#subtotalDisplay').text(`$${subtotal.toFixed(2)}`);
|
|
$('#taxDisplay').text(`$${tax_amount.toFixed(2)}`);
|
|
$('#totalDisplay').text(`$${total.toFixed(2)}`);
|
|
}
|
|
}
|
|
_72eab514_defineProperty(Frontend_Invoices_Add, "line_item_count", 1);
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports {
|
|
static init() {
|
|
if (!$(".Frontend_Reports").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports.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/frontend/reports/frontend_reports_revenue.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Revenue {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Revenue").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Revenue initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Revenue.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/frontend/reports/frontend_reports_clients.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Clients {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Clients").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Clients initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Clients.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/frontend/reports/frontend_reports_projects.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Projects {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Projects").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Projects initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Projects.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/frontend/reports/frontend_reports_time.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Time {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Time").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Time initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Time.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/frontend/account/frontend_account.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* JavaScript for Frontend_Account view
|
|
*/
|
|
class Frontend_Account {
|
|
/**
|
|
* Initialize the view when app is ready
|
|
* This method is automatically called by RSX framework
|
|
* No manual registration is required
|
|
*/
|
|
static on_app_ready() {
|
|
// Check if we're on this specific page
|
|
if (!$(".Frontend_Account").exists()) return;
|
|
|
|
// View-specific initialization
|
|
console.log('Frontend_Account initialized');
|
|
}
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Rsx_Reference_Data_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Rsx_Reference_Data_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Rsx_Reference_Data_Controller {
|
|
/**
|
|
* Call Rsx_Reference_Data_Controller::countries via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async countries(params = {}) {
|
|
return Ajax.call('/_ajax/Rsx_Reference_Data_Controller/countries', params);
|
|
}
|
|
|
|
/**
|
|
* Call Rsx_Reference_Data_Controller::states via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async states(params = {}) {
|
|
return Ajax.call('/_ajax/Rsx_Reference_Data_Controller/states', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Rsx_Reference_Data_Controller.countries.path = '/_ajax/Rsx_Reference_Data_Controller/countries';
|
|
Rsx_Reference_Data_Controller.states.path = '/_ajax/Rsx_Reference_Data_Controller/states';
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/client-department-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Client_Department_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Client_Department_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Client_Department_Model';
|
|
}
|
|
|
|
/**
|
|
* Fetch client relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async client() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Department_Model/${this.id}/client`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch contacts relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async contacts() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Department_Model/${this.id}/contacts`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch created_by relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async created_by() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Department_Model/${this.id}/created_by`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/client-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Client_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Client_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Client_Model';
|
|
}
|
|
|
|
static PRIORITY_LOW = 1;
|
|
static PRIORITY_MEDIUM = 2;
|
|
static PRIORITY_HIGH = 3;
|
|
static PRIORITY_URGENT = 4;
|
|
|
|
static priority_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"PRIORITY_LOW","label":"Low","badge":"bg-secondary"};
|
|
order.push(1);
|
|
data[2] = {"constant":"PRIORITY_MEDIUM","label":"Medium","badge":"bg-primary"};
|
|
order.push(2);
|
|
data[3] = {"constant":"PRIORITY_HIGH","label":"High","badge":"bg-warning"};
|
|
order.push(3);
|
|
data[4] = {"constant":"PRIORITY_URGENT","label":"Urgent","badge":"bg-danger"};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static priority_label_list() {
|
|
const values = {};
|
|
values[1] = 'Low';
|
|
values[2] = 'Medium';
|
|
values[3] = 'High';
|
|
values[4] = 'Urgent';
|
|
return values;
|
|
}
|
|
|
|
static priority_enum_select() {
|
|
const fullData = this.priority_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch billing_contact relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async billing_contact() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Model/${this.id}/billing_contact`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch contacts relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async contacts() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Model/${this.id}/contacts`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch departments relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async departments() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Model/${this.id}/departments`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch created_by relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async created_by() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Model/${this.id}/created_by`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch owner relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async owner() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Client_Model/${this.id}/owner`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/contact-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Contact_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Contact_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Contact_Model';
|
|
}
|
|
|
|
static PRIORITY_LOW = 1;
|
|
static PRIORITY_MEDIUM = 2;
|
|
static PRIORITY_HIGH = 3;
|
|
static PRIORITY_URGENT = 4;
|
|
|
|
static priority_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"PRIORITY_LOW","label":"Low","badge":"bg-secondary"};
|
|
order.push(1);
|
|
data[2] = {"constant":"PRIORITY_MEDIUM","label":"Medium","badge":"bg-primary"};
|
|
order.push(2);
|
|
data[3] = {"constant":"PRIORITY_HIGH","label":"High","badge":"bg-warning"};
|
|
order.push(3);
|
|
data[4] = {"constant":"PRIORITY_URGENT","label":"Urgent","badge":"bg-danger"};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static priority_label_list() {
|
|
const values = {};
|
|
values[1] = 'Low';
|
|
values[2] = 'Medium';
|
|
values[3] = 'High';
|
|
values[4] = 'Urgent';
|
|
return values;
|
|
}
|
|
|
|
static priority_enum_select() {
|
|
const fullData = this.priority_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch client relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async client() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/client`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch department relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async department() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/department`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch reports_to relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async reports_to() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/reports_to`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch direct_reports relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async direct_reports() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/direct_reports`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch created_by relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async created_by() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/created_by`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch owner relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async owner() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Contact_Model/${this.id}/owner`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/project-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Project_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Project_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Project_Model';
|
|
}
|
|
|
|
static STATUS_PLANNING = 1;
|
|
static STATUS_ACTIVE = 2;
|
|
static STATUS_ON_HOLD = 3;
|
|
static STATUS_COMPLETED = 4;
|
|
static STATUS_CANCELLED = 5;
|
|
|
|
static status_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"STATUS_PLANNING","label":"Planning","badge":"bg-info"};
|
|
order.push(1);
|
|
data[2] = {"constant":"STATUS_ACTIVE","label":"Active","badge":"bg-success"};
|
|
order.push(2);
|
|
data[3] = {"constant":"STATUS_ON_HOLD","label":"On Hold","badge":"bg-warning"};
|
|
order.push(3);
|
|
data[4] = {"constant":"STATUS_COMPLETED","label":"Completed","badge":"bg-primary"};
|
|
order.push(4);
|
|
data[5] = {"constant":"STATUS_CANCELLED","label":"Cancelled","badge":"bg-secondary"};
|
|
order.push(5);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static status_label_list() {
|
|
const values = {};
|
|
values[1] = 'Planning';
|
|
values[2] = 'Active';
|
|
values[3] = 'On Hold';
|
|
values[4] = 'Completed';
|
|
values[5] = 'Cancelled';
|
|
return values;
|
|
}
|
|
|
|
static status_enum_select() {
|
|
const fullData = this.status_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static PRIORITY_LOW = 1;
|
|
static PRIORITY_MEDIUM = 2;
|
|
static PRIORITY_HIGH = 3;
|
|
static PRIORITY_URGENT = 4;
|
|
|
|
static priority_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"PRIORITY_LOW","label":"Low","badge":"bg-secondary"};
|
|
order.push(1);
|
|
data[2] = {"constant":"PRIORITY_MEDIUM","label":"Medium","badge":"bg-primary"};
|
|
order.push(2);
|
|
data[3] = {"constant":"PRIORITY_HIGH","label":"High","badge":"bg-warning"};
|
|
order.push(3);
|
|
data[4] = {"constant":"PRIORITY_URGENT","label":"Urgent","badge":"bg-danger"};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static priority_label_list() {
|
|
const values = {};
|
|
values[1] = 'Low';
|
|
values[2] = 'Medium';
|
|
values[3] = 'High';
|
|
values[4] = 'Urgent';
|
|
return values;
|
|
}
|
|
|
|
static priority_enum_select() {
|
|
const fullData = this.priority_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch client relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async client() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/client`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch client_department relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async client_department() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/client_department`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch contact relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async contact() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/contact`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch tasks relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async tasks() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/tasks`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch created_by relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async created_by() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/created_by`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch owner relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async owner() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Project_Model/${this.id}/owner`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/task-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Task_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Task_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Task_Model';
|
|
}
|
|
|
|
static STATUS_PENDING = 1;
|
|
static STATUS_IN_PROGRESS = 2;
|
|
static STATUS_COMPLETED = 3;
|
|
static STATUS_CANCELLED = 4;
|
|
|
|
static status_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"STATUS_PENDING","label":"Pending","badge":"bg-secondary"};
|
|
order.push(1);
|
|
data[2] = {"constant":"STATUS_IN_PROGRESS","label":"In Progress","badge":"bg-info"};
|
|
order.push(2);
|
|
data[3] = {"constant":"STATUS_COMPLETED","label":"Completed","badge":"bg-success"};
|
|
order.push(3);
|
|
data[4] = {"constant":"STATUS_CANCELLED","label":"Cancelled","badge":"bg-danger"};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static status_label_list() {
|
|
const values = {};
|
|
values[1] = 'Pending';
|
|
values[2] = 'In Progress';
|
|
values[3] = 'Completed';
|
|
values[4] = 'Cancelled';
|
|
return values;
|
|
}
|
|
|
|
static status_enum_select() {
|
|
const fullData = this.status_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static PRIORITY_LOW = 1;
|
|
static PRIORITY_MEDIUM = 2;
|
|
static PRIORITY_HIGH = 3;
|
|
static PRIORITY_URGENT = 4;
|
|
|
|
static priority_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"PRIORITY_LOW","label":"Low","badge":"bg-secondary"};
|
|
order.push(1);
|
|
data[2] = {"constant":"PRIORITY_MEDIUM","label":"Medium","badge":"bg-primary"};
|
|
order.push(2);
|
|
data[3] = {"constant":"PRIORITY_HIGH","label":"High","badge":"bg-warning"};
|
|
order.push(3);
|
|
data[4] = {"constant":"PRIORITY_URGENT","label":"Urgent","badge":"bg-danger"};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static priority_label_list() {
|
|
const values = {};
|
|
values[1] = 'Low';
|
|
values[2] = 'Medium';
|
|
values[3] = 'High';
|
|
values[4] = 'Urgent';
|
|
return values;
|
|
}
|
|
|
|
static priority_enum_select() {
|
|
const fullData = this.priority_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch taskable relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async taskable() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Task_Model/${this.id}/taskable`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch assigned_to relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async assigned_to() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Task_Model/${this.id}/assigned_to`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch created_by relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async created_by() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Task_Model/${this.id}/created_by`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Fetch subtasks relationship
|
|
* @returns {Promise} Related model instance(s) or false
|
|
*/
|
|
async subtasks() {
|
|
if (!this.id) {
|
|
shouldnt_happen('Cannot fetch relationship without id property');
|
|
}
|
|
|
|
const response = await $.ajax({
|
|
url: `/_fetch_rel/Task_Model/${this.id}/subtasks`,
|
|
method: 'POST',
|
|
dataType: 'json'
|
|
});
|
|
|
|
if (!response) return false;
|
|
|
|
// Convert response to model instance(s)
|
|
// Framework handles instantiation based on relationship type
|
|
return response;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-model-stubs/demo-product-model.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Demo_Product_Model
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Demo_Product_Model extends Rsx_Js_Model {
|
|
static get name() {
|
|
return 'Demo_Product_Model';
|
|
}
|
|
|
|
static STATUS_AVAILABLE = 1;
|
|
static STATUS_OUT_OF_STOCK = 2;
|
|
static STATUS_DISCONTINUED = 3;
|
|
|
|
static status_id_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"STATUS_AVAILABLE","label":"Available","order":1};
|
|
order.push(1);
|
|
data[2] = {"constant":"STATUS_OUT_OF_STOCK","label":"Out of Stock","order":2};
|
|
order.push(2);
|
|
data[3] = {"constant":"STATUS_DISCONTINUED","label":"Discontinued","order":3};
|
|
order.push(3);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static status_id_label_list() {
|
|
const values = {};
|
|
values[1] = 'Available';
|
|
values[2] = 'Out of Stock';
|
|
values[3] = 'Discontinued';
|
|
return values;
|
|
}
|
|
|
|
static status_id_enum_select() {
|
|
const fullData = this.status_id_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static CATEGORY_ELECTRONICS = 1;
|
|
static CATEGORY_CLOTHING = 2;
|
|
static CATEGORY_BOOKS = 3;
|
|
static CATEGORY_FOOD = 4;
|
|
|
|
static category_id_enum_val() {
|
|
const data = {};
|
|
const order = [];
|
|
data[1] = {"constant":"CATEGORY_ELECTRONICS","label":"Electronics","order":1};
|
|
order.push(1);
|
|
data[2] = {"constant":"CATEGORY_CLOTHING","label":"Clothing","order":2};
|
|
order.push(2);
|
|
data[3] = {"constant":"CATEGORY_BOOKS","label":"Books","order":3};
|
|
order.push(3);
|
|
data[4] = {"constant":"CATEGORY_FOOD","label":"Food & Beverage","order":4};
|
|
order.push(4);
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
static category_id_label_list() {
|
|
const values = {};
|
|
values[1] = 'Electronics';
|
|
values[2] = 'Clothing';
|
|
values[3] = 'Books';
|
|
values[4] = 'Food & Beverage';
|
|
return values;
|
|
}
|
|
|
|
static category_id_enum_select() {
|
|
const fullData = this.category_id_enum_val();
|
|
const data = {};
|
|
const order = [];
|
|
|
|
// Extract labels from full data, respecting selectable flag
|
|
for (const key in fullData) {
|
|
const item = fullData[key];
|
|
if (item.selectable !== false && item.label) {
|
|
data[key] = item.label;
|
|
order.push(parseInt(key));
|
|
}
|
|
}
|
|
|
|
// Return Proxy that maintains sort order for enumeration
|
|
return new Proxy(data, {
|
|
ownKeys() {
|
|
return order.map(String);
|
|
},
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
if (prop in target) {
|
|
return {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: target[prop]
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Clients_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Clients_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Clients_Controller {
|
|
/**
|
|
* Call Frontend_Clients_Controller::datagrid_fetch via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async datagrid_fetch(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Clients_Controller/datagrid_fetch', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Clients_Controller::save via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async save(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Clients_Controller/save', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Clients_Controller::delete via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async delete(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Clients_Controller/delete', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Clients_Controller::restore via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async restore(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Clients_Controller/restore', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Clients_Controller.datagrid_fetch.path = '/_ajax/Frontend_Clients_Controller/datagrid_fetch';
|
|
Frontend_Clients_Controller.save.path = '/_ajax/Frontend_Clients_Controller/save';
|
|
Frontend_Clients_Controller.delete.path = '/_ajax/Frontend_Clients_Controller/delete';
|
|
Frontend_Clients_Controller.restore.path = '/_ajax/Frontend_Clients_Controller/restore';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_Profile_Edit_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_Profile_Edit_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_Profile_Edit_Controller {
|
|
/**
|
|
* Call Frontend_Settings_Profile_Edit_Controller::save_profile via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async save_profile(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Profile_Edit_Controller/save_profile', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_Profile_Edit_Controller.save_profile.path = '/_ajax/Frontend_Settings_Profile_Edit_Controller/save_profile';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_User_Settings_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_User_Settings_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_User_Settings_Controller {
|
|
/**
|
|
* Call Frontend_Settings_User_Settings_Controller::update via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async update(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Settings_Controller/update', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_User_Settings_Controller.update.path = '/_ajax/Frontend_Settings_User_Settings_Controller/update';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_Password_Security_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_Password_Security_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_Password_Security_Controller {
|
|
/**
|
|
* Call Frontend_Settings_Password_Security_Controller::change_password via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async change_password(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Password_Security_Controller/change_password', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_Password_Security_Controller::revoke_session via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async revoke_session(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Password_Security_Controller/revoke_session', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_Password_Security_Controller.change_password.path = '/_ajax/Frontend_Settings_Password_Security_Controller/change_password';
|
|
Frontend_Settings_Password_Security_Controller.revoke_session.path = '/_ajax/Frontend_Settings_Password_Security_Controller/revoke_session';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_Api_Keys_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_Api_Keys_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_Api_Keys_Controller {
|
|
/**
|
|
* Call Frontend_Settings_Api_Keys_Controller::generate via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async generate(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Api_Keys_Controller/generate', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_Api_Keys_Controller::revoke via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async revoke(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Api_Keys_Controller/revoke', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_Api_Keys_Controller.generate.path = '/_ajax/Frontend_Settings_Api_Keys_Controller/generate';
|
|
Frontend_Settings_Api_Keys_Controller.revoke.path = '/_ajax/Frontend_Settings_Api_Keys_Controller/revoke';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_User_Management_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_User_Management_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_User_Management_Controller {
|
|
/**
|
|
* Call Frontend_Settings_User_Management_Controller::datagrid_fetch via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async datagrid_fetch(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Management_Controller/datagrid_fetch', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_User_Management_Controller::add_user via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async add_user(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Management_Controller/add_user', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_User_Management_Controller::get_user_for_edit via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async get_user_for_edit(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Management_Controller/get_user_for_edit', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_User_Management_Controller::save_user via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async save_user(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Management_Controller/save_user', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Settings_User_Management_Controller::send_invite via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async send_invite(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_User_Management_Controller/send_invite', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_User_Management_Controller.datagrid_fetch.path = '/_ajax/Frontend_Settings_User_Management_Controller/datagrid_fetch';
|
|
Frontend_Settings_User_Management_Controller.add_user.path = '/_ajax/Frontend_Settings_User_Management_Controller/add_user';
|
|
Frontend_Settings_User_Management_Controller.get_user_for_edit.path = '/_ajax/Frontend_Settings_User_Management_Controller/get_user_for_edit';
|
|
Frontend_Settings_User_Management_Controller.save_user.path = '/_ajax/Frontend_Settings_User_Management_Controller/save_user';
|
|
Frontend_Settings_User_Management_Controller.send_invite.path = '/_ajax/Frontend_Settings_User_Management_Controller/send_invite';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Settings_Site_Settings_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Settings_Site_Settings_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Settings_Site_Settings_Controller {
|
|
/**
|
|
* Call Frontend_Settings_Site_Settings_Controller::update via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async update(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Settings_Site_Settings_Controller/update', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Settings_Site_Settings_Controller.update.path = '/_ajax/Frontend_Settings_Site_Settings_Controller/update';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Contacts_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Contacts_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Contacts_Controller {
|
|
/**
|
|
* Call Frontend_Contacts_Controller::datagrid_fetch via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async datagrid_fetch(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Contacts_Controller/datagrid_fetch', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Contacts_Controller::get_clients via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async get_clients(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Contacts_Controller/get_clients', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Contacts_Controller::get_client via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async get_client(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Contacts_Controller/get_client', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Contacts_Controller::save via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async save(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Contacts_Controller/save', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Contacts_Controller.datagrid_fetch.path = '/_ajax/Frontend_Contacts_Controller/datagrid_fetch';
|
|
Frontend_Contacts_Controller.get_clients.path = '/_ajax/Frontend_Contacts_Controller/get_clients';
|
|
Frontend_Contacts_Controller.get_client.path = '/_ajax/Frontend_Contacts_Controller/get_client';
|
|
Frontend_Contacts_Controller.save.path = '/_ajax/Frontend_Contacts_Controller/save';
|
|
|
|
|
|
/* === storage/rsx-build/js-stubs/Frontend_Projects_Controller.js === */
|
|
/**
|
|
* Auto-generated JavaScript stub for Frontend_Projects_Controller
|
|
* DO NOT EDIT - This file is automatically regenerated
|
|
*/
|
|
|
|
class Frontend_Projects_Controller {
|
|
/**
|
|
* Call Frontend_Projects_Controller::datagrid_fetch via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async datagrid_fetch(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Projects_Controller/datagrid_fetch', params);
|
|
}
|
|
|
|
/**
|
|
* Call Frontend_Projects_Controller::save via Ajax.call()
|
|
* @param {Object} params - Parameters object to pass to the method
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async save(params = {}) {
|
|
return Ajax.call('/_ajax/Frontend_Projects_Controller/save', params);
|
|
}
|
|
|
|
}
|
|
|
|
// Path properties for type-safe routing
|
|
Frontend_Projects_Controller.datagrid_fetch.path = '/_ajax/Frontend_Projects_Controller/datagrid_fetch';
|
|
Frontend_Projects_Controller.save.path = '/_ajax/Frontend_Projects_Controller/save';
|
|
|
|
|
|
/* === 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/jqhtml_0624c3489faf8bba.js === */
|
|
/* Compiled from: rsx/app/frontend/clients/index/clients_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Clients_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Clients_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Clients_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Client List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "name"}, false]}); _output.push("Company Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "city"}, false]}); _output.push("Location"); _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("Website"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Clients_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #CL"); (() => { const result = String(row.id).padStart(3, '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("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { 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(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.city && row.state) { (() => { const result = row.city ; 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 = row.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(" "); } else if (row.city) { (() => { const result = row.city ; 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 (row.state) { (() => { const result = row.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(" "); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _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(" "); if (row.website) { _output.push({tag: ["a", {"href": (row.website), "target": "_blank", "class": "text-decoration-none"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-link-45deg"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; 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: ["a", {"class": "btn btn-outline-primary", "href": "/clients/view/" + (row.id), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "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("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, 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_Clients_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a0ed24b2f2a26a2c.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/add_user_modal_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Add_User_Modal_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Add_User_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({comp: ["Rsx_Form", {"data-controller": "Frontend_Settings_User_Management_Controller", "data-method": "add_user"}, function(Rsx_Form) { let _output = [];
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "email", "data-label": "Email Address", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {"data-type": "email", "data-placeholder": "user@example.com", "data-autofocus": true}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "row"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "first_name", "data-label": "First Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "last_name", "data-label": "Last Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "role_id", "data-label": "Role", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Select_Input", {"data-options": (JSON.stringify([ {value: 3, label: 'Member'}, {value: 2, label: 'Admin'}, {value: 1, label: 'Owner'}, {value: 4, label: 'Viewer'} ]))}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "phone", "data-label": "Phone Number"}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Phone_Text_Input", {"data-placeholder": "(555) 123-4567"}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
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_Add_User_Modal_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b1ddcd786055dd48.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/users_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Users_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Users_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Settings_User_Management_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("User List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "first_name"}, false]}); _output.push("Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "email"}, false]}); _output.push("Email"); _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("Phone"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "user_role_id"}, false]}); _output.push("Role"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": (Rsx.Route('Frontend_Settings_User_Management_Controller', 'view', row.id))}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #U"); (() => { const result = String(row.id).padStart(3, '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("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.first_name || row.last_name) { (() => { const result = row.first_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(" "); (() => { const result = row.last_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({tag: ["em", {"class": "text-muted"}, false]}); _output.push("No name set"); _output.push("</em>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { 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(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.invitation_status === 'accepted') { _output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push(" "); } else if (row.invitation_status === 'expired') { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Expired"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Invited"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _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(" "); if (row.user_role_id_label) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); (() => { const result = row.user_role_id_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("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; 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: ["a", {"class": "btn btn-outline-primary", "href": (Rsx.Route('Frontend_Settings_User_Management_Controller', 'view', row.id)), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "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("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, 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_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_999138a7ad9fb892.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/edit_user_modal_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Edit_User_Modal_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Edit_User_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({comp: ["Rsx_Form", {"data-controller": "Frontend_Settings_User_Management_Controller", "data-method": "save_user", "data-data": (JSON.stringify(this.args.data))}, function(Rsx_Form) { let _output = [];
|
|
_output.push(" ");
|
|
_output.push({comp: ["Form_Hidden_Field", {"data-name": "id"}]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "email", "data-label": "Email Address", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {"data-type": "email", "data-placeholder": "user@example.com", "data-autofocus": true}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "row"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "first_name", "data-label": "First Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "last_name", "data-label": "Last Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "role_id", "data-label": "Role", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Select_Input", {"data-options": (JSON.stringify([ {value: 3, label: 'Member'}, {value: 2, label: 'Admin'}, {value: 1, label: 'Owner'}, {value: 4, label: 'Viewer'} ]))}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "phone", "data-label": "Phone Number"}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Phone_Text_Input", {"data-placeholder": "(555) 123-4567"}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
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_Edit_User_Modal_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2db45a178bfdaa95.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/index/contacts_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Contacts_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Contact List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "first_name"}, false]}); _output.push("Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "email"}, 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", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Contacts_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #CT"); (() => { const result = String(row.id).padStart(3, '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("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.first_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(" "); (() => { const result = row.last_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("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { 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(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.phone_work || '-' ; 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(" "); if (row.client_id) { _output.push({comp: ["Client_Label", {"data-client_id": row.client_id}]}); _output.push(" "); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push("-"); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; 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: ["a", {"class": "btn btn-outline-primary", "href": "/contacts/view/" + (row.id), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "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("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, 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_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e2d87387fe13db9a.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/_data_table_qq/data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Data_Table',
|
|
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]}); (() => { 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: ["div", {"class": "d-flex gap-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "search_container" + ":" + this._cid, "data-id": "search_container"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "filter_container" + ":" + this._cid, "data-id": "filter_container"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "column_toggle_container" + ":" + this._cid, "data-id": "column_toggle_container"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({comp: ["Bulk_Action_Bar", {"id": "bulk_bar" + ":" + this._cid, "data-id": "bulk_bar", "style": "display: none;"}, function(Bulk_Action_Bar) { let _output = [];
|
|
_output.push(" "); _output.push({comp: ["Button_Danger", {"id": "bulk_delete" + ":" + this._cid, "data-id": "bulk_delete"}, function(Button_Danger) {
|
|
const _output = [];
|
|
_output.push("Delete Selected");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "bulk_export" + ":" + this._cid, "data-id": "bulk_export"}, function(Button_Secondary) {
|
|
const _output = [];
|
|
_output.push("Export Selected");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_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({comp: ["Table", {"id": "table" + ":" + this._cid, "data-id": "table"}, function(Table) { let _output = [];
|
|
_output.push(" "); _output.push({tag: ["thead", {}, false]}); _output.push(" "); _output.push({tag: ["tr", {"id": "header_row" + ":" + this._cid, "data-id": "header_row"}, false]}); _output.push(" "); if (this.args.bulk_actions) { _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({comp: ["Bulk_Selection", {"id": "bulk_selection" + ":" + this._cid, "data-id": "bulk_selection"}]}); _output.push(" "); _output.push("</th>"); } _output.push("<!-- Column headers dynamically generated -->"); _output.push(" "); _output.push("</tr>"); _output.push("</thead>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["tbody", {"id": "tbody" + ":" + this._cid, "data-id": "tbody"}, false]}); _output.push(" "); if (Object.keys(this.data).length === 0) { _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({tag: ["div", {"class": "mt-2 text-muted"}, false]}); _output.push("Loading data..."); _output.push("</div>"); _output.push(" "); _output.push("</td>"); _output.push("</tr>"); } else if (this.data.rows && this.data.rows.length === 0) { _output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "100"}, false]}); _output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "inbox", "data-title": "No data available", "data-message": "There are no records to display"}]}); _output.push(" "); _output.push("</td>"); _output.push("</tr>"); } else { for (let row of this.data.rows || []) { _output.push({tag: ["tr", {"id": row.id + ":" + this._cid, "data-id": row.id}, false]}); _output.push(" "); if (this.args.bulk_actions) { _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input row-checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); } for (let col of this.data.columns || []) { _output.push({tag: ["td", {}, false]}); (() => { const result = row[col.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("</td>"); _output.push(" "); } if (this.args.row_actions) { _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({comp: ["Row_Action_Menu", {"id": "row_actions_" + row.id + ":" + this._cid, "data-id": "row_actions_" + row.id}, function(Row_Action_Menu) {
|
|
const _output = [];
|
|
_output.push(" "); (() => { const result = this.args.row_actions(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("</td>"); } _output.push("</tr>"); } } _output.push("</tbody>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"class": "card-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Table_Pagination", {"id": "pagination" + ":" + this._cid, "data-id": "pagination", "data-start": this.data.start, "data-end": this.data.end, "data-total": this.data.total, "data-current_page": this.data.current_page, "data-total_pages": this.data.total_pages}]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_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_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_af2c362f250eb18b.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/_new_elements/Card_Header_Right.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Header_Right = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_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;
|
|
|
|
(() => { 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_Header_Right);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ae868a09468038cb.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/edit/form/client_selector_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Selector_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Selector_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_Client_Selector_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_54d7ab6b9e7b33ca.js === */
|
|
/* Compiled from: rsx/app/frontend/projects/index/projects_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Projects_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Projects_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Projects_Controller.datagrid_fetch, "sort": "created_at", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Project List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "name"}, false]}); _output.push("Project Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "client_id"}, false]}); _output.push("Client"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "status"}, false]}); _output.push("Status"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "start_date"}, false]}); _output.push("Start Date"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "due_date"}, false]}); _output.push("Due Date"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Projects_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #PR"); (() => { const result = String(row.id).padStart(3, '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("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { 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(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.client) { (() => { const result = row.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(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.status === 1) { _output.push({tag: ["span", {"class": "badge bg-info"}, false]}); _output.push("Planning"); _output.push("</span>"); _output.push(" "); } else if (row.status === 2) { _output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push(" "); } else if (row.status === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("On Hold"); _output.push("</span>"); _output.push(" "); } else if (row.status === 4) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Completed"); _output.push("</span>"); _output.push(" "); } else if (row.status === 5) { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Cancelled"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.start_date ? new Date(row.start_date).toLocaleDateString() : '-' ; 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.due_date ? new Date(row.due_date).toLocaleDateString() : '-' ; 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 = new Date(row.created_at).toLocaleDateString() ; 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: ["a", {"class": "btn btn-outline-primary", "href": (Rsx.Route('Frontend_Projects_Controller', 'view', row.id)), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "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("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, 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_Projects_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_Bundle_74e6763d.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],
|
|
[Jqhtml_Component, "Jqhtml_Component", _Base_Jqhtml_Component],
|
|
[Jqhtml_Integration, "Jqhtml_Integration", null],
|
|
[DataGrid_Abstract, "DataGrid_Abstract", Jqhtml_Component],
|
|
[Activity_Feed, "Activity_Feed", Jqhtml_Component],
|
|
[Actor_Reference, "Actor_Reference", Jqhtml_Component],
|
|
[Advanced_Search_Panel, "Advanced_Search_Panel", Jqhtml_Component],
|
|
[Alert_Banner, "Alert_Banner", Jqhtml_Component],
|
|
[Avatar, "Avatar", Jqhtml_Component],
|
|
[Blockquote, "Blockquote", Jqhtml_Component],
|
|
[Breadcrumbs, "Breadcrumbs", Jqhtml_Component],
|
|
[Bulk_Action_Bar, "Bulk_Action_Bar", Jqhtml_Component],
|
|
[Bulk_Selection, "Bulk_Selection", Jqhtml_Component],
|
|
[Button_Group, "Button_Group", Jqhtml_Component],
|
|
[Button_Primary, "Button_Primary", Jqhtml_Component],
|
|
[Button_Secondary, "Button_Secondary", Jqhtml_Component],
|
|
[Button, "Button", Jqhtml_Component],
|
|
[Calendar_Event, "Calendar_Event", Jqhtml_Component],
|
|
[Calendar_Grid, "Calendar_Grid", Jqhtml_Component],
|
|
[Card, "Card", Jqhtml_Component],
|
|
[Chart_Component, "Chart_Component", Jqhtml_Component],
|
|
[Checkbox, "Checkbox", Jqhtml_Component],
|
|
[Code_Block, "Code_Block", Jqhtml_Component],
|
|
[Column_Visibility_Toggle, "Column_Visibility_Toggle", Jqhtml_Component],
|
|
[Comment_Thread, "Comment_Thread", Jqhtml_Component],
|
|
[Date_Picker, "Date_Picker", Jqhtml_Component],
|
|
[Dropdown_Menu, "Dropdown_Menu", Jqhtml_Component],
|
|
[Empty_State, "Empty_State", Jqhtml_Component],
|
|
[Export_Button, "Export_Button", Jqhtml_Component],
|
|
[File_Upload, "File_Upload", Jqhtml_Component],
|
|
[Filter_Bar, "Filter_Bar", Jqhtml_Component],
|
|
[Form_Actions_Component, "Form_Actions_Component", Jqhtml_Component],
|
|
[Form_Field_Group, "Form_Field_Group", Jqhtml_Component],
|
|
[Form_Group_Component, "Form_Group_Component", Jqhtml_Component],
|
|
[Form_Row_Component, "Form_Row_Component", Jqhtml_Component],
|
|
[Form_Validation_Message, "Form_Validation_Message", Jqhtml_Component],
|
|
[Gantt_Chart, "Gantt_Chart", Jqhtml_Component],
|
|
[Icon_Button, "Icon_Button", Jqhtml_Component],
|
|
[Icon_With_Label, "Icon_With_Label", Jqhtml_Component],
|
|
[Icon_With_Text, "Icon_With_Text", Jqhtml_Component],
|
|
[Icon, "Icon", Jqhtml_Component],
|
|
[Info_Box, "Info_Box", Jqhtml_Component],
|
|
[Inline_Edit_Field, "Inline_Edit_Field", Jqhtml_Component],
|
|
[Input_With_Icon, "Input_With_Icon", Jqhtml_Component],
|
|
[Input_With_Validation, "Input_With_Validation", Jqhtml_Component],
|
|
[Input, "Input", Jqhtml_Component],
|
|
[Kanban_Board, "Kanban_Board", Jqhtml_Component],
|
|
[Link, "Link", Jqhtml_Component],
|
|
[List, "List", Jqhtml_Component],
|
|
[Loading_Skeleton, "Loading_Skeleton", Jqhtml_Component],
|
|
[Metric_Card, "Metric_Card", Jqhtml_Component],
|
|
[Mobile_Header, "Mobile_Header", Jqhtml_Component],
|
|
[Modal_Dialog, "Modal_Dialog", Jqhtml_Component],
|
|
[Multi_Select, "Multi_Select", Jqhtml_Component],
|
|
[Notification_Badge, "Notification_Badge", Jqhtml_Component],
|
|
[Notification_Dropdown, "Notification_Dropdown", Jqhtml_Component],
|
|
[Overdue_Indicator, "Overdue_Indicator", Jqhtml_Component],
|
|
[Page_Header, "Page_Header", Jqhtml_Component],
|
|
[Page_Section, "Page_Section", Jqhtml_Component],
|
|
[Page, "Page", Jqhtml_Component],
|
|
[Popover, "Popover", Jqhtml_Component],
|
|
[Progress_Bar, "Progress_Bar", Jqhtml_Component],
|
|
[Radio_Button, "Radio_Button", Jqhtml_Component],
|
|
[Rich_Text_Editor, "Rich_Text_Editor", Jqhtml_Component],
|
|
[Row_Action_Menu, "Row_Action_Menu", Jqhtml_Component],
|
|
[Sample_Datagrid_Component, "Sample_Datagrid_Component", Jqhtml_Component],
|
|
[Search_Bar, "Search_Bar", Jqhtml_Component],
|
|
[Searchable_Select, "Searchable_Select", Jqhtml_Component],
|
|
[Select_Dropdown, "Select_Dropdown", Jqhtml_Component],
|
|
[Sidebar_Nav, "Sidebar_Nav", Jqhtml_Component],
|
|
[Sortable_Column_Header, "Sortable_Column_Header", Jqhtml_Component],
|
|
[Spinner, "Spinner", Jqhtml_Component],
|
|
[Stat_Card, "Stat_Card", Jqhtml_Component],
|
|
[Status_Badge, "Status_Badge", Jqhtml_Component],
|
|
[Tab_Content, "Tab_Content", Jqhtml_Component],
|
|
[Table_Pagination, "Table_Pagination", Jqhtml_Component],
|
|
[Table, "Table", Jqhtml_Component],
|
|
[Tabs, "Tabs", Jqhtml_Component],
|
|
[Tag_Group, "Tag_Group", Jqhtml_Component],
|
|
[Tag, "Tag", Jqhtml_Component],
|
|
[Text_Display, "Text_Display", Jqhtml_Component],
|
|
[Textarea, "Textarea", Jqhtml_Component],
|
|
[Three_Column_Layout, "Three_Column_Layout", Jqhtml_Component],
|
|
[Time_Picker, "Time_Picker", Jqhtml_Component],
|
|
[Timeline, "Timeline", Jqhtml_Component],
|
|
[Timestamp_Display, "Timestamp_Display", Jqhtml_Component],
|
|
[Tooltip, "Tooltip", Jqhtml_Component],
|
|
[Top_Nav, "Top_Nav", Jqhtml_Component],
|
|
[Trend_Indicator, "Trend_Indicator", Jqhtml_Component],
|
|
[Two_Column_Layout, "Two_Column_Layout", Jqhtml_Component],
|
|
[User_Avatar_Dropdown, "User_Avatar_Dropdown", Jqhtml_Component],
|
|
[Modal_Abstract, "Modal_Abstract", null],
|
|
[Rsx_Modal, "Rsx_Modal", Jqhtml_Component],
|
|
[Modal, "Modal", null],
|
|
[Breadcrumb_Item, "Breadcrumb_Item", Jqhtml_Component],
|
|
[Client_Label_Link, "Client_Label_Link", Jqhtml_Component],
|
|
[Client_Label, "Client_Label", Jqhtml_Component],
|
|
[Form_Input_Abstract, "Form_Input_Abstract", Jqhtml_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", Jqhtml_Component],
|
|
[Rsx_Tab, "Rsx_Tab", Jqhtml_Component],
|
|
[Rsx_Form, "Rsx_Form", Jqhtml_Component],
|
|
[Pin_Verification_Form, "Pin_Verification_Form", Rsx_Form],
|
|
[Form_Field_Abstract, "Form_Field_Abstract", Jqhtml_Component],
|
|
[Form_Field, "Form_Field", Form_Field_Abstract],
|
|
[Form_Hidden_Field, "Form_Hidden_Field", Form_Field_Abstract],
|
|
[Frontend_Dashboard, "Frontend_Dashboard", null],
|
|
[Clients_DataGrid, "Clients_DataGrid", DataGrid_Abstract],
|
|
[Frontend_Clients_Edit, "Frontend_Clients_Edit", null],
|
|
[Frontend_Clients_View, "Frontend_Clients_View", null],
|
|
[Frontend_Clients, "Frontend_Clients", null],
|
|
[Frontend_Settings_Team, "Frontend_Settings_Team", null],
|
|
[Frontend_Settings_Notifications, "Frontend_Settings_Notifications", null],
|
|
[Frontend_Settings_Billing, "Frontend_Settings_Billing", null],
|
|
[Frontend_Settings_Import, "Frontend_Settings_Import", null],
|
|
[Frontend_Settings_Api, "Frontend_Settings_Api", null],
|
|
[Frontend_Settings_Templates, "Frontend_Settings_Templates", null],
|
|
[Frontend_Settings_Audit, "Frontend_Settings_Audit", null],
|
|
[Frontend_Settings_Profile_Display, "Frontend_Settings_Profile_Display", null],
|
|
[Frontend_Settings_User_Settings, "Frontend_Settings_User_Settings", null],
|
|
[Frontend_Settings_Password_Security, "Frontend_Settings_Password_Security", null],
|
|
[Frontend_Settings_Api_Keys, "Frontend_Settings_Api_Keys", null],
|
|
[Users_DataGrid, "Users_DataGrid", DataGrid_Abstract],
|
|
[Add_User_Form, "Add_User_Form", Jqhtml_Component],
|
|
[Add_User_Modal, "Add_User_Modal", Modal_Abstract],
|
|
[Send_User_Invite_Modal, "Send_User_Invite_Modal", Modal_Abstract],
|
|
[Frontend_Settings_User_Management, "Frontend_Settings_User_Management", null],
|
|
[Edit_User_Modal, "Edit_User_Modal", Modal_Abstract],
|
|
[Frontend_Settings_User_Management_View, "Frontend_Settings_User_Management_View", null],
|
|
[Frontend_Settings_Site_Settings, "Frontend_Settings_Site_Settings", null],
|
|
[Frontend_Settings, "Frontend_Settings", null],
|
|
[Contacts_DataGrid, "Contacts_DataGrid", DataGrid_Abstract],
|
|
[Data_Table, "Data_Table", Jqhtml_Component],
|
|
[Client_Selector_Input, "Client_Selector_Input", Ajax_Select_Input],
|
|
[Frontend_Contacts_Edit, "Frontend_Contacts_Edit", null],
|
|
[Frontend_Contacts_View, "Frontend_Contacts_View", null],
|
|
[Frontend_Contacts, "Frontend_Contacts", null],
|
|
[Projects_DataGrid, "Projects_DataGrid", DataGrid_Abstract],
|
|
[Frontend_Projects_Edit, "Frontend_Projects_Edit", null],
|
|
[Frontend_Projects_List, "Frontend_Projects_List", null],
|
|
[Frontend_Projects_View, "Frontend_Projects_View", null],
|
|
[Frontend_Projects_Add, "Frontend_Projects_Add", null],
|
|
[Frontend_Projects, "Frontend_Projects", null],
|
|
[Frontend_Tasks, "Frontend_Tasks", null],
|
|
[Frontend_Tasks_View, "Frontend_Tasks_View", null],
|
|
[Frontend_Tasks_Add, "Frontend_Tasks_Add", null],
|
|
[Frontend_Calendar, "Frontend_Calendar", null],
|
|
[Frontend_Calendar_Event, "Frontend_Calendar_Event", null],
|
|
[Frontend_Invoices, "Frontend_Invoices", null],
|
|
[Frontend_Invoices_View, "Frontend_Invoices_View", null],
|
|
[Frontend_Invoices_Add, "Frontend_Invoices_Add", null],
|
|
[Frontend_Reports, "Frontend_Reports", null],
|
|
[Frontend_Reports_Revenue, "Frontend_Reports_Revenue", null],
|
|
[Frontend_Reports_Clients, "Frontend_Reports_Clients", null],
|
|
[Frontend_Reports_Projects, "Frontend_Reports_Projects", null],
|
|
[Frontend_Reports_Time, "Frontend_Reports_Time", null],
|
|
[Frontend_Account, "Frontend_Account", null],
|
|
[Rsx_Reference_Data_Controller, "Rsx_Reference_Data_Controller", null],
|
|
[Client_Department_Model, "Client_Department_Model", null],
|
|
[Client_Model, "Client_Model", null],
|
|
[Contact_Model, "Contact_Model", null],
|
|
[Project_Model, "Project_Model", null],
|
|
[Task_Model, "Task_Model", null],
|
|
[Demo_Product_Model, "Demo_Product_Model", null],
|
|
[Frontend_Clients_Controller, "Frontend_Clients_Controller", null],
|
|
[Frontend_Settings_Profile_Edit_Controller, "Frontend_Settings_Profile_Edit_Controller", null],
|
|
[Frontend_Settings_User_Settings_Controller, "Frontend_Settings_User_Settings_Controller", null],
|
|
[Frontend_Settings_Password_Security_Controller, "Frontend_Settings_Password_Security_Controller", null],
|
|
[Frontend_Settings_Api_Keys_Controller, "Frontend_Settings_Api_Keys_Controller", null],
|
|
[Frontend_Settings_User_Management_Controller, "Frontend_Settings_User_Management_Controller", null],
|
|
[Frontend_Settings_Site_Settings_Controller, "Frontend_Settings_Site_Settings_Controller", null],
|
|
[Frontend_Contacts_Controller, "Frontend_Contacts_Controller", null],
|
|
[Frontend_Projects_Controller, "Frontend_Projects_Controller", null]
|
|
]);
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_Bundle_bedffa98.js === */
|
|
// RSX Route Definitions - Generated by BundleCompiler
|
|
// Provides route patterns for type-safe URL generation
|
|
Rsx._define_routes({
|
|
"Frontend_Dashboard_Controller": {
|
|
"index": "/dashboard"
|
|
},
|
|
"Frontend_Clients_Controller": {
|
|
"index": "/clients",
|
|
"view": "/clients/view/:id",
|
|
"add": "/clients/add",
|
|
"edit": "/clients/edit/:id"
|
|
},
|
|
"Frontend_Settings_Team_Controller": {
|
|
"index": "/frontend/settings/team"
|
|
},
|
|
"Frontend_Settings_Notifications_Controller": {
|
|
"index": "/frontend/settings/notifications"
|
|
},
|
|
"Frontend_Settings_Billing_Controller": {
|
|
"index": "/frontend/settings/billing"
|
|
},
|
|
"Frontend_Settings_Import_Controller": {
|
|
"index": "/frontend/settings/import"
|
|
},
|
|
"Frontend_Settings_Api_Controller": {
|
|
"index": "/frontend/settings/api"
|
|
},
|
|
"Frontend_Settings_Templates_Controller": {
|
|
"index": "/frontend/settings/templates"
|
|
},
|
|
"Frontend_Settings_Audit_Controller": {
|
|
"index": "/frontend/settings/audit"
|
|
},
|
|
"Frontend_Settings_Account_Controller": {
|
|
"index": "/frontend/settings/account"
|
|
},
|
|
"Frontend_Settings_General_Controller": {
|
|
"index": "/frontend/settings/general"
|
|
},
|
|
"Frontend_Settings_Profile_Controller": {
|
|
"index": "/frontend/settings/profile"
|
|
},
|
|
"Frontend_Settings_Profile_Display_Controller": {
|
|
"index": "/frontend/settings/profile_display"
|
|
},
|
|
"Frontend_Settings_Profile_Edit_Controller": {
|
|
"index": "/frontend/settings/profile_edit"
|
|
},
|
|
"Frontend_Settings_User_Settings_Controller": {
|
|
"index": "/frontend/settings/user_settings"
|
|
},
|
|
"Frontend_Settings_Password_Security_Controller": {
|
|
"index": "/frontend/settings/password_security"
|
|
},
|
|
"Frontend_Settings_Api_Keys_Controller": {
|
|
"index": "/frontend/settings/api_keys"
|
|
},
|
|
"Frontend_Settings_User_Management_Controller": {
|
|
"index": "/frontend/settings/user_management",
|
|
"view": "/frontend/settings/user_management/:id"
|
|
},
|
|
"Frontend_Settings_Site_Settings_Controller": {
|
|
"index": "/frontend/settings/site_settings"
|
|
},
|
|
"Frontend_Contacts_Controller": {
|
|
"index": "/contacts",
|
|
"view": "/contacts/view/:id",
|
|
"add": "/contacts/add",
|
|
"edit": "/contacts/edit/:id"
|
|
},
|
|
"Frontend_Projects_Controller": {
|
|
"index": "/projects",
|
|
"view": "/projects/view/:id",
|
|
"add": "/projects/add",
|
|
"edit": "/projects/edit/:id"
|
|
},
|
|
"Frontend_Tasks_Controller": {
|
|
"index": "/tasks"
|
|
},
|
|
"Frontend_Tasks_View_Controller": {
|
|
"index": "/tasks/view"
|
|
},
|
|
"Frontend_Tasks_Add_Controller": {
|
|
"index": "/tasks/add"
|
|
},
|
|
"Frontend_Calendar_Controller": {
|
|
"index": "/calendar"
|
|
},
|
|
"Frontend_Calendar_Event_Controller": {
|
|
"index": "/calendar/event"
|
|
},
|
|
"Frontend_Invoices_Controller": {
|
|
"index": "/invoices"
|
|
},
|
|
"Frontend_Invoices_View_Controller": {
|
|
"index": "/invoices/view"
|
|
},
|
|
"Frontend_Invoices_Add_Controller": {
|
|
"index": "/invoices/add"
|
|
},
|
|
"Frontend_Reports_Clients_Controller": {
|
|
"index": "/reports/clients"
|
|
},
|
|
"Frontend_Reports_Controller": {
|
|
"index": "/reports"
|
|
},
|
|
"Frontend_Reports_Projects_Controller": {
|
|
"index": "/reports/projects"
|
|
},
|
|
"Frontend_Reports_Revenue_Controller": {
|
|
"index": "/reports/revenue"
|
|
},
|
|
"Frontend_Reports_Time_Controller": {
|
|
"index": "/reports/time"
|
|
},
|
|
"Frontend_Account_Controller": {
|
|
"index": "/frontend/account"
|
|
}
|
|
});
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfY29uZmlnX0Zyb250ZW5kX0J1bmRsZS5qcyIsInN0b3JhZ2UvcnN4LXRtcC9ucG1faW1wb3J0X2RlY2xhcmF0aW9uc185NWE2ZjYwMmM5ODAzNzYxMWI2NDBiMGI1MzQyODMwYi5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9kZWNvcmF0b3IuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvYnJvd3Nlci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9kYXRldGltZS5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9lcnJvci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9oYXNoLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL011dGV4LmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL2FzeW5jLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL2Z1bmN0aW9ucy5qcyIsInJzeC90aGVtZS9xdWlsbC9xdWlsbF9jZG4uanMiLCJyc3gvYXBwL2Zyb250ZW5kL2NsaWVudHMvZWRpdC9zYXZlX2NsaWVudC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9zYXZlX2NvbnRhY3QuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvTWFuaWZlc3QuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0JlaGF2aW9ycy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfQ2FjaGUuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0luaXQuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0pzX01vZGVsLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9WaWV3X1RyYW5zaXRpb25zLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JlYWRXcml0ZUxvY2suanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvRm9ybV9VdGlscy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9EZWJ1Z2dlci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfSnFfSGVscGVycy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3guanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvQWpheC5qcyIsImFwcC9SU3BhZGUvSW50ZWdyYXRpb25zL0pxaHRtbC9KcWh0bWxfQ29tcG9uZW50LmpzIiwiYXBwL1JTcGFkZS9JbnRlZ3JhdGlvbnMvSnFodG1sL0pxaHRtbF9JbnRlZ3JhdGlvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2RhdGFncmlkL2RhdGFncmlkX2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQWN0aXZpdHlfRmVlZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FjdG9yX1JlZmVyZW5jZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FkdmFuY2VkX1NlYXJjaF9QYW5lbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FsZXJ0X0Jhbm5lci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0F2YXRhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Jsb2NrcXVvdGUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9CcmVhZGNydW1icy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0J1bGtfQWN0aW9uX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0J1bGtfU2VsZWN0aW9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uX2dyb3VwLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uX3ByaW1hcnkuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9idXR0b25fc2Vjb25kYXJ5LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ2FsZW5kYXJfRXZlbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9DYWxlbmRhcl9HcmlkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NoYXJ0X0NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NoZWNrYm94LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ29kZV9CbG9jay5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NvbW1lbnRfVGhyZWFkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRGF0ZV9QaWNrZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ecm9wZG93bl9NZW51LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRW1wdHlfU3RhdGUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9FeHBvcnRfQnV0dG9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRmlsZV9VcGxvYWQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9GaWx0ZXJfQmFyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvZm9ybV9hY3Rpb25zX2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Zvcm1fRmllbGRfR3JvdXAuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9mb3JtX2dyb3VwX2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2Zvcm1fcm93X2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Zvcm1fVmFsaWRhdGlvbl9NZXNzYWdlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvR2FudHRfQ2hhcnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9pY29uX2J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0ljb25fV2l0aF9MYWJlbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0ljb25fV2l0aF9UZXh0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvaWNvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0luZm9fQm94LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvSW5saW5lX0VkaXRfRmllbGQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dF9XaXRoX0ljb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dF9XaXRoX1ZhbGlkYXRpb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0thbmJhbl9Cb2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2xpbmsuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9MaXN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvTG9hZGluZ19Ta2VsZXRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL01ldHJpY19DYXJkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvTW9iaWxlX0hlYWRlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL01vZGFsX0RpYWxvZy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL011bHRpX1NlbGVjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL05vdGlmaWNhdGlvbl9CYWRnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL05vdGlmaWNhdGlvbl9Ecm9wZG93bi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL092ZXJkdWVfSW5kaWNhdG9yLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvUGFnZV9IZWFkZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9wYWdlX3NlY3Rpb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9wYWdlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvUG9wb3Zlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1Byb2dyZXNzX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1JhZGlvX0J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1JpY2hfVGV4dF9FZGl0b3IuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Sb3dfQWN0aW9uX01lbnUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9TYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2VhcmNoX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NlYXJjaGFibGVfU2VsZWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2VsZWN0X0Ryb3Bkb3duLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2lkZWJhcl9OYXYuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Tb3J0YWJsZV9Db2x1bW5fSGVhZGVyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU3Bpbm5lci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1N0YXRfQ2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1N0YXR1c19CYWRnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYl9Db250ZW50LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGFibGVfUGFnaW5hdGlvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYmxlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGFicy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhZ19Hcm91cC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhZy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL3RleHRfZGlzcGxheS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RleHRhcmVhLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGhyZWVfQ29sdW1uX0xheW91dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RpbWVfUGlja2VyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGltZWxpbmUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UaW1lc3RhbXBfRGlzcGxheS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1Rvb2x0aXAuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ub3BfTmF2LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVHJlbmRfSW5kaWNhdG9yLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVHdvX0NvbHVtbl9MYXlvdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Vc2VyX0F2YXRhcl9Ecm9wZG93bi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL21vZGFsL21vZGFsX2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvbW9kYWwvcnN4X21vZGFsLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvbW9kYWwvTW9kYWwuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9wYWdlX2VsZW1lbnRzL2JyZWFkY3J1bWJfaXRlbS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL3BhZ2VfZWxlbWVudHMvY2xpZW50X2xhYmVsX2xpbmsuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9wYWdlX2VsZW1lbnRzL2NsaWVudF9sYWJlbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9mb3JtX2lucHV0X2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL3RleHRfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY2hlY2tib3hfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvd3lzaXd5Z19pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvYWpheF9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY3VycmVuY3lfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvcGhvbmVfdGV4dF9pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9zdGF0ZV9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY291bnRyeV9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvcHJvZmlsZV9waG90b19pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF90YWJzLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvcnN4X3RhYi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF9mb3JtLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvcGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvZm9ybV9maWVsZF9hYnN0cmFjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL2Zvcm1fZmllbGQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9mb3JtX2hpZGRlbl9maWVsZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvZGFzaGJvYXJkL2Zyb250ZW5kX2Rhc2hib2FyZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY2xpZW50cy9pbmRleC9jbGllbnRzX2RhdGFncmlkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL2VkaXQvZnJvbnRlbmRfY2xpZW50c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL3ZpZXcvZnJvbnRlbmRfY2xpZW50c192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL2Zyb250ZW5kX2NsaWVudHMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3RlYW0vZnJvbnRlbmRfc2V0dGluZ3NfdGVhbS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3Mvbm90aWZpY2F0aW9ucy9mcm9udGVuZF9zZXR0aW5nc19ub3RpZmljYXRpb25zLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9iaWxsaW5nL2Zyb250ZW5kX3NldHRpbmdzX2JpbGxpbmcuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2ltcG9ydC9mcm9udGVuZF9zZXR0aW5nc19pbXBvcnQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2FwaS9mcm9udGVuZF9zZXR0aW5nc19hcGkuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3RlbXBsYXRlcy9mcm9udGVuZF9zZXR0aW5nc190ZW1wbGF0ZXMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2F1ZGl0L2Zyb250ZW5kX3NldHRpbmdzX2F1ZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9wcm9maWxlX2Rpc3BsYXkvZnJvbnRlbmRfc2V0dGluZ3NfcHJvZmlsZV9kaXNwbGF5LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfc2V0dGluZ3MuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3Bhc3N3b3JkX3NlY3VyaXR5L2Zyb250ZW5kX3NldHRpbmdzX3Bhc3N3b3JkX3NlY3VyaXR5LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9hcGlfa2V5cy9mcm9udGVuZF9zZXR0aW5nc19hcGlfa2V5cy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L3VzZXJzX2RhdGFncmlkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvYWRkX3VzZXJfZm9ybS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2FkZF91c2VyX21vZGFsLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvc2VuZF91c2VyX2ludml0ZV9tb2RhbC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfbWFuYWdlbWVudC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2VkaXRfdXNlcl9tb2RhbC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfbWFuYWdlbWVudF92aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9zaXRlX3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzX3NpdGVfc2V0dGluZ3MuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jb250YWN0cy9pbmRleC9jb250YWN0c19kYXRhZ3JpZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvX2RhdGFfdGFibGVfcXEvRGF0YV9UYWJsZS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9mb3JtL2NsaWVudF9zZWxlY3Rvcl9pbnB1dC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9mcm9udGVuZF9jb250YWN0c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jb250YWN0cy92aWV3L2Zyb250ZW5kX2NvbnRhY3RzX3ZpZXcuanMiLCJyc3gvYXBwL2Zyb250ZW5kL2NvbnRhY3RzL2Zyb250ZW5kX2NvbnRhY3RzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9pbmRleC9wcm9qZWN0c19kYXRhZ3JpZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvcHJvamVjdHMvZWRpdC9mcm9udGVuZF9wcm9qZWN0c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c19saXN0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c19hZGQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3Byb2plY3RzL2Zyb250ZW5kX3Byb2plY3RzLmpzIiwicnN4L2FwcC9mcm9udGVuZC90YXNrcy9mcm9udGVuZF90YXNrcy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvdGFza3MvZnJvbnRlbmRfdGFza3Nfdmlldy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvdGFza3MvZnJvbnRlbmRfdGFza3NfYWRkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jYWxlbmRhci9mcm9udGVuZF9jYWxlbmRhci5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY2FsZW5kYXIvZnJvbnRlbmRfY2FsZW5kYXJfZXZlbnQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL2ludm9pY2VzL2Zyb250ZW5kX2ludm9pY2VzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9pbnZvaWNlcy9mcm9udGVuZF9pbnZvaWNlc192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9pbnZvaWNlcy9mcm9udGVuZF9pbnZvaWNlc19hZGQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0cy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvcmVwb3J0cy9mcm9udGVuZF9yZXBvcnRzX3JldmVudWUuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0c19jbGllbnRzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9yZXBvcnRzL2Zyb250ZW5kX3JlcG9ydHNfcHJvamVjdHMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0c190aW1lLmpzIiwicnN4L2FwcC9mcm9udGVuZC9hY2NvdW50L2Zyb250ZW5kX2FjY291bnQuanMiLCJzdG9yYWdlL3JzeC1idWlsZC9qcy1zdHVicy9Sc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci5qcyIsInN0b3JhZ2UvcnN4LWJ1aWxkL2pzLW1vZGVsLXN0dWJzL2NsaWVudC1kZXBhcnRtZW50LW1vZGVsLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtbW9kZWwtc3R1YnMvY2xpZW50LW1vZGVsLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtbW9kZWwtc3R1YnMvY29udGFjdC1tb2RlbC5qcyIsInN0b3JhZ2UvcnN4LWJ1aWxkL2pzLW1vZGVsLXN0dWJzL3Byb2plY3QtbW9kZWwuanMiLCJzdG9yYWdlL3JzeC1idWlsZC9qcy1tb2RlbC1zdHVicy90YXNrLW1vZGVsLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtbW9kZWwtc3R1YnMvZGVtby1wcm9kdWN0LW1vZGVsLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtc3R1YnMvRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtc3R1YnMvRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9FZGl0X0NvbnRyb2xsZXIuanMiLCJzdG9yYWdlL3JzeC1idWlsZC9qcy1zdHVicy9Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX1NldHRpbmdzX0NvbnRyb2xsZXIuanMiLCJzdG9yYWdlL3JzeC1idWlsZC9qcy1zdHVicy9Gcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eV9Db250cm9sbGVyLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtc3R1YnMvRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlci5qcyIsInN0b3JhZ2UvcnN4LWJ1aWxkL2pzLXN0dWJzL0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtc3R1YnMvRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyLmpzIiwic3RvcmFnZS9yc3gtYnVpbGQvanMtc3R1YnMvRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5qcyIsInN0b3JhZ2UvcnN4LWJ1aWxkL2pzLXN0dWJzL0Zyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXIuanMiLCJkYXRhZ3JpZF9hYnN0cmFjdC5qcWh0bWwiLCJhY3Rpb25fYnV0dG9uX2RlbGV0ZS5qcWh0bWwiLCJhY3Rpb25fYnV0dG9uX2VkaXQuanFodG1sIiwiYWN0aW9uX2J1dHRvbl92aWV3LmpxaHRtbCIsImFjdGl2aXR5X2ZlZWQuanFodG1sIiwiYWN0b3JfcmVmZXJlbmNlLmpxaHRtbCIsImFkdmFuY2VkX3NlYXJjaF9wYW5lbC5qcWh0bWwiLCJhbGVydF9iYW5uZXIuanFodG1sIiwiYXZhdGFyLmpxaHRtbCIsImJsb2NrcXVvdGUuanFodG1sIiwiYnJlYWRjcnVtYnMuanFodG1sIiwiYnVsa19hY3Rpb25fYmFyLmpxaHRtbCIsImJ1bGtfc2VsZWN0aW9uLmpxaHRtbCIsImJ1dHRvbl9ncm91cC5qcWh0bWwiLCJidXR0b25fcHJpbWFyeS5qcWh0bWwiLCJidXR0b25fc2Vjb25kYXJ5LmpxaHRtbCIsImJ1dHRvbi5qcWh0bWwiLCJjYWxlbmRhcl9ldmVudC5qcWh0bWwiLCJjYWxlbmRhcl9ncmlkLmpxaHRtbCIsImNhcmRfZm9vdGVyLmpxaHRtbCIsImNhcmRfaGVhZGVyLmpxaHRtbCIsImNhcmRfdGl0bGUuanFodG1sIiwiY2FyZC5qcWh0bWwiLCJjaGFydF9jb21wb25lbnQuanFodG1sIiwiY2hlY2tib3guanFodG1sIiwiY29kZV9ibG9jay5qcWh0bWwiLCJjb2x1bW5fdmlzaWJpbGl0eV90b2dnbGUuanFodG1sIiwiY29tbWVudF90aHJlYWQuanFodG1sIiwiY29udGFjdF9hY3Rpb25zLmpxaHRtbCIsImNvbnRhY3Rfcm93LmpxaHRtbCIsImNvbnRhY3RzX2RhdGFfdGFibGUuanFodG1sIiwiY29udGFjdHNfbGlzdF9jYXJkLmpxaHRtbCIsImRhdGVfcGlja2VyLmpxaHRtbCIsImRyb3Bkb3duX21lbnUuanFodG1sIiwiZW1wdHlfc3RhdGUuanFodG1sIiwiZXhwb3J0X2J1dHRvbi5qcWh0bWwiLCJmaWxlX3VwbG9hZC5qcWh0bWwiLCJmaWx0ZXJfYmFyLmpxaHRtbCIsImZvcm1fYWN0aW9uc19jb21wb25lbnQuanFodG1sIiwiZm9ybV9maWVsZF9ncm91cC5qcWh0bWwiLCJmb3JtX2dyb3VwX2NvbXBvbmVudC5qcWh0bWwiLCJmb3JtX3Jvd19jb21wb25lbnQuanFodG1sIiwiZm9ybV92YWxpZGF0aW9uX21lc3NhZ2UuanFodG1sIiwiZ2FudHRfY2hhcnQuanFodG1sIiwiaWNvbl9idXR0b24uanFodG1sIiwiaWNvbl93aXRoX2xhYmVsLmpxaHRtbCIsImljb25fd2l0aF90ZXh0LmpxaHRtbCIsImljb24uanFodG1sIiwiaW5mb19ib3guanFodG1sIiwiaW5saW5lX2VkaXRfZmllbGQuanFodG1sIiwiaW5wdXRfd2l0aF9pY29uLmpxaHRtbCIsImlucHV0X3dpdGhfdmFsaWRhdGlvbi5qcWh0bWwiLCJpbnB1dC5qcWh0bWwiLCJrYW5iYW5fYm9hcmQuanFodG1sIiwibGluay5qcWh0bWwiLCJsaXN0LmpxaHRtbCIsImxvYWRpbmdfc2tlbGV0b24uanFodG1sIiwibWV0cmljX2NhcmQuanFodG1sIiwibW9iaWxlX2hlYWRlci5qcWh0bWwiLCJtb2RhbF9kaWFsb2cuanFodG1sIiwibXVsdGlfc2VsZWN0LmpxaHRtbCIsIm5vdGlmaWNhdGlvbl9iYWRnZS5qcWh0bWwiLCJub3RpZmljYXRpb25fZHJvcGRvd24uanFodG1sIiwib3ZlcmR1ZV9pbmRpY2F0b3IuanFodG1sIiwicGFnZV9oZWFkZXJfbGVmdC5qcWh0bWwiLCJwYWdlX2hlYWRlcl9yaWdodC5qcWh0bWwiLCJwYWdlX2hlYWRlci5qcWh0bWwiLCJwYWdlX3NlY3Rpb24uanFodG1sIiwicGFnZV9zdWJ0aXRsZS5qcWh0bWwiLCJwYWdlX3RpdGxlLmpxaHRtbCIsInBhZ2UuanFodG1sIiwicGFnaW5hdGlvbl9jb250cm9scy5qcWh0bWwiLCJwYWdpbmF0aW9uX2luZm8uanFodG1sIiwicG9wb3Zlci5qcWh0bWwiLCJwcm9ncmVzc19iYXIuanFodG1sIiwicmFkaW9fYnV0dG9uLmpxaHRtbCIsInJlY29yZF9jb3VudF9kaXNwbGF5LmpxaHRtbCIsInJpY2hfdGV4dF9lZGl0b3IuanFodG1sIiwicm93X2FjdGlvbl9tZW51LmpxaHRtbCIsIlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnQuanFodG1sIiwic2VhcmNoX2Jhci5qcWh0bWwiLCJzZWFyY2hfYnV0dG9uLmpxaHRtbCIsInNlYXJjaF9pbnB1dC5qcWh0bWwiLCJzZWFyY2hhYmxlX3NlbGVjdC5qcWh0bWwiLCJzZWxlY3RfZHJvcGRvd24uanFodG1sIiwic2lkZWJhcl9uYXYuanFodG1sIiwic2ltcGxlX3RhYmxlX3Rlc3QuanFodG1sIiwic29ydGFibGVfY29sdW1uX2hlYWRlci5qcWh0bWwiLCJzcGlubmVyLmpxaHRtbCIsInN0YXRfY2FyZC5qcWh0bWwiLCJzdGF0dXNfYmFkZ2UuanFodG1sIiwidGFiX2NvbnRlbnQuanFodG1sIiwidGFibGVfYm9keS5qcWh0bWwiLCJ0YWJsZV9oZWFkZXJzLmpxaHRtbCIsInRhYmxlX3BhZ2luYXRpb24uanFodG1sIiwidGFibGUuanFodG1sIiwidGFicy5qcWh0bWwiLCJ0YWdfZ3JvdXAuanFodG1sIiwidGFnLmpxaHRtbCIsInRleHRfZGlzcGxheS5qcWh0bWwiLCJ0ZXh0YXJlYS5qcWh0bWwiLCJ0aHJlZV9jb2x1bW5fbGF5b3V0LmpxaHRtbCIsInRpbWVfcGlja2VyLmpxaHRtbCIsInRpbWVsaW5lLmpxaHRtbCIsInRpbWVzdGFtcF9kaXNwbGF5LmpxaHRtbCIsInRvb2x0aXAuanFodG1sIiwidG9wX25hdi5qcWh0bWwiLCJ0cmVuZF9pbmRpY2F0b3IuanFodG1sIiwidHdvX2NvbHVtbl9sYXlvdXQuanFodG1sIiwidXNlcl9hdmF0YXJfZHJvcGRvd24uanFodG1sIiwidXNlcnNfZGF0YV90YWJsZS5qcWh0bWwiLCJyc3hfbW9kYWwuanFodG1sIiwiYnJlYWRjcnVtYi5qcWh0bWwiLCJicmVhZGNydW1iX2l0ZW0uanFodG1sIiwiY2xpZW50X2xhYmVsLmpxaHRtbCIsImNsaWVudF9sYWJlbF9saW5rLmpxaHRtbCIsInRleHRfaW5wdXQuanFodG1sIiwic2VsZWN0X2lucHV0LmpxaHRtbCIsImFqYXhfc2VsZWN0X2lucHV0LmpxaHRtbCIsImNoZWNrYm94X2lucHV0LmpxaHRtbCIsInd5c2l3eWdfaW5wdXQuanFodG1sIiwiY291bnRyeV9zZWxlY3RfaW5wdXQuanFodG1sIiwic3RhdGVfc2VsZWN0X2lucHV0LmpxaHRtbCIsInByb2ZpbGVfcGhvdG9faW5wdXQuanFodG1sIiwicnN4X3RhYnMuanFodG1sIiwicnN4X3RhYi5qcWh0bWwiLCJyc3hfZm9ybS5qcWh0bWwiLCJmb3JtX2ZpZWxkX2Fic3RyYWN0LmpxaHRtbCIsImZvcm1fZmllbGQuanFodG1sIiwiZm9ybV9oaWRkZW5fZmllbGQuanFodG1sIiwicGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpxaHRtbCIsImNsaWVudHNfZGF0YWdyaWQuanFodG1sIiwiYWRkX3VzZXJfbW9kYWxfZm9ybS5qcWh0bWwiLCJ1c2Vyc19kYXRhZ3JpZC5qcWh0bWwiLCJlZGl0X3VzZXJfbW9kYWxfZm9ybS5qcWh0bWwiLCJjb250YWN0c19kYXRhZ3JpZC5qcWh0bWwiLCJkYXRhX3RhYmxlLmpxaHRtbCIsIkNhcmRfSGVhZGVyX1JpZ2h0LmpxaHRtbCIsImNsaWVudF9zZWxlY3Rvcl9pbnB1dC5qcWh0bWwiLCJwcm9qZWN0c19kYXRhZ3JpZC5qcWh0bWwiLCJzdG9yYWdlL3JzeC10bXAvYnVuZGxlX0Zyb250ZW5kX0J1bmRsZV83NGU2NzYzZC5qcyIsInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfRnJvbnRlbmRfQnVuZGxlX2JlZGZmYTk4LmpzIiwic3RvcmFnZS9yc3gtdG1wL2J1bmRsZV9Gcm9udGVuZF9CdW5kbGVfZTgzZTQzZDMuanMiXSwibmFtZXMiOlsiZGVjb3JhdG9yIiwidmFsdWUiLCJpc19tb2JpbGUiLCJ0ZXN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiJCIsIndpbmRvdyIsIndpZHRoIiwiaXNfZGVza3RvcCIsImdldF9vcyIsInVzZXJfYWdlbnQiLCJwbGF0Zm9ybSIsIm1hY29zX3BsYXRmb3JtcyIsIndpbmRvd3NfcGxhdGZvcm1zIiwiaW9zX3BsYXRmb3JtcyIsIm9zIiwiaXNfbW9iaWxlX2RldmljZSIsImluZGV4T2YiLCJpc19jcmF3bGVyIiwiYm90X3BhdHRlcm4iLCJzY3JvbGxfaW50b192aWV3X2lmX25lZWRlZCIsInRhcmdldCIsIiR0YXJnZXQiLCIkcGFyZW50IiwicGFyZW50IiwidGFyZ2V0X3RvcCIsInBvc2l0aW9uIiwidG9wIiwic2Nyb2xsVG9wIiwidGFyZ2V0X2hlaWdodCIsIm91dGVySGVpZ2h0IiwicGFyZW50X2hlaWdodCIsImhlaWdodCIsInNjcm9sbF9wb3NpdGlvbiIsIkRlYnVnZ2VyIiwiY29uc29sZV9kZWJ1ZyIsIm5ld19zY3JvbGxfcG9zaXRpb24iLCJNYXRoIiwibWF4IiwibWluIiwic2Nyb2xsSGVpZ2h0Iiwic2Nyb2xsX3BhZ2VfaW50b192aWV3X2lmX25lZWRlZCIsIm9mZnNldCIsIndpbmRvd19oZWlnaHQiLCJ3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uIiwiYW5pbWF0ZSIsIndhaXRfZm9yX2ltYWdlcyIsImNhbGxiYWNrIiwiJGltYWdlcyIsInRvdGFsX2ltYWdlcyIsImxlbmd0aCIsImltYWdlc19sb2FkZWQiLCJlYWNoIiwiaW1nIiwiSW1hZ2UiLCJvbmxvYWQiLCJvbmVycm9yIiwic3JjIiwiJG5ic3AiLCJlc2NhcGVfanFfc2VsZWN0b3IiLCJpZCIsInJlcGxhY2UiLCJ1bml4X3RpbWUiLCJyb3VuZCIsIkRhdGUiLCJnZXRUaW1lIiwieW1kaGlzX3RvX3VuaXgiLCJzdHJfZGF0ZSIsImRhdGUiLCJlcnJvciIsInN0ciIsImVycm9yX2NvZGUiLCJ1bmRlZiIsInN0YXR1cyIsInNob3VsZG50X2hhcHBlbiIsIm1lc3NhZ2UiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJFcnJvciIsInN0YWNrIiwic3RhY2tMaW5lcyIsInNwbGl0IiwiY2FsbGVySW5mbyIsImNhbGxlckxpbmUiLCJtYXRjaCIsImVycm9yTWVzc2FnZSIsImNvbnNvbGUiLCJyZXBlYXQiLCJmYXRhbEVycm9yIiwibmFtZSIsImhhc2giLCJ0aGVfdmFyIiwiY2FsY19zaGExIiwiaWdub3JlZF9rZXlzIiwianNvbl9zdHJpbmdpZnlfbm9jaXJjIiwiY2FjaGUiLCJKU09OIiwic3RyaW5naWZ5Iiwia2V5IiwidiIsIl9jYWNoZV9rZXkiLCJfaGFzaF9rZXkiLCJwdXNoIiwiZmxhdF92YXIiLCJfZmxhdHRlbiIsInByZWZpeCIsImRlcHRoIiwiaXNfb2JqZWN0IiwiQWJzdHJhY3QiLCJrIiwiaGFzT3duUHJvcGVydHkiLCJpc19hcnJheSIsImkiLCJmb3JlYWNoIiwiaXNfZnVuY3Rpb24iLCJpc19udW1lcmljIiwiU3RyaW5nIiwic29ydGVyIiwic29ydCIsImEiLCJiIiwianNvbiIsImhhc2hlZCIsInNoYTEiLCJkZWVwX2VxdWFsIiwibXV0ZXgiLCJnbG9iYWxfaWQiLCJpbnN0YW5jZV9tdXRleGVzIiwiX2luc3RhbmNlX3N0b3JhZ2UiLCJXZWFrTWFwIiwiZ2xvYmFsX211dGV4ZXMiLCJfZ2xvYmFsX3N0b3JhZ2UiLCJNYXAiLCJnZXRfaW5zdGFuY2VfbXV0ZXgiLCJpbnN0YW5jZSIsIm1ldGhvZF9uYW1lIiwiaW5zdGFuY2VfbG9ja3MiLCJnZXQiLCJzZXQiLCJsb2NrX3N0YXRlIiwiYWN0aXZlIiwicXVldWUiLCJnZXRfZ2xvYmFsX211dGV4Iiwic2NoZWR1bGVfbmV4dCIsImZuIiwicmVzb2x2ZSIsInJlamVjdCIsInNoaWZ0IiwiUHJvbWlzZSIsInRoZW4iLCJmaW5hbGx5IiwiYWNxdWlyZV9sb2NrIiwiZGVzY3JpcHRvciIsIm9yaWdpbmFsX21ldGhvZCIsIl9sZW4iLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiYXBwbHkiLCJfbGVuMiIsIl9rZXkyIiwic2xlZXAiLCJtaWxsaXNlY29uZHMiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJzZXRUaW1lb3V0IiwiZGVib3VuY2UiLCJjYWxsYmFja19vcl9kZWxheSIsImRlbGF5IiwiaW1tZWRpYXRlIiwiZGVjb3JhdG9yX2RlbGF5IiwiZGVjb3JhdG9yX2ltbWVkaWF0ZSIsImNvbnRleHQiLCJraW5kIiwiZGVib3VuY2VfaW1wbCIsInJ1bm5pbmciLCJxdWV1ZWQiLCJsYXN0X2VuZF90aW1lIiwidGltZXIiLCJuZXh0X2FyZ3MiLCJuZXh0X2NvbnRleHQiLCJyZXNvbHZlX3F1ZXVlIiwicmVqZWN0X3F1ZXVlIiwicnVuX2Z1bmN0aW9uIiwidGhlc2VfcmVzb2x2ZXMiLCJ0aGVzZV9yZWplY3RzIiwicmVzdWx0IiwiZXJyIiwibm93IiwiY2xlYXJUaW1lb3V0IiwiZmlyc3RfY2FsbCIsInNpbmNlIiwiSW5maW5pdHkiLCJ3YWl0Iiwicndsb2NrIiwiY2IiLCJSZWFkV3JpdGVMb2NrIiwiYWNxdWlyZSIsInJ3bG9ja19yZWFkIiwiYWNxdWlyZV9yZWFkIiwicndsb2NrX2ZvcmNlX3VubG9jayIsImZvcmNlX3VubG9jayIsInJ3bG9ja19wZW5kaW5nIiwicGVuZGluZyIsIm9iaiIsInJlc3VsdHMiLCJpc0FycmF5IiwiZm9yRWFjaCIsImluZGV4IiwicHJvbWlzZXMiLCJmaWx0ZXIiLCJhbGwiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJpc19zdHJpbmciLCJzIiwiaXNfaW50ZWdlciIsIk51bWJlciIsImlzSW50ZWdlciIsImlzX3Byb21pc2UiLCJmdW5jdGlvbl90b19jaGVjayIsInRvU3RyaW5nIiwiY2FsbCIsImlzX2VtYWlsIiwiZW1haWwiLCJyZWdleCIsImlzc2V0IiwiZW1wdHkiLCJvYmplY3QiLCJmbG9hdCIsInZhbCIsInBhcnNlZCIsImludCIsInBhcnNlSW50IiwidmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSIsImh0bWwiLCJfIiwiZXNjYXBlIiwibmwyYnIiLCJodG1sYnIiLCJ1cmxlbmNvZGUiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ1cmxkZWNvZGUiLCJkZWNvZGVVUklDb21wb25lbnQiLCJqc29uX2VuY29kZSIsImpzb25fZGVjb2RlIiwicGFyc2UiLCJjaGFubmVsIiwidmFsdWVzIiwicmVwbGFjZV9hbGwiLCJzdHJpbmciLCJzZWFyY2giLCJqb2luIiwidWN3b3JkcyIsImlucHV0IiwibWFwIiwid29yZCIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJjb3VudCIsIm8iLCJjIiwiY2xvbmUiLCJGdW5jdGlvbiIsInByb3RvdHlwZSIsIl9fY2xvbmUiLCJ0aGF0IiwidGVtcCIsImNsb25lZCIsImNvbnN0cnVjdG9yIiwiT2JqZWN0IiwiYXNzaWduIiwiY29hbGVzY2UiLCJmcm9tIiwicmV0dXJuX3ZhbCIsImFyZyIsImNzdl90b19hcnJheV90cmltIiwic3RyX2NzdiIsInBhcnRzIiwicmV0IiwicGFydCIsInRyaW0iLCJxdWlsbF9yZWFkeSIsIlF1aWxsIiwic2F2ZV9jbGllbnQiLCJjbGllbnRfaWQiLCJyZXNwb25zZSIsIkZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlciIsInNhdmUiLCJzdWNjZXNzIiwicmVkaXJlY3QiLCJSc3giLCJSb3V0ZSIsImVycm9ycyIsIl9nZW5lcmFsIiwic2F2ZV9jb250YWN0IiwiY29udGFjdF9pZCIsIkZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIiLCJNYW5pZmVzdCIsIl9kZWZpbmUiLCJpdGVtcyIsIl9jbGFzc2VzIiwiaXRlbSIsImNsYXNzX29iamVjdCIsImNsYXNzX25hbWUiLCJjbGFzc19leHRlbmRzIiwiZGVjb3JhdG9ycyIsImNsYXNzIiwiZXh0ZW5kcyIsIl9uYW1lIiwiX2V4dGVuZHMiLCJfZGVjb3JhdG9ycyIsIl9idWlsZF9zdWJjbGFzc19pbmRleCIsIl9zdWJjbGFzc19pbmRleCIsImNsYXNzZGF0YSIsImN1cnJlbnRfY2xhc3NfbmFtZSIsImN1cnJlbnRfY2xhc3NkYXRhIiwiZXh0ZW5kc19uYW1lIiwiaW5jbHVkZXMiLCJnZXRfZXh0ZW5kaW5nIiwiYmFzZV9jbGFzcyIsImJhc2VfY2xhc3Nfb2JqZWN0IiwiZ2V0X2NsYXNzX2J5X25hbWUiLCJjbGFzc2VzIiwianNfaXNfc3ViY2xhc3Nfb2YiLCJsb2NhbGVDb21wYXJlIiwic3ViY2xhc3MiLCJzdXBlcmNsYXNzIiwic3ViY2xhc3Nfb2JqZWN0Iiwic3VwZXJjbGFzc19vYmplY3QiLCJjdXJyZW50X2NsYXNzIiwiZ2V0X2FsbF9jbGFzc2VzIiwiYnVpbGRfa2V5IiwicnN4YXBwIiwiZ2V0X2RlY29yYXRvcnMiLCJjbGFzc19pbmZvIiwiX3RyYW5zZm9ybV9kZWNvcmF0b3JzIiwiZ2V0X2FsbF9kZWNvcmF0b3JzIiwiY29tcGFjdF9kZWNvcmF0b3JzIiwiaGFzX2RlY29yYXRvciIsImRlY29yYXRvcl9uYW1lIiwic29tZSIsImQiLCJqc19nZXRfc3ViY2xhc3Nlc19vZiIsImJhc2VfY2xhc3NfbmFtZSIsInN1YmNsYXNzX25hbWVzIiwic3ViY2xhc3Nfb2JqZWN0cyIsInN1YmNsYXNzX25hbWUiLCJuYW1lX2EiLCJuYW1lX2IiLCJSc3hfQmVoYXZpb3JzIiwiX29uX2ZyYW1ld29ya19jb3JlX2luaXQiLCJfaW5pdF9pZ25vcmVfaW52YWxpZF9hbmNob3JfbGlua3MiLCJfdHJpbV9jb3BpZWRfdGV4dCIsImRvY3VtZW50Iiwib24iLCJlIiwiJGxpbmsiLCJocmVmIiwiYXR0ciIsImlzRGVmYXVsdFByZXZlbnRlZCIsImRhdGEiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInN0YXJ0c1dpdGgiLCJ0YXJnZXRJZCIsInN1YnN0cmluZyIsInRhcmdldEV4aXN0cyIsImdldEVsZW1lbnRCeUlkIiwicXVlcnlTZWxlY3RvciIsImFkZEV2ZW50TGlzdGVuZXIiLCJldmVudCIsInNoaWZ0S2V5Iiwic2VsZWN0aW9uIiwiZ2V0U2VsZWN0aW9uIiwic2VsZWN0ZWRfdGV4dCIsImNvbnRhaW5lciIsImdldFJhbmdlQXQiLCJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsIm5vZGVUeXBlIiwicGFyZW50Tm9kZSIsImNsb3Nlc3QiLCJ0cmltbWVkX3RleHQiLCJjbGlwYm9hcmREYXRhIiwic2V0RGF0YSIsImxvZyIsIlJzeF9DYWNoZSIsIm9uX2NvcmVfZGVmaW5lIiwiQ29yZV9DYWNoZSIsIl9jYWNoZXMiLCJnbG9iYWwiLCJfY2FjaGVzX3NldCIsImdldF9pbnN0YW5jZSIsIk1haW4iLCJkZWJ1ZyIsImtleV9lbmNvZGVkIiwiX2VuY29kZWtleSIsImdldF9nbG9iYWwiLCJnZXRfc2Vzc2lvbiIsIl9zdXBwb3J0c1N0b3JhZ2UiLCJycyIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInNldF9zZXNzaW9uIiwiX3RyeWFnYWluIiwicmVtb3ZlSXRlbSIsInNldEl0ZW0iLCJfaXNPdXRPZlNwYWNlIiwiY2xlYXIiLCJfcmVzZXQiLCJfX3N1cHBvcnRzU3RvcmFnZSIsImV4IiwiUnN4X0luaXQiLCJpc19wcm9kIiwiX19lbnZpcm9ubWVudF9jaGVja3MiLCJzY3JpcHRzIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJzY3JpcHQiLCJkZWZlciIsInJlYXNvbiIsIl9yc3hfY29yZV9ib290X3N0b3AiLCJSc3hfSnNfTW9kZWwiLCJfX01PREVMIiwibW9kZWxEYXRhIiwiZmV0Y2giLCJDdXJyZW50Q2xhc3MiLCJtb2RlbE5hbWUiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YVR5cGUiLCJfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSIsImdldE1vZGVsTmFtZSIsInJlZnJlc2giLCJmcmVzaCIsInRvT2JqZWN0IiwidG9KU09OIiwiTW9kZWxDbGFzcyIsIlJzeF9WaWV3X1RyYW5zaXRpb25zIiwic3RhcnRWaWV3VHJhbnNpdGlvbiIsIl9pbmplY3RfdHJhbnNpdGlvbl9jc3MiLCJzdHlsZSIsImNyZWF0ZUVsZW1lbnQiLCJ0ZXh0Q29udGVudCIsImhlYWQiLCJhcHBlbmRDaGlsZCIsIl81MGFlNjA5ZV9hc3NlcnRDbGFzc0JyYW5kIiwiXzUwYWU2MDllX2dldF9sb2NrIiwid3JpdGVyX3EiLCJfNTBhZTYwOWVfc2NoZWR1bGUiLCJ3cml0ZXJfYWN0aXZlIiwicmVhZGVyX3EiLCJyZWFkZXJzIiwiX2xvY2tzIiwiZGVsZXRlIiwiXzUwYWU2MDllX1JlYWRXcml0ZUxvY2siLCJiYXRjaCIsInNwbGljZSIsIkZvcm1fVXRpbHMiLCJfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lIiwicGFyYW1zIiwiYWpheF9zdWJtaXQiLCJvcHRpb25zIiwiJGVsZW1lbnQiLCJpcyIsImNvbnRyb2xsZXIiLCJhY3Rpb24iLCJBamF4IiwiYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24iLCJhcHBseV9mb3JtX2Vycm9ycyIsInBhcmVudF9zZWxlY3RvciIsInJlc2V0X2Zvcm1fZXJyb3JzIiwibm9ybWFsaXplZCIsIl9ub3JtYWxpemVfZXJyb3JzIiwiYW5pbWF0aW9ucyIsInR5cGUiLCJfYXBwbHlfZ2VuZXJhbF9lcnJvcnMiLCJkZWR1cGxpY2F0ZWQiLCJfZGVkdXBsaWNhdGVfZXJyb3JzIiwiX2FwcGx5X2ZpZWxkX2Vycm9ycyIsIm1hdGNoZWRfY291bnQiLCJrZXlzIiwidW5tYXRjaGVkIiwidW5tYXRjaGVkX2RlZHVwbGljYXRlZCIsInVubWF0Y2hlZF9jb3VudCIsInN1bW1hcnlfbXNnIiwic3VtbWFyeV9hbmltYXRpb25zIiwiX2FwcGx5X2NvbWJpbmVkX2Vycm9yIiwiJGVycm9yX2NvbnRhaW5lciIsImZpbmQiLCJmaXJzdCIsImNvbnRhaW5lcl90b3AiLCJmaXhlZF9oZWFkZXJfaGVpZ2h0IiwiX2dldF9maXhlZF9oZWFkZXJfaGVpZ2h0IiwidGFyZ2V0X3Njcm9sbCIsInJlc2V0IiwiZm9ybV9zZWxlY3RvciIsIiRmb3JtIiwidHJpZ2dlciIsInNlcmlhbGl6ZSIsInNlcmlhbGl6ZUFycmF5IiwiZm9ybV9kYXRhIiwib25fc3VjY2VzcyIsImRldGFpbHMiLCJvbl9lcnJvciIsInJlbW92ZSIsInJlbW92ZUNsYXNzIiwiZXZlcnkiLCJ1bndyYXBwZWQiLCJmaWVsZCIsIlNldCIsInNlZW4iLCJoYXMiLCJhZGQiLCJmaWVsZF9lcnJvcnMiLCJmaWVsZF9uYW1lIiwiZXJyb3JfbWVzc2FnZSIsIiRpbnB1dCIsIiRlcnJvciIsImFkZENsYXNzIiwiYXBwZW5kVG8iLCJoaWRlIiwiZmFkZUluIiwicHJvbWlzZSIsInVubWF0Y2hlZF9lcnJvcnMiLCIkYWxlcnQiLCJ0ZXh0IiwiJGxpc3QiLCJlcnJvcl9tc2ciLCJwcmVwZW5kVG8iLCJtZXNzYWdlcyIsIm1zZyIsImVycm9yX2xpc3QiLCJ0b3RhbF9oZWlnaHQiLCIkZWwiLCJjc3MiLCJvdXRlcldpZHRoIiwidmlld3BvcnRfd2lkdGgiLCJsb2dfYnJvd3Nlcl9lcnJvcnMiLCJfaGFuZGxlX2Jyb3dzZXJfZXJyb3IiLCJmaWxlbmFtZSIsImxpbmVubyIsImNvbG5vIiwib25fcmVmcmVzaCIsImVuYWJsZWQiLCJjb25maWciLCJmaWx0ZXJfbW9kZSIsInNwZWNpZmljIiwic3BlY2lmaWNfY2hhbm5lbCIsImNoYW5uZWxzIiwid2hpdGVsaXN0IiwiZmlsdGVyX2NoYW5uZWxzIiwiYmxhY2tsaXN0IiwidGltZXN0YW1wIiwidG9JU09TdHJpbmciLCJpbmNsdWRlX2xvY2F0aW9uIiwiaW5jbHVkZV9iYWNrdHJhY2UiLCJsb2NhdGlvbiIsImJhY2t0cmFjZSIsImxpbmUiLCJvdXRwdXRzIiwiYnJvd3NlciIsImluY2x1ZGVfYmVuY2htYXJrIiwiX2dldF90aW1lX3ByZWZpeCIsImNoYW5uZWxQcmVmaXgiLCJjb25zb2xlTWV0aG9kIiwibGFyYXZlbF9sb2ciLCJfYmF0Y2hfY29uc29sZV9tZXNzYWdlIiwibG9nX2Vycm9yIiwiZXJyb3JEYXRhIiwiX2Vycm9yX2NvdW50IiwiTUFYX0VSUk9SU19QRVJfUEFHRSIsIl9lcnJvcl9iYXRjaF9jb3VudCIsIk1BWF9FUlJPUl9CQVRDSEVTIiwiX2Vycm9yX2JhdGNoIiwiX2Vycm9yX3RpbWVyIiwiX2ZsdXNoX2Vycm9yX2JhdGNoIiwiREVCT1VOQ0VfTVMiLCJfY29uc29sZV9iYXRjaCIsIl9jb25zb2xlX3RpbWVyIiwiX2ZsdXNoX2NvbnNvbGVfYmF0Y2giLCJfc3RhcnRfdGltZSIsImVsYXBzZWQiLCJ0b0ZpeGVkIiwiXzI3ZTBlOTg2X2RlZmluZVByb3BlcnR5IiwiUnN4X0pxX0hlbHBlcnMiLCJleGlzdHMiLCJpc192aXNpYmxlIiwic2Nyb2xsX3VwX3RvIiwic3BlZWQiLCJpc19pbl9kb20iLCJlX3RvcCIsInNfdG9wIiwiZXhwciIsImZvY3VzIiwiZWxlbSIsImFjdGl2ZUVsZW1lbnQiLCJfY2xpY2tfbmF0aXZlIiwiY2xpY2siLCJoYW5kbGVyIiwib3JpZ2luYWxfcHJldmVudERlZmF1bHQiLCJiaW5kIiwid2FybiIsImNsaWNrX2FsbG93X2RlZmF1bHQiLCJfYW5jZXN0b3IiLCJIVE1Mb2JqIiwicGFyZW50RWxlbWVudCIsImRvY3VtZW50RWxlbWVudCIsImlzX2luX3ZpZXdwb3J0Iiwic2Nyb2xsdG9wIiwidG9wX29mX2VsZW1lbnQiLCJib3R0b21fb2ZfZWxlbWVudCIsImJvdHRvbV9vZl9zY3JlZW4iLCJpbm5lckhlaWdodCIsInRvcF9vZl9zY3JlZW4iLCJ0YWduYW1lIiwicHJvcCIsInRvTG93ZXJDYXNlIiwiaXNfZXh0ZXJuYWwiLCJob3N0IiwibGluayIsImhvc3RuYW1lIiwiY2hlY2tWYWxpZGl0eSIsInJlcG9ydFZhbGlkaXR5IiwicmVxdWVzdFN1Ym1pdCIsImNsb3Nlc3Rfc2libGluZyIsInNlbGVjdG9yIiwiJGN1cnJlbnQiLCIkZm91bmQiLCJuYXRpdmVfYWpheCIsInNldHRpbmdzIiwicmVxdWVzdF91cmwiLCJpc19yZWxhdGl2ZSIsImlzX3NhbWVfZG9tYWluIiwib3JpZ2luIiwiaXNfbG9jYWxfcmVxdWVzdCIsIl9fbG9jYWxfaW50ZWdyYXRpb24iLCJpc19maWxlX3VwbG9hZCIsImVuZHNXaXRoIiwiY29udHJvbGxlcl9uYW1lIiwiYWN0aW9uX25hbWUiLCJ1cmxfbWF0Y2giLCJfaW5pdF9ldmVudHMiLCJfZXZlbnRfaGFuZGxlcnMiLCJfdHJpZ2dlcmVkX2V2ZW50cyIsInRyaWdnZXJfcmVmcmVzaCIsIkNvcmVfTG9nIiwiaXNfZGV2IiwidWlkIiwiX3VpZCIsIl9kZWZpbmVfcm91dGVzIiwicm91dGVzIiwiX3JvdXRlcyIsInBhcmFtc19vYmoiLCJwYXR0ZXJuIiwiX2dlbmVyYXRlX3VybF9mcm9tX3BhdHRlcm4iLCJyZXF1aXJlZF9wYXJhbXMiLCJtYXRjaGVzIiwibWlzc2luZyIsInJlcXVpcmVkIiwidXNlZF9wYXJhbXMiLCJwYXJhbV9uYW1lIiwiZW5jb2RlZF92YWx1ZSIsInF1ZXJ5X3BhcmFtcyIsInF1ZXJ5X3N0cmluZyIsImVudHJpZXMiLCJfcmVmIiwiX3JzeF9jYWxsX2FsbF9jbGFzc2VzIiwiYWxsX2NsYXNzZXMiLCJjbGFzc2VzX3dpdGhfbWV0aG9kIiwicHJvbWlzZV9waWxlIiwicmV0dXJuX3ZhbHVlIiwiX19zdG9wcGVkIiwiX3JzeF9jb3JlX2Jvb3QiLCJfX2Jvb3RlZCIsInBoYXNlcyIsInBoYXNlIiwiX3BhcnNlX2hhc2giLCJoYXNoX3N0cmluZyIsInBhaXJzIiwicGFpciIsIl9zZXJpYWxpemVfaGFzaCIsImdldF9hbGxfcGFnZV9zdGF0ZSIsImdldF9wYWdlX3N0YXRlIiwiX3N0YXRlJGtleSIsInN0YXRlIiwic2V0X3BhZ2Vfc3RhdGUiLCJuZXdfaGFzaCIsInBhdGhuYW1lIiwiaGlzdG9yeSIsInJlcGxhY2VTdGF0ZSIsInNldF9hbGxfcGFnZV9zdGF0ZSIsIm5ld19zdGF0ZSIsInJlbmRlcl9lcnJvciIsIiRjb250YWluZXIiLCJmaWxlIiwiX2VzY2FwZV9odG1sIiwiZGl2IiwiaW5uZXJIVE1MIiwiX2U4MjExZjViX2RlZmluZVByb3BlcnR5IiwiX3BlbmRpbmdfY2FsbHMiLCJfZmx1c2hfdGltZW91dCIsIl9jYWxsX2NvdW50ZXIiLCJNQVhfQkFUQ0hfU0laRSIsIl90cmFja2VkX3Byb21pc2VzIiwiV2Vha1NldCIsIk1vZGFsIiwicGF0aCIsImFqYXhfZGlzYWJsZV9iYXRjaGluZyIsIl9jYWxsX2RpcmVjdCIsIl9jYWxsX2JhdGNoIiwiY2FsbF9rZXkiLCJfZ2VuZXJhdGVfY2FsbF9rZXkiLCJleGlzdGluZ19jYWxsIiwiaXNfY29tcGxldGUiLCJpc19lcnJvciIsImNhbGxiYWNrcyIsImNhbGxfaWQiLCJwZW5kaW5nX2NhbGwiLCJwZW5kaW5nX2NvdW50IiwiX2ZsdXNoX3BlbmRpbmdfY2FsbHMiLCJfc3VjY2VzcyIsInByb2Nlc3NlZF92YWx1ZSIsIl9hamF4X3JldHVybl92YWx1ZSIsImVycm9yX3R5cGUiLCJmYXRhbF9lcnJvcl9kYXRhIiwiZmF0YWxfZXJyb3IiLCJlbmRwb2ludCIsImF1dGhfZXJyb3IiLCJ1bmF1dGhfZXJyb3IiLCJmb3JtX2Vycm9yIiwiZ2VuZXJpY19lcnJvciIsInhociIsIl9leHRyYWN0X2Vycm9yX21lc3NhZ2UiLCJuZXR3b3JrX2Vycm9yIiwic3RhdHVzVGV4dCIsImNhbGxzX3RvX3NlbmQiLCJjYWxsX21hcCIsImJhdGNoX2NhbGxzIiwicmVzcG9uc2Vfa2V5IiwiY2FsbF9yZXNwb25zZSIsImVycm9yX2RldGFpbHMiLCJfcmVmMiIsInhocl9lcnJvciIsIl9yZWYzIiwic29ydGVkX3BhcmFtcyIsInJlc3BvbnNlSlNPTiIsInJlc3BvbnNlVGV4dCIsIkpxaHRtbF9Db21wb25lbnQiLCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50IiwiSnFodG1sX0ludGVncmF0aW9uIiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZSIsImpxaHRtbF9jb21wb25lbnRzIiwiY29tcG9uZW50IiwianFodG1sIiwicmVnaXN0ZXJfY29tcG9uZW50IiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQiLCIkc2NvcGUiLCJpc190b3BfbGV2ZWwiLCJjb21wb25lbnRzX25lZWRpbmdfaW5pdCIsImNvbnRhaW5zIiwiY2xhc3NMaXN0IiwiY29tcG9uZW50X25hbWUiLCJjb21wb25lbnRfYXJncyIsImFyZ3Nfc3RyaW5nIiwicmVtb3ZlQXR0ciIsInJlbW92ZURhdGEiLCJjb21wb25lbnRfYXJnc19maWx0ZXJlZCIsIl9pbm5lcl9odG1sIiwiY29tcG9uZW50X3Byb21pc2UiLCJuZXN0ZWRfcHJvbWlzZXMiLCJnZXRfY29tcG9uZW50X25hbWVzIiwiaGFzX2NvbXBvbmVudCIsIkRhdGFHcmlkX0Fic3RyYWN0Iiwib25fY3JlYXRlIiwicm93cyIsImxvYWRpbmciLCJpc19lbXB0eSIsImxvYWRlZCIsInRvdGFsX3BhZ2VzIiwib25fcmVhZHkiLCJfdGhhdCRhcmdzJHBlcl9wYWdlIiwiX3RoYXQkYXJncyRzb3J0IiwiX3RoYXQkYXJncyRvcmRlciIsImRhdGFfc291cmNlIiwiZGVmYXVsdF9wYWdlIiwiZGVmYXVsdF9wZXJfcGFnZSIsInBlcl9wYWdlIiwiZGVmYXVsdF9zb3J0IiwiZGVmYXVsdF9vcmRlciIsIm9yZGVyIiwiZGVmYXVsdF9maWx0ZXIiLCJoYXNoX3BhZ2UiLCJfY2lkIiwiaGFzaF9zb3J0IiwiaGFzaF9vcmRlciIsImhhc2hfZmlsdGVyIiwicGFnZSIsInJlZ2lzdGVyX3JlbmRlcl9jYWxsYmFja3MiLCJyZWdpc3Rlcl9maWx0ZXJfaGFuZGxlcnMiLCIkZmlsdGVyIiwiJGlkIiwibWVhc3VyZV9hbmRfc2V0X2ZpeGVkX2hlaWdodCIsImxvYWRfcGFnZSIsInVwZGF0ZV9oZWFkZXIiLCJfbGFzdF9oZWFkZXJfc3RhdGUiLCJjdXJyZW50IiwicmVuZGVyIiwidXBkYXRlX3BhZ2luYXRpb24iLCJfbGFzdF9wYWdpbmF0aW9uX3N0YXRlIiwidG90YWwiLCJyZWNvcmRzIiwic2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQiLCIkcm93IiwiJGNvbCIsIiRjaGlsZHJlbiIsImNoaWxkcmVuIiwiJHRoIiwic29ydGJ5IiwiJGV4aXN0aW5nX2xpbmsiLCJjb250ZW50cyIsImVuZCIsImFycm93Iiwic29ydF9ieSIsImhhc0NsYXNzIiwiJGNsZWFyX2J0biIsImNsZWFyX2ZpbHRlciIsImNvbHVtbiIsImZpbHRlcl92YWx1ZSIsImZpbHRlcl9jaGFuZ2VkIiwiJGRhdGFncmlkIiwiZGF0YWdyaWRUb3AiLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiJHRib2R5IiwiJG1lYXN1cmVtZW50X3JvdyIsImFwcGVuZCIsInJvd19oZWlnaHQiLCJtaW5faGVpZ2h0IiwidGJvZHlfbWluX2hlaWdodCIsIkFjdGl2aXR5X0ZlZWQiLCJvbl9sb2FkIiwiYWN0aXZpdGllcyIsImF1dG9fcmVmcmVzaCIsInN0YXJ0X2F1dG9fcmVmcmVzaCIsImludGVydmFsIiwicmVmcmVzaF9pbnRlcnZhbCIsInJlZnJlc2hfdGltZXIiLCJzZXRJbnRlcnZhbCIsInJlbG9hZF9kYXRhIiwic3RvcF9hdXRvX3JlZnJlc2giLCJjbGVhckludGVydmFsIiwiQWN0b3JfUmVmZXJlbmNlIiwiQWR2YW5jZWRfU2VhcmNoX1BhbmVsIiwiY2F0ZWdvcmllcyIsInNldF9vcHRpb25zIiwidGFncyIsInBlcmZvcm1fc2VhcmNoIiwib25fY2xvc2UiLCJjcml0ZXJpYSIsImtleXdvcmRzIiwiZ2V0X3ZhbHVlIiwiY2F0ZWdvcnkiLCJmcm9tX2RhdGUiLCJ0b19kYXRlIiwiZXhhY3RfbWF0Y2giLCJvbl9zZWFyY2giLCJzZXRfdmFsdWUiLCJvbl9yZXNldCIsIkFsZXJ0X0Jhbm5lciIsImRpc21pc3NpYmxlIiwiQXZhdGFyIiwic2l6ZSIsInNpemVfbWFwIiwic2hvd19pbml0aWFscyIsImluaXRpYWxzIiwiJGRpdiIsInJlcGxhY2VXaXRoIiwiQmxvY2txdW90ZSIsIkJyZWFkY3J1bWJzIiwiQnVsa19BY3Rpb25fQmFyIiwiJHRhYmxlIiwic2V0X2NvdW50IiwiQnVsa19TZWxlY3Rpb24iLCIkY2hlY2tib3giLCJjaGVja2VkIiwib25fY2hhbmdlIiwiQnV0dG9uX0dyb3VwIiwiQnV0dG9uX1ByaW1hcnkiLCJCdXR0b25fU2Vjb25kYXJ5IiwiQnV0dG9uIiwiQ2FsZW5kYXJfRXZlbnQiLCJvbl9jbGljayIsIkNhbGVuZGFyX0dyaWQiLCJjdXJyZW50X2RhdGUiLCJyZW5kZXJfY2FsZW5kYXIiLCJzZXRNb250aCIsImdldE1vbnRoIiwieWVhciIsImdldEZ1bGxZZWFyIiwibW9udGgiLCJtb250aF9uYW1lcyIsImZpcnN0X2RheSIsImdldERheSIsImRheXNfaW5fbW9udGgiLCJnZXREYXRlIiwiZGF5IiwiJHRyIiwiaiIsIiR0ZCIsIiRkYXlfbnVtIiwidG9kYXkiLCJldmVudHMiLCJnZXRfZXZlbnRzX2Zvcl9kYXRlIiwiJGV2ZW50IiwidGl0bGUiLCJvbl9ldmVudF9jbGljayIsInBhZFN0YXJ0Iiwib25fZGF0ZV9jbGljayIsImRhdGVfc3RyIiwiQ2FyZCIsIkNoYXJ0X0NvbXBvbmVudCIsIkNoZWNrYm94IiwiZGlzYWJsZWQiLCJDb2RlX0Jsb2NrIiwiQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIiwiY29sdW1ucyIsImJ1aWxkX21lbnUiLCIkbWVudSIsIiRsaSIsIiRsYWJlbCIsInZpc2libGUiLCJsYWJlbCIsInRvZ2dsZV9jb2x1bW4iLCJvbl90b2dnbGUiLCJ0YWJsZSIsInNob3ciLCJzZXRfY29sdW1ucyIsIkNvbW1lbnRfVGhyZWFkIiwiY29tbWVudHMiLCJzdWJtaXRfY29tbWVudCIsIiRjb21tZW50IiwiY29tbWVudF9pZCIsInNob3dfcmVwbHlfZm9ybSIsImVkaXRfY29tbWVudCIsImRlbGV0ZV9jb21tZW50Iiwib25fc3VibWl0Iiwib25fZWRpdCIsImNvbmZpcm0iLCJvbl9kZWxldGUiLCJEYXRlX1BpY2tlciIsInJlYWRvbmx5IiwiRHJvcGRvd25fTWVudSIsIiRjaGlsZCIsIkVtcHR5X1N0YXRlIiwiRXhwb3J0X0J1dHRvbiIsImZvcm1hdCIsImN1cnJlbnRUYXJnZXQiLCJleHBvcnRfZGF0YSIsIm9uX2V4cG9ydCIsImF1dG9fZXhwb3J0IiwiZXhwb3J0X3VybCIsImV4cG9ydF9jc3YiLCJleHBvcnRfanNvbiIsImhlYWRlcnMiLCJjc3YiLCJyb3ciLCJoZWFkZXIiLCJibG9iIiwiQmxvYiIsIlVSTCIsImNyZWF0ZU9iamVjdFVSTCIsIiRhIiwicmV2b2tlT2JqZWN0VVJMIiwiRmlsZV9VcGxvYWQiLCIkZHJvcF96b25lIiwiYWNjZXB0IiwibXVsdGlwbGUiLCJmaWxlcyIsImhhbmRsZV9maWxlcyIsInN0b3BQcm9wYWdhdGlvbiIsIm9yaWdpbmFsRXZlbnQiLCJkYXRhVHJhbnNmZXIiLCJtYXhfc2l6ZV9ieXRlcyIsImFsZXJ0IiwiZm9ybWF0X3NpemUiLCJzZWxlY3RlZF9maWxlIiwidXBsb2FkX3VybCIsInVwbG9hZCIsIm9uX3NlbGVjdCIsIkZvcm1EYXRhIiwiYm9keSIsIm9uX3VwbG9hZCIsIm9uX2NsZWFyIiwiZ2V0X2ZpbGUiLCJieXRlcyIsIkZpbHRlcl9CYXIiLCJhY3RpdmVfZmlsdGVycyIsInN0YXR1c19vcHRpb25zIiwiJHN0YXR1cyIsIm9wdCIsInNlYXJjaF90aW1lb3V0IiwiYWRkX2ZpbHRlciIsImFwcGx5X2ZpbHRlcnMiLCJjbGVhcl9maWx0ZXJzIiwidXBkYXRlX2ZpbHRlcl9kaXNwbGF5IiwiZGF0ZV9yYW5nZSIsInN0YXJ0X2RhdGUiLCJlbmRfZGF0ZSIsIm9uX2FwcGx5IiwiJHRhZ3MiLCIkdGFnIiwiJHJlbW92ZSIsImdldF9maWx0ZXJzIiwiRm9ybV9BY3Rpb25zX0NvbXBvbmVudCIsIm9uX2NsaWNrX2hlbGxvIiwiRm9ybV9GaWVsZF9Hcm91cCIsImNvbGxhcHNpYmxlIiwibWFrZV9jb2xsYXBzaWJsZSIsIiRoZWFkZXIiLCIkYm9keSIsImNvbGxhcHNlX2lkIiwicmFuZG9tIiwic3Vic3RyIiwiJHRvZ2dsZSIsIkZvcm1fR3JvdXBfQ29tcG9uZW50IiwiY29sX2NsYXNzIiwiRm9ybV9Sb3dfQ29tcG9uZW50IiwiRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UiLCJHYW50dF9DaGFydCIsInRhc2tzIiwibW9udGhzIiwiZ2VuZXJhdGVfbW9udGhzIiwiSWNvbl9CdXR0b24iLCJJY29uX1dpdGhfTGFiZWwiLCJJY29uX1dpdGhfVGV4dCIsIkljb24iLCJJbmZvX0JveCIsImNvbG9yIiwiSW5saW5lX0VkaXRfRmllbGQiLCJjdXJyZW50X3ZhbHVlIiwiZW50ZXJfZWRpdF9tb2RlIiwiY2FuY2VsIiwic2VsZWN0IiwiZXhpdF9lZGl0X21vZGUiLCJuZXdfdmFsdWUiLCJvbl9zYXZlIiwic2hvd19zYXZpbmciLCJ1cGRhdGVfZGlzcGxheSIsImNhdGNoIiwiZGlzcGxheSIsInBsYWNlaG9sZGVyIiwiSW5wdXRfV2l0aF9JY29uIiwib25faW5wdXQiLCJJbnB1dF9XaXRoX1ZhbGlkYXRpb24iLCJ2YWxpZGF0ZSIsInNldF92YWxpZCIsInNldF9lcnJvciIsIiRzdWNjZXNzIiwiY2xlYXJfdmFsaWRhdGlvbiIsIklucHV0IiwiS2FuYmFuX0JvYXJkIiwic2V0dXBfZHJhZ19hbmRfZHJvcCIsImRyYWdnZWRfY2FyZCIsIiRjYXJkIiwiJGNvbHVtbiIsIm9uX21vdmUiLCJjYXJkX2lkIiwiY29sdW1uX2lkIiwiTGluayIsIkxpc3QiLCJMb2FkaW5nX1NrZWxldG9uIiwibGluZXMiLCIkc3BhbiIsIk1ldHJpY19DYXJkIiwiTW9iaWxlX0hlYWRlciIsIk1vZGFsX0RpYWxvZyIsIm1vZGFsIiwiYm9vdHN0cmFwIiwiTXVsdGlfU2VsZWN0Iiwic2VsZWN0ZWRfdmFsdWVzIiwiYWxsX29wdGlvbnMiLCJyZW5kZXJfb3B0aW9ucyIsIiRzZWFyY2giLCJmaWx0ZXJfb3B0aW9ucyIsImNsZWFyX2FsbCIsInNlbGVjdF9hbGwiLCJvcHRpb24iLCJ0b2dnbGVfb3B0aW9uIiwicXVlcnkiLCJmaWx0ZXJlZCIsIiR0ZXh0IiwiZWwiLCJOb3RpZmljYXRpb25fQmFkZ2UiLCIkY291bnQiLCJOb3RpZmljYXRpb25fRHJvcGRvd24iLCJPdmVyZHVlX0luZGljYXRvciIsIlBhZ2VfSGVhZGVyIiwiUGFnZV9TZWN0aW9uIiwiUGFnZSIsIlBvcG92ZXIiLCJjb250ZW50IiwiUHJvZ3Jlc3NfQmFyIiwiJGJhciIsInNob3dfdmFsdWUiLCJSYWRpb19CdXR0b24iLCJSaWNoX1RleHRfRWRpdG9yIiwiJGVkaXRvciIsImNvbW1hbmQiLCJwcm9tcHQiLCJleGVjQ29tbWFuZCIsInBsYWluX3RleHRfcGFzdGUiLCJnZXREYXRhIiwiZ2V0X3RleHQiLCJSb3dfQWN0aW9uX01lbnUiLCJ3cmFwIiwiU2FtcGxlX0RhdGFncmlkX0NvbXBvbmVudCIsImFwaV91cmwiLCJnZW5lcmF0ZV9zYW1wbGVfZGF0YSIsInNlbGVjdGFibGUiLCJ1cGRhdGVfc2VsZWN0aW9uX2NvdW50IiwiYWxsb3dfZGVsZXRlIiwiJGJ1dHRvbiIsImNvbmZpcm1fZGVsZXRlIiwicGFnaW5hdGlvbiIsImdvX3RvX3BhZ2UiLCJjdXJyZW50X3BhZ2UiLCJzZWxlY3RlZCIsImdldF9zZWxlY3RlZF9pZHMiLCJpZHMiLCJjaGVja2JveCIsImNsZWFyX3NlbGVjdGlvbiIsImRlbGV0ZV9yb3ciLCJzdGF0dXNlcyIsImZpcnN0X25hbWVzIiwibGFzdF9uYW1lcyIsImNvbXBhbmllcyIsInNob3dpbmciLCJmaXJzdF9uYW1lIiwiZmxvb3IiLCJsYXN0X25hbWUiLCJjb21wYW55IiwicGhvbmUiLCJzdGF0dXNfY29sb3IiLCJjcmVhdGVkIiwicmFuZG9tX2RhdGUiLCJjZWlsIiwidG8iLCJwYWdlcyIsIlNlYXJjaF9CYXIiLCJTZWFyY2hhYmxlX1NlbGVjdCIsInNlbGVjdGVkX3ZhbHVlIiwic2VsZWN0ZWRfb3B0aW9uIiwiJGl0ZW0iLCJzZWxlY3Rfb3B0aW9uIiwiZHJvcGRvd24iLCJEcm9wZG93biIsImdldEluc3RhbmNlIiwiU2VsZWN0X0Ryb3Bkb3duIiwiU2lkZWJhcl9OYXYiLCIkbmF2X2l0ZW1zIiwiY3VycmVudF9wYXRoIiwiU29ydGFibGVfQ29sdW1uX0hlYWRlciIsInRvZ2dsZV9zb3J0Iiwic2V0X3NvcnQiLCJuZXh0Iiwib25fc29ydCIsImRpcmVjdGlvbiIsIiRpY29uIiwiU3Bpbm5lciIsIlN0YXRfQ2FyZCIsIlN0YXR1c19CYWRnZSIsImNvbG9yX21hcCIsImJnX2NsYXNzIiwiVGFiX0NvbnRlbnQiLCJUYWJsZV9QYWdpbmF0aW9uIiwiZ2VuZXJhdGVfcGFnaW5hdGlvbiIsIiRwYWdpbmF0aW9uIiwiJHByZXYiLCJzdGFydCIsIiRuZXh0IiwiVGFibGUiLCJ2YXJpYW50IiwiVGFicyIsIlRhZ19Hcm91cCIsIlRhZyIsIlRleHRfRGlzcGxheSIsIlRleHRhcmVhIiwiVGhyZWVfQ29sdW1uX0xheW91dCIsIlRpbWVfUGlja2VyIiwic3RlcCIsIlRpbWVsaW5lIiwiVGltZXN0YW1wX0Rpc3BsYXkiLCJUb29sdGlwIiwicGxhY2VtZW50IiwiVG9wX05hdiIsIiRuYXYiLCJUcmVuZF9JbmRpY2F0b3IiLCJpc19wb3NpdGl2ZSIsImlzX25lZ2F0aXZlIiwiVHdvX0NvbHVtbl9MYXlvdXQiLCJVc2VyX0F2YXRhcl9Ecm9wZG93biIsIk1vZGFsX0Fic3RyYWN0IiwiUnN4X01vZGFsIiwiYm9keV9jb250ZW50IiwiYnV0dG9ucyIsImNsb3NhYmxlIiwibWF4X3dpZHRoIiwiY2xvc2Vfb25fc3VibWl0IiwicmVzdWx0X3Byb21pc2UiLCJyZXNvbHZlX2ZuIiwiX2JzX21vZGFsIiwiX3Jlc2l6ZV9oYW5kbGVyIiwiY2xvc2UiLCJfYXBwbHlfc2l6aW5nIiwiaW50ZXJuYWxfb3B0aW9ucyIsInNraXBfYmFja2Ryb3AiLCJzaG91bGRfYW5pbWF0ZSIsImljb24iLCJfc2V0X2JvZHlfY29udGVudCIsIl9zZXRfYnV0dG9ucyIsIl9mYWRlX2luIiwiX2ZvY3VzX2ZpcnN0X2lucHV0IiwiJGNvbnRlbnQiLCJlc2NhcGVkIiwialF1ZXJ5IiwiJGZvb3RlciIsImJ1dHRvbl9kZWYiLCJoYWRfY2FsbGJhY2siLCJ2aWV3cG9ydF9oZWlnaHQiLCJ2aWV3cG9ydF9saW1pdCIsInByZWZlcnJlZF93aWR0aCIsImNvbnRlbnRfaGVpZ2h0IiwibWF4X2hlaWdodCIsIm9mZnNldEhlaWdodCIsIiRmaXJzdF9pbnB1dCIsIm9mZiIsImFwcGx5X2Vycm9ycyIsIl9pbml0IiwiX2luaXRpYWxpemVkIiwiX2JhY2tkcm9wIiwiX2dldF9zY3JvbGxiYXJfd2lkdGgiLCIkb3V0ZXIiLCJ2aXNpYmlsaXR5Iiwib3ZlcmZsb3ciLCJ3aWR0aF93aXRoX3Njcm9sbGJhciIsIm9mZnNldFdpZHRoIiwiJGlubmVyIiwid2lkdGhfd2l0aG91dF9zY3JvbGxiYXIiLCJfbG9ja19ib2R5X3Njcm9sbCIsIl91bmxvY2tfdGltZW91dCIsIl9vcmlnaW5hbF9ib2R5X292ZXJmbG93IiwiX29yaWdpbmFsX2JvZHlfcGFkZGluZyIsImhhc19zY3JvbGxiYXIiLCJzY3JvbGxiYXJfd2lkdGgiLCJjdXJyZW50X3BhZGRpbmciLCJfdW5sb2NrX2JvZHlfc2Nyb2xsIiwiX2N1cnJlbnQiLCJfcXVldWUiLCJfc2hvd19iYWNrZHJvcCIsIl9oaWRlX2JhY2tkcm9wIiwiX2NyZWF0ZV9tb2RhbCIsIiRtb2RhbF9lbGVtZW50IiwibW9kYWxfaW5zdGFuY2UiLCJmb290ZXIiLCJfc2hvd19tb2RhbCIsIl9wcm9jZXNzX3F1ZXVlIiwiYmFja2Ryb3BfdmlzaWJsZSIsInRpbWVfc2luY2VfbGFzdF9jbG9zZSIsIl9sYXN0X2Nsb3NlX3RpbWVzdGFtcCIsImlzX29wZW4iLCJnZXRfY3VycmVudCIsInRpdGxlX29yX2JvZHkiLCJidXR0b25fbGFiZWwiLCJkZWZhdWx0IiwiY29uZmlybV9sYWJlbCIsImNhbmNlbF9sYWJlbCIsImRlZmF1bHRfdmFsdWUiLCJtdWx0aWxpbmUiLCJkZWZhdWx0cyIsImZpbmFsX29wdGlvbnMiLCJmb3JtIiwic3VibWl0X2xhYmVsIiwiJGNvbXBvbmVudF9jb250YWluZXIiLCJjb21wb25lbnRfaW5zdGFuY2UiLCJ2YWxzIiwic3VibWl0IiwidW5jbG9zYWJsZSIsImN1c3RvbSIsImVycm9yX21lc3NhZ2VzIiwicmVvcGVuX3dpdGhfZXJyb3JzIiwiX2QxZjVhM2NiX2RlZmluZVByb3BlcnR5IiwiQnJlYWRjcnVtYl9JdGVtIiwiQ2xpZW50X0xhYmVsX0xpbmsiLCJjbGllbnQiLCJnZXRfY2xpZW50Iiwib25fcmVuZGVyIiwiQ2xpZW50X0xhYmVsIiwiRm9ybV9JbnB1dF9BYnN0cmFjdCIsInNlZWQiLCJUZXh0X0lucHV0Iiwic2VlZGVyIiwiQ2hlY2tib3hfSW5wdXQiLCJjaGVja2VkX3ZhbHVlIiwidW5jaGVja2VkX3ZhbHVlIiwiaW5wdXRfaWQiLCJpc19jaGVja2VkIiwic2hvdWxkX2NoZWNrIiwiV3lzaXd5Z19JbnB1dCIsInF1aWxsIiwiX2luaXRpYWxpemVfcXVpbGwiLCJ0aGVtZSIsIm1vZHVsZXMiLCJ0b29sYmFyIiwicm9vdCIsInNhbXBsZV9jb250ZW50IiwiU2VsZWN0X0lucHV0IiwiZGVjb2RlZCIsImFsbG93RW1wdHlPcHRpb24iLCJjcmVhdGUiLCJtYXhPcHRpb25zIiwicGx1Z2lucyIsIm9uSW5pdGlhbGl6ZSIsImNvbnRyb2wiLCJ0b21fc2VsZWN0IiwiVG9tU2VsZWN0Iiwic2V0VmFsdWUiLCJnZXRWYWx1ZSIsInJhbmRvbV9pbmRleCIsInJhbmRvbV9vcHQiLCJyYW5kb21fdmFsdWUiLCJvbl9kZXN0cm95IiwiZGVzdHJveSIsIkFqYXhfU2VsZWN0X0lucHV0Iiwic2VsZWN0X3ZhbHVlcyIsIl9wZW5kaW5nX3ZhbHVlIiwib2siLCJDdXJyZW5jeV9JbnB1dCIsImFsbG93X2RlY2ltYWxzIiwic2hvd19zeW1ib2wiLCJjdXJyZW5jeV9zeW1ib2wiLCJfZm9ybWF0X2N1cnJlbmN5IiwiaW50ZWdlcl9wYXJ0IiwiZGVjaW1hbF9wYXJ0IiwiZm9ybWF0dGVkIiwiX2dldF9udW1lcmljX3ZhbHVlIiwiY2xlYW5lZCIsImRlY2ltYWxfY291bnQiLCJmaXJzdF9kZWNpbWFsIiwicmF3IiwibnVtZXJpYyIsImlucHV0X2VsZW1lbnQiLCJjdXJzb3JfcG9zIiwic2VsZWN0aW9uU3RhcnQiLCJjdXJzb3JfZW5kIiwic2VsZWN0aW9uRW5kIiwidmFsdWVfbGVuZ3RoIiwiY2hhcl9iZWZvcmUiLCJuZXdfbnVtZXJpYyIsIm5ld19sZW5ndGgiLCJzZXRTZWxlY3Rpb25SYW5nZSIsInN5bWJvbF9vZmZzZXQiLCJuZXdfY3Vyc29yIiwiaW5pdGlhbF92YWx1ZSIsIlBob25lX1RleHRfSW5wdXQiLCJfaXNfaW50ZXJuYXRpb25hbCIsIl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUiLCJfZm9ybWF0X3VzX3Bob25lIiwiZGlnaXRzIiwic3RyX3ZhbHVlIiwiZGlnaXRzX3RvX2Zvcm1hdCIsIl9sYXN0X2N1cnNvcl9wb3NpdGlvbiIsIm5ld19kaWdpdHMiLCJTdGF0ZV9TZWxlY3RfSW5wdXQiLCJjb3VudHJ5X2NvZGUiLCJSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlciIsInN0YXRlcyIsImNvdW50cnkiLCJfc3RhdGVfY2FjaGUiLCJpc19uYSIsImRpc2FibGUiLCJzZXRfY291bnRyeV9jb2RlIiwiY3VycmVudF9jb3VudHJ5IiwicmVkcmF3IiwiY2FjaGVkX3ZhbHVlIiwidmFsdWVfZXhpc3RzIiwiZW5hYmxlIiwiQ291bnRyeV9TZWxlY3RfSW5wdXQiLCJjb3VudHJpZXMiLCJkZWZhdWx0X2NvdW50cnkiLCJkZWZhdWx0X2NvdW50cnlfY29kZSIsImRlZmF1bHRfY291bnRyeV9pbmRleCIsImZpbmRJbmRleCIsInVuc2hpZnQiLCJfdXBkYXRlX3N0YXRlX3NlbGVjdG9yIiwic3RhdGVfY29tcG9uZW50IiwiUHJvZmlsZV9QaG90b19JbnB1dCIsImF0dGFjaG1lbnRfa2V5IiwidGh1bWJuYWlsX3VybCIsInVwbG9hZF9waG90byIsInNob3dfcmVtb3ZlIiwicmVtb3ZlX3Bob3RvIiwibWF4X3NpemUiLCJwcm9jZXNzRGF0YSIsImNvbnRlbnRUeXBlIiwiYXR0YWNobWVudCIsIl94aHIkcmVzcG9uc2VKU09OIiwidXBkYXRlX3Bob3RvIiwiUnN4X1RhYnMiLCJ0YWJzIiwiYWN0aXZlX3RhYl9pZCIsIl9idWlsZF9uYXYiLCJ0YWJfaWQiLCJhY3RpdmF0ZV90YWIiLCJyZWdpc3Rlcl90YWIiLCJ0YWJfY29tcG9uZW50IiwidGFiIiwiaXNfYWN0aXZlIiwidCIsImhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyIsInRhYl9lcnJvcnMiLCJlcnJvcl9jb3VudCIsImNvdW50X2Vycm9ycyIsIiRiYWRnZSIsImZpcnN0X2Vycm9yZWRfdGFiIiwiY2xlYXJfZXJyb3JfYmFkZ2VzIiwiUnN4X1RhYiIsInRhYnNfY29udGFpbmVyIiwiZmllbGRzIiwiZWxlbWVudCIsImZpZWxkX2NvbXBvbmVudCIsIlJzeF9Gb3JtIiwidGFic19lbCIsInNoYWxsb3dGaW5kIiwiJHdpZGdldCIsIndpZGdldF9uYW1lIiwiZ2V0X2Vycm9yIiwiYWpheF91cmwiLCJQaW5fVmVyaWZpY2F0aW9uX0Zvcm0iLCJwaW5fbGVuZ3RoIiwicGluIiwiZmlyc3RfZW1wdHkiLCJfZmluZF9maXJzdF9lbXB0eV9pbmRleCIsIl9mb2N1c19pbnB1dCIsIl9oYW5kbGVfcGFzdGUiLCJzdGFydF9pbmRleCIsInBhc3RlIiwibmV4dF9pbmRleCIsIkZvcm1fRmllbGRfQWJzdHJhY3QiLCJoYXNfZXJyb3IiLCJ3aWRnZXRfY29tcG9uZW50IiwiRm9ybV9GaWVsZCIsIkZvcm1fSGlkZGVuX0ZpZWxkIiwiRnJvbnRlbmRfRGFzaGJvYXJkIiwiaW5pdCIsInRvb2x0aXAiLCJvbl9hcHBfcmVhZHkiLCJDbGllbnRzX0RhdGFHcmlkIiwiRnJvbnRlbmRfQ2xpZW50c19FZGl0IiwidGFnX2h0bWwiLCJGcm9udGVuZF9DbGllbnRzX1ZpZXciLCJjb25maXJtZWQiLCJyZWxvYWQiLCJyZXN0b3JlIiwiRnJvbnRlbmRfQ2xpZW50cyIsIkZyb250ZW5kX1NldHRpbmdzX1RlYW0iLCJGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zIiwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZyIsIkZyb250ZW5kX1NldHRpbmdzX0ltcG9ydCIsIkZyb250ZW5kX1NldHRpbmdzX0FwaSIsIkZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlcyIsIkZyb250ZW5kX1NldHRpbmdzX0F1ZGl0IiwiRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5IiwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5ncyIsIkZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5IiwiRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXMiLCJVc2Vyc19EYXRhR3JpZCIsIkFkZF9Vc2VyX0Zvcm0iLCJBZGRfVXNlcl9Nb2RhbCIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyIiwiYWRkX3VzZXIiLCJTZW5kX1VzZXJfSW52aXRlX01vZGFsIiwidXNlcl9pZCIsInNlbmRfaW52aXRlIiwiaW52aXRlX3VybCIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudCIsImhhbmRsZV9hZGRfdXNlciIsInVzZXIiLCJFZGl0X1VzZXJfTW9kYWwiLCJ1c2VyX2RhdGEiLCJnZXRfdXNlcl9mb3JfZWRpdCIsInNhdmVfdXNlciIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9WaWV3IiwiaGFuZGxlX2VkaXRfdXNlciIsImhhbmRsZV9yZXNlbmRfaW52aXRlIiwiX3dpbmRvdyRyc3hhcHAkcGFnZV9kIiwicGFnZV9kYXRhIiwiX3dpbmRvdyRyc3hhcHAkcGFnZV9kMiIsIkZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3MiLCJGcm9udGVuZF9TZXR0aW5ncyIsInNlY3Rpb24iLCJmb3JtRGF0YSIsInByZXBlbmQiLCJvcmlnaW5hbFRleHQiLCJDb250YWN0c19EYXRhR3JpZCIsIkRhdGFfVGFibGUiLCJmZXRjaF9kYXRhIiwiYnVpbGRfaGVhZGVycyIsInNlYXJjaGFibGUiLCJzZXR1cF9zZWFyY2giLCJjb2x1bW5fdG9nZ2xlIiwic2V0dXBfY29sdW1uX3RvZ2dsZSIsImJ1bGtfYWN0aW9ucyIsInNldHVwX2J1bGtfYWN0aW9ucyIsInVwZGF0ZV9idWxrX3NlbGVjdGlvbiIsInBhZ2VfdGV4dCIsIiRoZWFkZXJfcm93IiwiY29sIiwic29ydGFibGUiLCIkc29ydGFibGUiLCJoYW5kbGVfc29ydCIsInJvd19hY3Rpb25zIiwidGltZW91dCIsInNlYXJjaF9xdWVyeSIsInRvZ2dsZV9jb21wb25lbnQiLCIkYnVsa19zZWxlY3Rpb24iLCIkYnVsa19iYXIiLCJzb3J0X2ZpZWxkIiwic29ydF9kaXJlY3Rpb24iLCJzZWFyY2hQYXJhbXMiLCJDbGllbnRfU2VsZWN0b3JfSW5wdXQiLCJnZXRfY2xpZW50cyIsIkZyb250ZW5kX0NvbnRhY3RzX0VkaXQiLCJGcm9udGVuZF9Db250YWN0c19WaWV3IiwiRnJvbnRlbmRfQ29udGFjdHMiLCJQcm9qZWN0c19EYXRhR3JpZCIsIkZyb250ZW5kX1Byb2plY3RzX0VkaXQiLCJGcm9udGVuZF9Qcm9qZWN0c19MaXN0IiwiRnJvbnRlbmRfUHJvamVjdHNfVmlldyIsIkZyb250ZW5kX1Byb2plY3RzX0FkZCIsIkZyb250ZW5kX1Byb2plY3RzIiwiRnJvbnRlbmRfVGFza3MiLCJGcm9udGVuZF9UYXNrc19WaWV3IiwiRnJvbnRlbmRfVGFza3NfQWRkIiwiRnJvbnRlbmRfQ2FsZW5kYXIiLCJGcm9udGVuZF9DYWxlbmRhcl9FdmVudCIsIkZyb250ZW5kX0ludm9pY2VzIiwiRnJvbnRlbmRfSW52b2ljZXNfVmlldyIsIkZyb250ZW5kX0ludm9pY2VzX0FkZCIsImFkZF9saW5lX2l0ZW0iLCJjYWxjdWxhdGVfdG90YWxzIiwiYXR0YWNoX2xpbmVfaXRlbV9oYW5kbGVycyIsInVwZGF0ZV9saW5lX2l0ZW1fYW1vdW50IiwibGluZV9pdGVtX2NvdW50IiwicXVhbnRpdHkiLCJyYXRlIiwiYW1vdW50Iiwic3VidG90YWwiLCJ0YXhfcmF0ZSIsInRheF9hbW91bnQiLCJfNzJlYWI1MTRfZGVmaW5lUHJvcGVydHkiLCJGcm9udGVuZF9SZXBvcnRzIiwiRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlIiwiRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzIiwiRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cyIsIkZyb250ZW5kX1JlcG9ydHNfVGltZSIsIkZyb250ZW5kX0FjY291bnQiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOzs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLFNBQVNBLENBQUNDLEtBQUssRUFBRTtFQUN0QixPQUFPQSxLQUFLO0FBQ2hCOzs7Ozs7QUN4QkE7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN2TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3BTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMUJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMUtBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMvQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNUQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNOQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3BDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3pFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMU1BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNaQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ05BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNYQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNwQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDaERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMzQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDZkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2pCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3RCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3ZCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNYQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDdk5BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1RBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1RBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNWQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNaQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzlVQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNsQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDckJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN0QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN4QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDNURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzlCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3ZDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN4QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbkNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDdERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM1QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3hDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDM0NBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMzQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5RkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDNURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN2RkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5REE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMUZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcEZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2hDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRyIsImZpbGUiOiJidW5kbGVfb3V0cHV0X0Zyb250ZW5kX0J1bmRsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIndpbmRvdy5yc3hhcHAgPSB3aW5kb3cucnN4YXBwIHx8IHt9O1xud2luZG93LnJzeGFwcC5tb2R1bGVfcGF0aHMgPSB7XCJib290c3RyYXA1X3NyY1wiOlwicnN4XFwvdGhlbWVcXC92ZW5kb3JcXC9ib290c3RyYXA1XFwvc2Nzc1wifTtcbiIsIi8vIE5QTSBJbXBvcnQgRGVjbGFyYXRpb25zIGZvciBBcHAgQnVuZGxlXG4vLyBBdXRvLWdlbmVyYXRlZCB0byBwcm92aWRlIE5QTSBtb2R1bGVzIHRvIGFwcCBidW5kbGUgc2NvcGVcbi8vIENhY2hlIGtleTogOTVhNmY2MDJjOTgwMzc2MTFiNjQwYjBiNTM0MjgzMGJcblxuY29uc3QganFodG1sID0gd2luZG93Ll9yc3hfbnBtLmpxaHRtbDtcbmlmICghanFodG1sKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnUlNYIEZyYW1ld29yayBFcnJvcjogTlBNIG1vZHVsZSBcImpxaHRtbFwiIG5vdCBmb3VuZC5cXG4nICtcbiAgICAgICAgJ0V4cGVjdGVkIHdpbmRvdy5fcnN4X25wbS5qcWh0bWwgdG8gYmUgZGVmaW5lZCBieSB0aGUgdmVuZG9yIGJ1bmRsZS4nXG4gICAgKTtcbn1cblxuY29uc3QgX0Jhc2VfSnFodG1sX0NvbXBvbmVudCA9IHdpbmRvdy5fcnN4X25wbS5fQmFzZV9KcWh0bWxfQ29tcG9uZW50O1xuaWYgKCFfQmFzZV9KcWh0bWxfQ29tcG9uZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnUlNYIEZyYW1ld29yayBFcnJvcjogTlBNIG1vZHVsZSBcIl9CYXNlX0pxaHRtbF9Db21wb25lbnRcIiBub3QgZm91bmQuXFxuJyArXG4gICAgICAgICdFeHBlY3RlZCB3aW5kb3cuX3JzeF9ucG0uX0Jhc2VfSnFodG1sX0NvbXBvbmVudCB0byBiZSBkZWZpbmVkIGJ5IHRoZSB2ZW5kb3IgYnVuZGxlLidcbiAgICApO1xufVxuXG4vLyBDbGVhbiB1cCBOUE0gY29udGFpbmVyIHRvIHByZXZlbnQgY29uc29sZSBhY2Nlc3NcbmRlbGV0ZSB3aW5kb3cuX3JzeF9ucG07XG4iLCIvKipcbiAqIERlY29yYXRvciBmdW5jdGlvbiB0aGF0IG1hcmtzIGEgZnVuY3Rpb24gYXMgYSBkZWNvcmF0b3IgaW1wbGVtZW50YXRpb24uXG4gKlxuICogV2hlbiBhIGZ1bmN0aW9uIGhhcyBAZGVjb3JhdG9yIGluIGl0cyBKU0RvYyBjb21tZW50LCBpdCB3aGl0ZWxpc3RzIHRoYXQgZnVuY3Rpb25cbiAqIHRvIGJlIHVzZWQgYXMgYSBkZWNvcmF0b3Igb24gb3RoZXIgbWV0aG9kcyB0aHJvdWdob3V0IHRoZSBjb2RlYmFzZS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gaXRzZWxmIHBlcmZvcm1zIG5vIG9wZXJhdGlvbiAtIGl0IHNpbXBseSByZXR1cm5zIGl0cyBpbnB1dCB1bmNoYW5nZWQuXG4gKiBJdHMgcHVycG9zZSBpcyBwdXJlbHkgYXMgYSBtYXJrZXIgZm9yIHRoZSBtYW5pZmVzdCB2YWxpZGF0aW9uIHN5c3RlbS5cbiAqXG4gKiBVc2FnZTpcbiAqICAgLy8gLyoqXG4gKiAgIC8vICAqIE15IGN1c3RvbSBkZWNvcmF0b3IgaW1wbGVtZW50YXRpb25cbiAqICAgLy8gICogQGRlY29yYXRvclxuICogICAvLyAgKlxcL1xuICogICBmdW5jdGlvbiBteV9jdXN0b21fZGVjb3JhdG9yKHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKSB7XG4gKiAgICAgICAvLyBEZWNvcmF0b3IgaW1wbGVtZW50YXRpb25cbiAqICAgfVxuICpcbiAqIFRoaXMgYWxsb3dzIG15X2N1c3RvbV9kZWNvcmF0b3IgdG8gYmUgdXNlZCBhcyBAbXlfY3VzdG9tX2RlY29yYXRvciBvbiBzdGF0aWMgbWV0aG9kcy5cbiAqXG4gKiBUT0RPOiBUaGlzIGlzIHByb2JhYmx5IG5vIGxvbmdlciBuZWNlc3Nhcnk/IG1heWJlP1xuICovXG5mdW5jdGlvbiBkZWNvcmF0b3IodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG59XG4iLCIvKlxuICogQnJvd3NlciBhbmQgRE9NIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB0aGUgUlNwYWRlIGZyYW1ld29yay5cbiAqIFRoZXNlIGZ1bmN0aW9ucyBoYW5kbGUgYnJvd3NlciBkZXRlY3Rpb24sIHZpZXdwb3J0IHV0aWxpdGllcywgYW5kIERPTSBtYW5pcHVsYXRpb24uXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQlJPV1NFUiBERVRFQ1RJT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBEZXRlY3RzIGlmIHVzZXIgaXMgb24gYSBtb2JpbGUgZGV2aWNlIG9yIHVzaW5nIG1vYmlsZSB2aWV3cG9ydFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgbW9iaWxlIGRldmljZSBvciB2aWV3cG9ydCA8IDk5MnB4XG4gKiBAdG9kbyBJbXByb3ZlIHVzZXIgYWdlbnQgZGV0ZWN0aW9uIGZvciBhbGwgbW9iaWxlIGRldmljZXNcbiAqL1xuZnVuY3Rpb24gaXNfbW9iaWxlKCkge1xuICAgIGlmICgvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBhZHxpUG9kfEJsYWNrQmVycnl8SUVNb2JpbGV8T3BlcmEgTWluaS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICgkKHdpbmRvdykud2lkdGgoKSA8IDk5Mikge1xuICAgICAgICAvLyA5OTJweCA9IGJvb3RzdHJhcCA0IGNvbC1tZC1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlY3RzIGlmIHVzZXIgaXMgb24gZGVza3RvcCAobm90IG1vYmlsZSlcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG5vdCBtb2JpbGUgZGV2aWNlL3ZpZXdwb3J0XG4gKi9cbmZ1bmN0aW9uIGlzX2Rlc2t0b3AoKSB7XG4gICAgcmV0dXJuICFpc19tb2JpbGUoKTtcbn1cblxuLyoqXG4gKiBEZXRlY3RzIHRoZSB1c2VyJ3Mgb3BlcmF0aW5nIHN5c3RlbVxuICogQHJldHVybnMge3N0cmluZ30gT1MgbmFtZTogJ01hYyBPUycsICdpUGhvbmUnLCAnaVBhZCcsICdXaW5kb3dzJywgJ0FuZHJvaWQtUGhvbmUnLCAnQW5kcm9pZC1UYWJsZXQnLCAnTGludXgnLCBvciAnVW5rbm93bidcbiAqL1xuZnVuY3Rpb24gZ2V0X29zKCkge1xuICAgIGxldCB1c2VyX2FnZW50ID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgIHBsYXRmb3JtID0gd2luZG93Lm5hdmlnYXRvci5wbGF0Zm9ybSxcbiAgICAgICAgbWFjb3NfcGxhdGZvcm1zID0gWydNYWNpbnRvc2gnLCAnTWFjSW50ZWwnLCAnTWFjUFBDJywgJ01hYzY4SyddLFxuICAgICAgICB3aW5kb3dzX3BsYXRmb3JtcyA9IFsnV2luMzInLCAnV2luNjQnLCAnV2luZG93cycsICdXaW5DRSddLFxuICAgICAgICBpb3NfcGxhdGZvcm1zID0gWydpUGhvbmUnLCAnaVBhZCcsICdpUG9kJ10sXG4gICAgICAgIG9zID0gbnVsbDtcblxuICAgIGxldCBpc19tb2JpbGVfZGV2aWNlID0gaXNfbW9iaWxlKCk7XG5cbiAgICBpZiAobWFjb3NfcGxhdGZvcm1zLmluZGV4T2YocGxhdGZvcm0pICE9PSAtMSkge1xuICAgICAgICBvcyA9ICdNYWMgT1MnO1xuICAgIH0gZWxzZSBpZiAoaW9zX3BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEgJiYgaXNfbW9iaWxlX2RldmljZSkge1xuICAgICAgICBvcyA9ICdpUGhvbmUnO1xuICAgIH0gZWxzZSBpZiAoaW9zX3BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEgJiYgIWlzX21vYmlsZV9kZXZpY2UpIHtcbiAgICAgICAgb3MgPSAnaVBhZCc7XG4gICAgfSBlbHNlIGlmICh3aW5kb3dzX3BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEpIHtcbiAgICAgICAgb3MgPSAnV2luZG93cyc7XG4gICAgfSBlbHNlIGlmICgvQW5kcm9pZC8udGVzdCh1c2VyX2FnZW50KSAmJiBpc19tb2JpbGVfZGV2aWNlKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQtUGhvbmUnO1xuICAgIH0gZWxzZSBpZiAoL0FuZHJvaWQvLnRlc3QodXNlcl9hZ2VudCkgJiYgIWlzX21vYmlsZV9kZXZpY2UpIHtcbiAgICAgICAgb3MgPSAnQW5kcm9pZC1UYWJsZXQnO1xuICAgIH0gZWxzZSBpZiAoIW9zICYmIC9MaW51eC8udGVzdChwbGF0Zm9ybSkpIHtcbiAgICAgICAgb3MgPSAnTGludXgnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG9zID0gJ1Vua25vd24nO1xuICAgIH1cblxuICAgIHJldHVybiBvcztcbn1cblxuLyoqXG4gKiBEZXRlY3RzIGlmIHRoZSB1c2VyIGFnZW50IGlzIGEgd2ViIGNyYXdsZXIvYm90XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB1c2VyIGFnZW50IGFwcGVhcnMgdG8gYmUgYSBib3QvY3Jhd2xlclxuICovXG5mdW5jdGlvbiBpc19jcmF3bGVyKCkge1xuICAgIGxldCB1c2VyX2FnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICBsZXQgYm90X3BhdHRlcm4gPSAvYm90fHNwaWRlcnxjcmF3bHxzbHVycHxhcmNoaXZlcnxwaW5nfHNlYXJjaHxkaWd8dHJhY2tlcnxtb25pdG9yfHNub29weXx5YWhvb3xiYWlkdXxtc258YXNrfHRlb21hfGF4aW9zL2k7XG5cbiAgICByZXR1cm4gYm90X3BhdHRlcm4udGVzdCh1c2VyX2FnZW50KTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRE9NIFNDUk9MTElORyBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBTY3JvbGxzIHBhcmVudCBjb250YWluZXIgdG8gbWFrZSB0YXJnZXQgZWxlbWVudCB2aXNpYmxlIGlmIG5lZWRlZFxuICogQHBhcmFtIHtzdHJpbmd8SFRNTEVsZW1lbnR8alF1ZXJ5fSB0YXJnZXQgLSBUYXJnZXQgZWxlbWVudCB0byBzY3JvbGwgaW50byB2aWV3XG4gKi9cbmZ1bmN0aW9uIHNjcm9sbF9pbnRvX3ZpZXdfaWZfbmVlZGVkKHRhcmdldCkge1xuICAgIGNvbnN0ICR0YXJnZXQgPSAkKHRhcmdldCk7XG5cbiAgICAvLyBGaW5kIHRoZSBjbG9zZXN0IHBhcmVudCB3aXRoIG92ZXJmbG93LXk6IGF1dG9cbiAgICBjb25zdCAkcGFyZW50ID0gJHRhcmdldC5wYXJlbnQoKTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgYWJzb2x1dGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXRcbiAgICBjb25zdCB0YXJnZXRfdG9wID0gJHRhcmdldC5wb3NpdGlvbigpLnRvcCArICRwYXJlbnQuc2Nyb2xsVG9wKCk7XG5cbiAgICBjb25zdCB0YXJnZXRfaGVpZ2h0ID0gJHRhcmdldC5vdXRlckhlaWdodCgpO1xuICAgIGNvbnN0IHBhcmVudF9oZWlnaHQgPSAkcGFyZW50LmhlaWdodCgpO1xuICAgIGNvbnN0IHNjcm9sbF9wb3NpdGlvbiA9ICRwYXJlbnQuc2Nyb2xsVG9wKCk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdGFyZ2V0IGlzIG91dCBvZiB2aWV3XG4gICAgaWYgKHRhcmdldF90b3AgPCBzY3JvbGxfcG9zaXRpb24gfHwgdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgPiBzY3JvbGxfcG9zaXRpb24gKyBwYXJlbnRfaGVpZ2h0KSB7XG4gICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoJ1VJJywgJ1Njcm9sbGluZyEnLCB0YXJnZXRfdG9wKTtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG5ldyBzY3JvbGwgcG9zaXRpb24gdG8gY2VudGVyIHRoZSB0YXJnZXRcbiAgICAgICAgbGV0IG5ld19zY3JvbGxfcG9zaXRpb24gPSB0YXJnZXRfdG9wICsgdGFyZ2V0X2hlaWdodCAvIDIgLSBwYXJlbnRfaGVpZ2h0IC8gMjtcblxuICAgICAgICAvLyBMaW1pdCB0aGUgc2Nyb2xsIHBvc2l0aW9uIGJldHdlZW4gMCBhbmQgdGhlIG1heGltdW0gc2Nyb2xsYWJsZSBoZWlnaHRcbiAgICAgICAgbmV3X3Njcm9sbF9wb3NpdGlvbiA9IE1hdGgubWF4KDAsIE1hdGgubWluKG5ld19zY3JvbGxfcG9zaXRpb24sICRwYXJlbnRbMF0uc2Nyb2xsSGVpZ2h0IC0gcGFyZW50X2hlaWdodCkpO1xuXG4gICAgICAgIC8vIFNjcm9sbCB0aGUgcGFyZW50IHRvIHRoZSBuZXcgc2Nyb2xsIHBvc2l0aW9uXG4gICAgICAgICRwYXJlbnQuc2Nyb2xsVG9wKG5ld19zY3JvbGxfcG9zaXRpb24pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBTY3JvbGxzIHBhZ2UgdG8gbWFrZSB0YXJnZXQgZWxlbWVudCB2aXNpYmxlIGlmIG5lZWRlZCAod2l0aCBhbmltYXRpb24pXG4gKiBAcGFyYW0ge3N0cmluZ3xIVE1MRWxlbWVudHxqUXVlcnl9IHRhcmdldCAtIFRhcmdldCBlbGVtZW50IHRvIHNjcm9sbCBpbnRvIHZpZXdcbiAqL1xuZnVuY3Rpb24gc2Nyb2xsX3BhZ2VfaW50b192aWV3X2lmX25lZWRlZCh0YXJnZXQpIHtcbiAgICBjb25zdCAkdGFyZ2V0ID0gJCh0YXJnZXQpO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBhYnNvbHV0ZSB0b3AgcG9zaXRpb24gb2YgdGhlIHRhcmdldCByZWxhdGl2ZSB0byB0aGUgZG9jdW1lbnRcbiAgICBjb25zdCB0YXJnZXRfdG9wID0gJHRhcmdldC5vZmZzZXQoKS50b3A7XG5cbiAgICBjb25zdCB0YXJnZXRfaGVpZ2h0ID0gJHRhcmdldC5vdXRlckhlaWdodCgpO1xuICAgIGNvbnN0IHdpbmRvd19oZWlnaHQgPSAkKHdpbmRvdykuaGVpZ2h0KCk7XG4gICAgY29uc3Qgd2luZG93X3Njcm9sbF9wb3NpdGlvbiA9ICQod2luZG93KS5zY3JvbGxUb3AoKTtcblxuICAgIC8vIENoZWNrIGlmIHRoZSB0YXJnZXQgaXMgb3V0IG9mIHZpZXdcbiAgICBpZiAodGFyZ2V0X3RvcCA8IHdpbmRvd19zY3JvbGxfcG9zaXRpb24gfHwgdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgPiB3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uICsgd2luZG93X2hlaWdodCkge1xuICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdVSScsICdTY3JvbGxpbmchJywgdGFyZ2V0X3RvcCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuZXcgc2Nyb2xsIHBvc2l0aW9uIHRvIGNlbnRlciB0aGUgdGFyZ2V0XG4gICAgICAgIGNvbnN0IG5ld19zY3JvbGxfcG9zaXRpb24gPSB0YXJnZXRfdG9wICsgdGFyZ2V0X2hlaWdodCAvIDIgLSB3aW5kb3dfaGVpZ2h0IC8gMjtcblxuICAgICAgICAvLyBBbmltYXRlIHRoZSBzY3JvbGwgdG8gdGhlIG5ldyBwb3NpdGlvblxuICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBzY3JvbGxUb3A6IG5ld19zY3JvbGxfcG9zaXRpb24sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgMTAwMFxuICAgICAgICApOyAvLyBkdXJhdGlvbiBvZiB0aGUgc2Nyb2xsIGFuaW1hdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERPTSBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIGltYWdlcyBvbiB0aGUgcGFnZSB0byBsb2FkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBhbGwgaW1hZ2VzIGFyZSBsb2FkZWRcbiAqL1xuZnVuY3Rpb24gd2FpdF9mb3JfaW1hZ2VzKGNhbGxiYWNrKSB7XG4gICAgY29uc3QgJGltYWdlcyA9ICQoJ2ltZycpOyAvLyBHZXQgYWxsIGltZyB0YWdzXG4gICAgY29uc3QgdG90YWxfaW1hZ2VzID0gJGltYWdlcy5sZW5ndGg7XG4gICAgbGV0IGltYWdlc19sb2FkZWQgPSAwO1xuXG4gICAgaWYgKHRvdGFsX2ltYWdlcyA9PT0gMCkge1xuICAgICAgICBjYWxsYmFjaygpOyAvLyBpZiB0aGVyZSBhcmUgbm8gaW1hZ2VzLCBpbW1lZGlhdGVseSBjYWxsIHRoZSBjYWxsYmFja1xuICAgIH1cblxuICAgICRpbWFnZXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaW1hZ2VzX2xvYWRlZCsrO1xuICAgICAgICAgICAgaWYgKGltYWdlc19sb2FkZWQgPT09IHRvdGFsX2ltYWdlcykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7IC8vIGNhbGwgdGhlIGNhbGxiYWNrIHdoZW4gYWxsIGltYWdlcyBhcmUgbG9hZGVkXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGltZy5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaW1hZ2VzX2xvYWRlZCsrO1xuICAgICAgICAgICAgaWYgKGltYWdlc19sb2FkZWQgPT09IHRvdGFsX2ltYWdlcykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7IC8vIGFsc28gY2FsbCB0aGUgY2FsbGJhY2sgaWYgYW4gaW1hZ2UgZmFpbHMgdG8gbG9hZFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpbWcuc3JjID0gdGhpcy5zcmM7IC8vIHRoaXMgdHJpZ2dlcnMgdGhlIGxvYWRpbmdcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgalF1ZXJ5IGVsZW1lbnQgY29udGFpbmluZyBhIG5vbi1icmVha2luZyBzcGFjZVxuICogQHJldHVybnMge2pRdWVyeX0galF1ZXJ5IHNwYW4gZWxlbWVudCB3aXRoICZuYnNwO1xuICovXG5mdW5jdGlvbiAkbmJzcCgpIHtcbiAgICByZXR1cm4gJCgnPHNwYW4+Jm5ic3A7PC9zcGFuPicpO1xufVxuXG4vKipcbiAqIEVzY2FwZXMgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIGEgalF1ZXJ5IHNlbGVjdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBFbGVtZW50IElEIHRvIGVzY2FwZVxuICogQHJldHVybnMge3N0cmluZ30galF1ZXJ5IHNlbGVjdG9yIHN0cmluZyB3aXRoIGVzY2FwZWQgc3BlY2lhbCBjaGFyYWN0ZXJzXG4gKiBAd2FybmluZyBOb3Qgc2FmZSBmb3Igc2VjdXJpdHktY3JpdGljYWwgb3BlcmF0aW9uc1xuICovXG5mdW5jdGlvbiBlc2NhcGVfanFfc2VsZWN0b3IoaWQpIHtcbiAgICByZXR1cm4gJyMnICsgaWQucmVwbGFjZSgvKDp8XFwufFxcW3xcXF18LHw9fEApL2csICdcXFxcJDEnKTtcbn0iLCIvKlxuICogRGF0ZSBhbmQgdGltZSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIGRhdGUvdGltZSBjb252ZXJzaW9ucyBhbmQgVW5peCB0aW1lc3RhbXBzLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERBVEUvVElNRSBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBHZXRzIHRoZSBjdXJyZW50IFVuaXggdGltZXN0YW1wIChzZWNvbmRzIHNpbmNlIGVwb2NoKVxuICogQHJldHVybnMge251bWJlcn0gQ3VycmVudCBVbml4IHRpbWVzdGFtcCBpbiBzZWNvbmRzXG4gKiBAdG9kbyBDYWxjdWxhdGUgYmFzZWQgb24gc2VydmVyIHRpbWUgYXQgcGFnZSByZW5kZXJcbiAqIEB0b2RvIE1vdmUgdG8gYSBkYXRlIGxpYnJhcnlcbiAqL1xuZnVuY3Rpb24gdW5peF90aW1lKCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBkYXRlIHN0cmluZyB0byBVbml4IHRpbWVzdGFtcFxuICogQHBhcmFtIHtzdHJpbmd9IHN0cl9kYXRlIC0gRGF0ZSBzdHJpbmcgKFktbS1kIEg6aTpzIGZvcm1hdClcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFVuaXggdGltZXN0YW1wIGluIHNlY29uZHNcbiAqL1xuZnVuY3Rpb24geW1kaGlzX3RvX3VuaXgoc3RyX2RhdGUpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoc3RyX2RhdGUpO1xuICAgIHJldHVybiBkYXRlLmdldFRpbWUoKSAvIDEwMDA7XG59IiwiLypcbiAqIEVycm9yIGhhbmRsaW5nIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB0aGUgUlNwYWRlIGZyYW1ld29yay5cbiAqIFRoZXNlIGZ1bmN0aW9ucyBoYW5kbGUgZXJyb3IgY3JlYXRpb24gYW5kIGRlYnVnZ2luZyB1dGlsaXRpZXMuXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRVJST1IgSEFORExJTkdcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGVycm9yIG9iamVjdCBmcm9tIGEgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IHN0ciAtIEVycm9yIG1lc3NhZ2Ugb3IgZXhpc3RpbmcgZXJyb3Igb2JqZWN0XG4gKiBAcGFyYW0ge251bWJlcn0gW2Vycm9yX2NvZGVdIC0gT3B0aW9uYWwgZXJyb3Igc3RhdHVzIGNvZGVcbiAqIEByZXR1cm5zIHtPYmplY3R9IEVycm9yIG9iamVjdCB3aXRoIGVycm9yIGFuZCBzdGF0dXMgcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBlcnJvcihzdHIsIGVycm9yX2NvZGUpIHtcbiAgICBpZiAodHlwZW9mIHN0ci5lcnJvciAhPSB1bmRlZikge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3JfY29kZSA9PSB1bmRlZikge1xuICAgICAgICAgICAgcmV0dXJuIHsgZXJyb3I6IHN0ciwgc3RhdHVzOiBudWxsIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4geyBlcnJvcjogc3RyLCBzdGF0dXM6IGVycm9yX2NvZGUgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBTYW5pdHkgY2hlY2sgZmFpbHVyZSBoYW5kbGVyIGZvciBKYXZhU2NyaXB0XG4gKlxuICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYSBzYW5pdHkgY2hlY2sgZmFpbHMgLSBpLmUuLCB3aGVuIHRoZSBjb2RlXG4gKiBlbmNvdW50ZXJzIGEgY29uZGl0aW9uIHRoYXQgXCJzaG91bGRuJ3QgaGFwcGVuXCIgaWYgZXZlcnl0aGluZyBpcyB3b3JraW5nIGNvcnJlY3RseS5cbiAqXG4gKiBVbmxpa2UgUEhQLCB3ZSBjYW4ndCBzdG9wIEphdmFTY3JpcHQgZXhlY3V0aW9uLCBidXQgd2UgY2FuOlxuICogMS4gVGhyb3cgYW4gZXJyb3IgdGhhdCB3aWxsIGJlIGNhdWdodCBieSBlcnJvciBoYW5kbGVyc1xuICogMi4gTG9nIGEgY2xlYXIgZXJyb3IgdG8gdGhlIGNvbnNvbGVcbiAqIDMuIFByb3ZpZGUgc3RhY2sgdHJhY2UgZm9yIGRlYnVnZ2luZ1xuICpcbiAqIFVzZSB0aGlzIGluc3RlYWQgb2Ygc2lsZW50bHkgcmV0dXJuaW5nIG9yIGNvbnRpbnVpbmcgd2hlbiBlbmNvdW50ZXJpbmcgdW5leHBlY3RlZCBjb25kaXRpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIE9wdGlvbmFsIHNwZWNpZmljIG1lc3NhZ2UgYWJvdXQgd2hhdCBzaG91bGRuJ3QgaGF2ZSBoYXBwZW5lZFxuICogQHRocm93cyB7RXJyb3J9IEFsd2F5cyB0aHJvd3Mgd2l0aCBsb2NhdGlvbiBhbmQgY29udGV4dCBpbmZvcm1hdGlvblxuICovXG5mdW5jdGlvbiBzaG91bGRudF9oYXBwZW4obWVzc2FnZSA9IG51bGwpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGNvbnN0IHN0YWNrID0gZXJyb3Iuc3RhY2sgfHwgJyc7XG4gICAgY29uc3Qgc3RhY2tMaW5lcyA9IHN0YWNrLnNwbGl0KCdcXG4nKTtcblxuICAgIC8vIEdldCB0aGUgY2FsbGVyIGxvY2F0aW9uIChza2lwIHRoZSBFcnJvciBsaW5lIGFuZCB0aGlzIGZ1bmN0aW9uKVxuICAgIGxldCBjYWxsZXJJbmZvID0gJ3Vua25vd24gbG9jYXRpb24nO1xuICAgIGlmIChzdGFja0xpbmVzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgY29uc3QgY2FsbGVyTGluZSA9IHN0YWNrTGluZXNbMl0gfHwgc3RhY2tMaW5lc1sxXSB8fCAnJztcbiAgICAgICAgLy8gRXh0cmFjdCBmaWxlIGFuZCBsaW5lIG51bWJlciBmcm9tIHN0YWNrIHRyYWNlXG4gICAgICAgIGNvbnN0IG1hdGNoID0gY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrLio/XFxzK1xcKCguKj8pOihcXGQrKTooXFxkKylcXCkvKSB8fCBjYWxsZXJMaW5lLm1hdGNoKC9hdFxccysoLio/KTooXFxkKyk6KFxcZCspLyk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgY2FsbGVySW5mbyA9IGAke21hdGNoWzFdfToke21hdGNoWzJdfWA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gYEZhdGFsOiBzaG91bGRudF9oYXBwZW4oKSB3YXMgY2FsbGVkIGF0ICR7Y2FsbGVySW5mb31cXG5gO1xuICAgIGVycm9yTWVzc2FnZSArPSAnVGhpcyBpbmRpY2F0ZXMgYSBzYW5pdHkgY2hlY2sgZmFpbGVkIC0gdGhlIGNvZGUgaXMgbm90IGJlaGF2aW5nIGFzIGV4cGVjdGVkLlxcbic7XG5cbiAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICBlcnJvck1lc3NhZ2UgKz0gYERldGFpbHM6ICR7bWVzc2FnZX1cXG5gO1xuICAgIH1cblxuICAgIGVycm9yTWVzc2FnZSArPSAnUGxlYXNlIHRob3JvdWdobHkgcmV2aWV3IHRoZSByZWxhdGVkIGNvZGUgdG8gZGV0ZXJtaW5lIHdoeSB0aGlzIGVycm9yIG9jY3VycmVkLic7XG5cbiAgICAvLyBMb2cgdG8gY29uc29sZSB3aXRoIGZ1bGwgdmlzaWJpbGl0eVxuICAgIGNvbnNvbGUuZXJyb3IoJz0nLnJlcGVhdCg4MCkpO1xuICAgIGNvbnNvbGUuZXJyb3IoJ1NBTklUWSBDSEVDSyBGQUlMVVJFJyk7XG4gICAgY29uc29sZS5lcnJvcignPScucmVwZWF0KDgwKSk7XG4gICAgY29uc29sZS5lcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgIGNvbnNvbGUuZXJyb3IoJ1N0YWNrIHRyYWNlOicsIHN0YWNrKTtcbiAgICBjb25zb2xlLmVycm9yKCc9Jy5yZXBlYXQoODApKTtcblxuICAgIC8vIFRocm93IGVycm9yIHRvIHN0b3AgZXhlY3V0aW9uIGZsb3dcbiAgICBjb25zdCBmYXRhbEVycm9yID0gbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgZmF0YWxFcnJvci5uYW1lID0gJ1Nhbml0eUNoZWNrRmFpbHVyZSc7XG4gICAgdGhyb3cgZmF0YWxFcnJvcjtcbn0iLCIvKlxuICogSGFzaGluZyBhbmQgY29tcGFyaXNvbiB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIG9iamVjdCBoYXNoaW5nIGFuZCBkZWVwIGNvbXBhcmlzb24uXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEFTSElORyBBTkQgQ09NUEFSSVNPTlxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBoYXNoIGZvciBhbnkgdmFsdWUgKGhhbmRsZXMgb2JqZWN0cywgYXJyYXlzLCBjaXJjdWxhciByZWZlcmVuY2VzKVxuICogQHBhcmFtIHsqfSB0aGVfdmFyIC0gVmFsdWUgdG8gaGFzaFxuICogQHBhcmFtIHtib29sZWFufSBbY2FsY19zaGExPXRydWVdIC0gSWYgdHJ1ZSwgcmV0dXJucyBTSEExIGhhc2g7IGlmIGZhbHNlLCByZXR1cm5zIEpTT05cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW2lnbm9yZWRfa2V5cz1udWxsXSAtIEtleXMgdG8gaWdub3JlIHdoZW4gaGFzaGluZyBvYmplY3RzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTSEExIGhhc2ggb3IgSlNPTiBzdHJpbmcgb2YgdGhlIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGhhc2godGhlX3ZhciwgY2FsY19zaGExID0gdHJ1ZSwgaWdub3JlZF9rZXlzID0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdGhlX3ZhciA9PSB1bmRlZikge1xuICAgICAgICB0aGVfdmFyID0gJ19fdW5kZWZpbmVkX18nO1xuICAgIH1cblxuICAgIGlmIChpZ25vcmVkX2tleXMgPT09IG51bGwpIHtcbiAgICAgICAgaWdub3JlZF9rZXlzID0gWyckJ107XG4gICAgfVxuXG4gICAgLy8gQ29udmVydHMgdmFsdWUgdG8ganNvbiwgZGlzY2FyZGluZyBjaXJjdWxhciByZWZlcmVuY2VzXG4gICAgbGV0IGpzb25fc3RyaW5naWZ5X25vY2lyYyA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBjb25zdCBjYWNoZSA9IFtdO1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIGZ1bmN0aW9uIChrZXksIHYpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdiA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHRoZV92YXIuX2NhY2hlX2tleSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoZV92YXIuX2hhc2hfa2V5KCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2ID09PSAnb2JqZWN0JyAmJiB2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlLmluZGV4T2YodikgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIER1cGxpY2F0ZSByZWZlcmVuY2UgZm91bmQsIGRpc2NhcmQga2V5XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FjaGUucHVzaCh2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2O1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gVHVybiBldmVyeSBwcm9wZXJ0eSBhbmQgYWxsIGl0cyBjaGlsZHJlbiBpbnRvIGEgc2luZ2xlIGRlcHRoIGFycmF5IG9mIHZhbHVlcyB0aGF0IHdlIGNhbiB0aGVuXG4gICAgLy8gc29ydCBhbmQgaGFzaCBhcyBhIHdob2xlXG4gICAgbGV0IGZsYXRfdmFyID0ge307XG4gICAgbGV0IF9mbGF0dGVuID0gZnVuY3Rpb24gKHRoZV92YXIsIHByZWZpeCwgZGVwdGggPSAwKSB7XG4gICAgICAgIC8vIElmIGEgY2xhc3Mgb2JqZWN0IGlzIHByb3ZpZGVkLCBjaXJjdWxhciByZWZlcmVuY2VzIGNhbiBtYWtlIHRoZSBjYWxsIHN0YWNrIHJlY3Vyc2l2ZS5cbiAgICAgICAgLy8gRm9yIHRoZSBwdXJwb3NlcyBvZiBob3cgdGhlIGhhc2ggZnVuY3Rpb24gaXMgY2FsbGVkLCB0aGlzIHNob3VsZCBiZSBzdWZmaWNpZW50LlxuICAgICAgICBpZiAoZGVwdGggPiAxMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRG9lcyBub3QgYWNjb3VudCBmb3IgZGF0ZXMgaSB0aGluay4uLlxuXG4gICAgICAgIGlmIChpc19vYmplY3QodGhlX3ZhcikgJiYgdHlwZW9mIHRoZV92YXIuX2NhY2hlX2tleSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBVc2UgX2NhY2hlX2tleSB0byBoYXNoIGNvbXBvbmVudHNcbiAgICAgICAgICAgIGZsYXRfdmFyW3ByZWZpeF0gPSB0aGVfdmFyLl9oYXNoX2tleSgpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzX29iamVjdCh0aGVfdmFyKSAmJiB0eXBlb2YgQWJzdHJhY3QgIT09ICd1bmRlZmluZWQnICYmIHRoZV92YXIgaW5zdGFuY2VvZiBBYnN0cmFjdCkge1xuICAgICAgICAgICAgLy8gU3RyaW5naWZ5IGFsbCBjbGFzcyBvYmplY3RzXG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0ganNvbl9zdHJpbmdpZnlfbm9jaXJjKHRoZV92YXIpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzX29iamVjdCh0aGVfdmFyKSkge1xuICAgICAgICAgICAgLy8gSXRlcmF0ZSBvdGhlciBvYmplY3RzXG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0ge307XG4gICAgICAgICAgICBmb3IgKGxldCBrIGluIHRoZV92YXIpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhlX3Zhci5oYXNPd25Qcm9wZXJ0eShrKSAmJiBpZ25vcmVkX2tleXMuaW5kZXhPZihrKSA9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBfZmxhdHRlbih0aGVfdmFyW2tdLCBwcmVmaXggKyAnLi4nICsgaywgZGVwdGggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaXNfYXJyYXkodGhlX3ZhcikpIHtcbiAgICAgICAgICAgIC8vIEl0ZXJhdGUgYXJyYXlzXG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0gW107XG4gICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICBmb3JlYWNoKHRoZV92YXIsICh2KSA9PiB7XG4gICAgICAgICAgICAgICAgX2ZsYXR0ZW4odiwgcHJlZml4ICsgJy4uJyArIGksIGRlcHRoICsgMSk7XG4gICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNfZnVuY3Rpb24odGhlX3ZhcikpIHtcbiAgICAgICAgICAgIC8vIG5vdGhpbmdcbiAgICAgICAgfSBlbHNlIGlmICghaXNfbnVtZXJpYyh0aGVfdmFyKSkge1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IFN0cmluZyh0aGVfdmFyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZsYXRfdmFyW3ByZWZpeF0gPSB0aGVfdmFyO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIF9mbGF0dGVuKHRoZV92YXIsICdfJyk7XG5cbiAgICBsZXQgc29ydGVyID0gW107XG5cbiAgICBmb3JlYWNoKGZsYXRfdmFyLCBmdW5jdGlvbiAodiwgaykge1xuICAgICAgICBzb3J0ZXIucHVzaChbaywgdl0pO1xuICAgIH0pO1xuXG4gICAgc29ydGVyLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGFbMF0gPiBiWzBdO1xuICAgIH0pO1xuXG4gICAgbGV0IGpzb24gPSBKU09OLnN0cmluZ2lmeShzb3J0ZXIpO1xuXG4gICAgaWYgKGNhbGNfc2hhMSkge1xuICAgICAgICBsZXQgaGFzaGVkID0gc2hhMS5zaGExKGpzb24pO1xuICAgICAgICByZXR1cm4gaGFzaGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBqc29uO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZWVwIGNvbXBhcmlzb24gb2YgdHdvIHZhbHVlcyAoaWdub3JlcyBwcm9wZXJ0eSBvcmRlciBhbmQgZnVuY3Rpb25zKVxuICogQHBhcmFtIHsqfSBhIC0gRmlyc3QgdmFsdWUgdG8gY29tcGFyZVxuICogQHBhcmFtIHsqfSBiIC0gU2Vjb25kIHZhbHVlIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlcyBhcmUgZGVlcGx5IGVxdWFsXG4gKi9cbmZ1bmN0aW9uIGRlZXBfZXF1YWwoYSwgYikge1xuICAgIHJldHVybiBoYXNoKGEsIGZhbHNlKSA9PSBoYXNoKGIsIGZhbHNlKTtcbn0iLCIvKipcbiAqIE11dGV4IGRlY29yYXRvciBmb3IgZXhjbHVzaXZlIG1ldGhvZCBleGVjdXRpb25cbiAqXG4gKiBXaXRob3V0IGFyZ3VtZW50czogUGVyLWluc3RhbmNlIGxvY2tpbmcgKGVhY2ggb2JqZWN0IGhhcyBpdHMgb3duIGxvY2sgcGVyIG1ldGhvZClcbiAqICAgQG11dGV4XG4gKiAgIGFzeW5jIG15X21ldGhvZCgpIHsgLi4uIH1cbiAqXG4gKiBXaXRoIElEIGFyZ3VtZW50OiBHbG9iYWwgbG9ja2luZyBieSBJRCAoYWxsIGluc3RhbmNlcyBzaGFyZSB0aGUgbG9jaylcbiAqICAgQG11dGV4KCdvcGVyYXRpb25fbmFtZScpXG4gKiAgIGFzeW5jIG15X21ldGhvZCgpIHsgLi4uIH1cbiAqXG4gKiBAZGVjb3JhdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gW2dsb2JhbF9pZF0gLSBPcHRpb25hbCBnbG9iYWwgbXV0ZXggSUQgZm9yIGNyb3NzLWluc3RhbmNlIGxvY2tpbmdcbiAqL1xuZnVuY3Rpb24gbXV0ZXgoZ2xvYmFsX2lkKSB7XG4gICAgLy8gU3RvcmFnZSAodXNpbmcgSUlGRXMgdG8ga2VlcCBXZWFrTWFwL01hcCBpbiBjbG9zdXJlIHNjb3BlKVxuICAgIGNvbnN0IGluc3RhbmNlX211dGV4ZXMgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICghbXV0ZXguX2luc3RhbmNlX3N0b3JhZ2UpIHtcbiAgICAgICAgICAgIG11dGV4Ll9pbnN0YW5jZV9zdG9yYWdlID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXV0ZXguX2luc3RhbmNlX3N0b3JhZ2U7XG4gICAgfSkoKTtcblxuICAgIGNvbnN0IGdsb2JhbF9tdXRleGVzID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIW11dGV4Ll9nbG9iYWxfc3RvcmFnZSkge1xuICAgICAgICAgICAgbXV0ZXguX2dsb2JhbF9zdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtdXRleC5fZ2xvYmFsX3N0b3JhZ2U7XG4gICAgfSkoKTtcblxuICAgIC8qKlxuICAgICAqIEdldCBvciBjcmVhdGUgYSBtdXRleCBmb3IgYSBzcGVjaWZpYyBpbnN0YW5jZSBhbmQgbWV0aG9kXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0X2luc3RhbmNlX211dGV4KGluc3RhbmNlLCBtZXRob2RfbmFtZSkge1xuICAgICAgICBsZXQgaW5zdGFuY2VfbG9ja3MgPSBpbnN0YW5jZV9tdXRleGVzLmdldChpbnN0YW5jZSk7XG4gICAgICAgIGlmICghaW5zdGFuY2VfbG9ja3MpIHtcbiAgICAgICAgICAgIGluc3RhbmNlX2xvY2tzID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgaW5zdGFuY2VfbXV0ZXhlcy5zZXQoaW5zdGFuY2UsIGluc3RhbmNlX2xvY2tzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBsb2NrX3N0YXRlID0gaW5zdGFuY2VfbG9ja3MuZ2V0KG1ldGhvZF9uYW1lKTtcbiAgICAgICAgaWYgKCFsb2NrX3N0YXRlKSB7XG4gICAgICAgICAgICBsb2NrX3N0YXRlID0geyBhY3RpdmU6IGZhbHNlLCBxdWV1ZTogW10gfTtcbiAgICAgICAgICAgIGluc3RhbmNlX2xvY2tzLnNldChtZXRob2RfbmFtZSwgbG9ja19zdGF0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9ja19zdGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3IgY3JlYXRlIGEgZ2xvYmFsIG11dGV4IGJ5IElEXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0X2dsb2JhbF9tdXRleChpZCkge1xuICAgICAgICBsZXQgbG9ja19zdGF0ZSA9IGdsb2JhbF9tdXRleGVzLmdldChpZCk7XG4gICAgICAgIGlmICghbG9ja19zdGF0ZSkge1xuICAgICAgICAgICAgbG9ja19zdGF0ZSA9IHsgYWN0aXZlOiBmYWxzZSwgcXVldWU6IFtdIH07XG4gICAgICAgICAgICBnbG9iYWxfbXV0ZXhlcy5zZXQoaWQsIGxvY2tfc3RhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NrX3N0YXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGUgdGhlIG5leHQgcXVldWVkIG9wZXJhdGlvbiBmb3IgYSBtdXRleFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNjaGVkdWxlX25leHQobG9ja19zdGF0ZSkge1xuICAgICAgICBpZiAobG9ja19zdGF0ZS5hY3RpdmUgfHwgbG9ja19zdGF0ZS5xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgZm4sIHJlc29sdmUsIHJlamVjdCB9ID0gbG9ja19zdGF0ZS5xdWV1ZS5zaGlmdCgpO1xuICAgICAgICBsb2NrX3N0YXRlLmFjdGl2ZSA9IHRydWU7XG5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgIC50aGVuKGZuKVxuICAgICAgICAgICAgLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvY2tfc3RhdGUuYWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgc2NoZWR1bGVfbmV4dChsb2NrX3N0YXRlKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjcXVpcmUgYSBtdXRleCBsb2NrIGFuZCBleGVjdXRlIGNhbGxiYWNrXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWNxdWlyZV9sb2NrKGxvY2tfc3RhdGUsIGZuKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2NrX3N0YXRlLnF1ZXVlLnB1c2goeyBmbiwgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICAgICAgc2NoZWR1bGVfbmV4dChsb2NrX3N0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSWYgY2FsbGVkIHdpdGggYW4gSUQgYXJndW1lbnQ6IEBtdXRleCgnaWQnKVxuICAgIGlmICh0eXBlb2YgZ2xvYmFsX2lkID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24odGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsX21ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3JpZ2luYWxfbWV0aG9kICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBAbXV0ZXggY2FuIG9ubHkgYmUgYXBwbGllZCB0byBtZXRob2RzICh0cmllZCB0byBhcHBseSB0byAke2tleX0pYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlc2NyaXB0b3IudmFsdWUgPSBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbG9ja19zdGF0ZSA9IGdldF9nbG9iYWxfbXV0ZXgoZ2xvYmFsX2lkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWNxdWlyZV9sb2NrKGxvY2tfc3RhdGUsICgpID0+IG9yaWdpbmFsX21ldGhvZC5hcHBseSh0aGlzLCBhcmdzKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBJZiBjYWxsZWQgd2l0aG91dCBhcmd1bWVudHM6IEBtdXRleCAodGFyZ2V0IGlzIHRoZSBmaXJzdCBhcmd1bWVudClcbiAgICBjb25zdCB0YXJnZXQgPSBnbG9iYWxfaWQ7ICAvLyBJbiB0aGlzIGNhc2UsIGZpcnN0IGFyZyBpcyB0YXJnZXRcbiAgICBjb25zdCBrZXkgPSBhcmd1bWVudHNbMV07XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IGFyZ3VtZW50c1syXTtcblxuICAgIGNvbnN0IG9yaWdpbmFsX21ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG5cbiAgICBpZiAodHlwZW9mIG9yaWdpbmFsX21ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEBtdXRleCBjYW4gb25seSBiZSBhcHBsaWVkIHRvIG1ldGhvZHMgKHRyaWVkIHRvIGFwcGx5IHRvICR7a2V5fSlgKTtcbiAgICB9XG5cbiAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICBjb25zdCBsb2NrX3N0YXRlID0gZ2V0X2luc3RhbmNlX211dGV4KHRoaXMsIGtleSk7XG4gICAgICAgIHJldHVybiBhY3F1aXJlX2xvY2sobG9ja19zdGF0ZSwgKCkgPT4gb3JpZ2luYWxfbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3MpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG4iLCIvKlxuICogQXN5bmMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHRoZSBSU3BhZGUgZnJhbWV3b3JrLlxuICogVGhlc2UgZnVuY3Rpb25zIGhhbmRsZSBhc3luY2hyb25vdXMgb3BlcmF0aW9ucywgZGVsYXlzLCBkZWJvdW5jaW5nLCBhbmQgbXV0ZXhlcy5cbiAqL1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBBU1lOQyBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBQYXVzZXMgZXhlY3V0aW9uIGZvciBzcGVjaWZpZWQgbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0ge251bWJlcn0gW21pbGxpc2Vjb25kcz0wXSAtIERlbGF5IGluIG1pbGxpc2Vjb25kcyAoMCB1c2VzIHJlcXVlc3RBbmltYXRpb25GcmFtZSlcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgZGVsYXlcbiAqIEBleGFtcGxlIGF3YWl0IHNsZWVwKDEwMDApOyAvLyBXYWl0IDEgc2Vjb25kXG4gKi9cbmZ1bmN0aW9uIHNsZWVwKG1pbGxpc2Vjb25kcyA9IDApIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgaWYgKG1pbGxpc2Vjb25kcyA9PSAwICYmIHJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJlc29sdmUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBtaWxsaXNlY29uZHMpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlYm91bmNlZCBmdW5jdGlvbiB3aXRoIGV4Y2x1c2l2aXR5IGFuZCBwcm9taXNlIGZhbi1pblxuICpcbiAqIFRoaXMgZnVuY3Rpb24sIHdoZW4gaW52b2tlZCwgaW1tZWRpYXRlbHkgcnVucyB0aGUgY2FsbGJhY2sgZXhjbHVzaXZlbHkuXG4gKiBGb3Igc3Vic2VxdWVudCBpbnZvY2F0aW9ucywgaXQgYXBwbGllcyBhIGRlbGF5IGJlZm9yZSBydW5uaW5nIHRoZSBjYWxsYmFjayBleGNsdXNpdmVseSBhZ2Fpbi5cbiAqIFRoZSBkZWxheSBzdGFydHMgYWZ0ZXIgdGhlIGN1cnJlbnQgYXN5bmNocm9ub3VzIG9wZXJhdGlvbiByZXNvbHZlcy5cbiAqXG4gKiBJZiAnZGVsYXknIGlzIHNldCB0byAwLCB0aGUgZnVuY3Rpb24gd2lsbCBvbmx5IHByZXZlbnQgZW5xdWV1ZWluZyBtdWx0aXBsZSBleGVjdXRpb25zIG9mIHRoZVxuICogc2FtZSBtZXRob2QgbW9yZSB0aGFuIG9uY2UsIGJ1dCB3aWxsIHN0aWxsIHJ1biB0aGVtIGltbWVkaWF0ZWx5IGluIGFuIGV4Y2x1c2l2ZSBzZXF1ZW50aWFsIG1hbm5lci5cbiAqXG4gKiBUaGUgbW9zdCByZWNlbnQgaW52b2NhdGlvbiBvZiB0aGUgZnVuY3Rpb24gd2lsbCBiZSB0aGUgcGFyYW1ldGVycyB0aGF0IGdldCBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uXG4gKiB3aGVuIGl0IGludm9rZXMuXG4gKlxuICogVGhlIGZ1bmN0aW9uIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbmV4dCBleGNsdXNpdmUgZXhlY3V0aW9uIGNvbXBsZXRlcy5cbiAqXG4gKiBVc2FnZSBhcyBmdW5jdGlvbjpcbiAqICAgY29uc3QgZGVib3VuY2VkRm4gPSBkZWJvdW5jZShteUZ1bmN0aW9uLCAyNTApO1xuICpcbiAqIFVzYWdlIGFzIGRlY29yYXRvcjpcbiAqICAgQGRlYm91bmNlKDI1MClcbiAqICAgbXlNZXRob2QoKSB7IC4uLiB9XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbnxudW1iZXJ9IGNhbGxiYWNrX29yX2RlbGF5IFRoZSBjYWxsYmFjayBmdW5jdGlvbiBPUiBkZWxheSB3aGVuIHVzZWQgYXMgZGVjb3JhdG9yXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgc3Vic2VxdWVudCBpbnZvY2F0aW9uc1xuICogQHBhcmFtIHtib29sZWFufSBpbW1lZGlhdGUgaWYgdHJ1ZSwgdGhlIGZpcnN0IHRpbWUgdGhlIGFjdGlvbiBpcyBjYWxsZWQsIHRoZSBjYWxsYmFjayBleGVjdXRlcyBpbW1lZGlhdGVseVxuICogQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRoYXQgd2hlbiBpbnZva2VkLCBydW5zIHRoZSBjYWxsYmFjayBpbW1lZGlhdGVseSBhbmQgZXhjbHVzaXZlbHksXG4gKlxuICogQGRlY29yYXRvclxuICovXG5mdW5jdGlvbiBkZWJvdW5jZShjYWxsYmFja19vcl9kZWxheSwgZGVsYXksIGltbWVkaWF0ZSA9IGZhbHNlKSB7XG4gICAgLy8gRGVjb3JhdG9yIHVzYWdlOiBAZGVib3VuY2UoMjUwKSBvciBAZGVib3VuY2UoMjUwLCB0cnVlKVxuICAgIC8vIEZpcnN0IGFyZ3VtZW50IGlzIGEgbnVtYmVyICh0aGUgZGVsYXkpLCByZXR1cm5zIGRlY29yYXRvciBmdW5jdGlvblxuICAgIGlmICh0eXBlb2YgY2FsbGJhY2tfb3JfZGVsYXkgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvcl9kZWxheSA9IGNhbGxiYWNrX29yX2RlbGF5O1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JfaW1tZWRpYXRlID0gZGVsYXkgfHwgZmFsc2U7XG5cbiAgICAgICAgLy8gVEMzOSBkZWNvcmF0b3IgZm9ybTogcmVjZWl2ZXMgKHZhbHVlLCBjb250ZXh0KVxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dC5raW5kID09PSAnbWV0aG9kJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZWJvdW5jZV9pbXBsKHZhbHVlLCBkZWNvcmF0b3JfZGVsYXksIGRlY29yYXRvcl9pbW1lZGlhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIEZ1bmN0aW9uIHVzYWdlOiBkZWJvdW5jZShmbiwgMjUwKVxuICAgIC8vIEZpcnN0IGFyZ3VtZW50IGlzIGEgZnVuY3Rpb24gKHRoZSBjYWxsYmFjaylcbiAgICBjb25zdCBjYWxsYmFjayA9IGNhbGxiYWNrX29yX2RlbGF5O1xuICAgIHJldHVybiBkZWJvdW5jZV9pbXBsKGNhbGxiYWNrLCBkZWxheSwgaW1tZWRpYXRlKTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiBkZWJvdW5jZSBsb2dpY1xuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVib3VuY2VfaW1wbChjYWxsYmFjaywgZGVsYXksIGltbWVkaWF0ZSA9IGZhbHNlKSB7XG4gICAgbGV0IHJ1bm5pbmcgPSBmYWxzZTtcbiAgICBsZXQgcXVldWVkID0gZmFsc2U7XG4gICAgbGV0IGxhc3RfZW5kX3RpbWUgPSAwOyAvLyB0aW1lc3RhbXAgb2YgbGFzdCBjb21wbGV0ZWQgcnVuXG4gICAgbGV0IHRpbWVyID0gbnVsbDtcblxuICAgIGxldCBuZXh0X2FyZ3MgPSBbXTtcbiAgICBsZXQgbmV4dF9jb250ZXh0ID0gbnVsbDtcbiAgICBsZXQgcmVzb2x2ZV9xdWV1ZSA9IFtdO1xuICAgIGxldCByZWplY3RfcXVldWUgPSBbXTtcblxuICAgIGNvbnN0IHJ1bl9mdW5jdGlvbiA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdGhlc2VfcmVzb2x2ZXMgPSByZXNvbHZlX3F1ZXVlO1xuICAgICAgICBjb25zdCB0aGVzZV9yZWplY3RzID0gcmVqZWN0X3F1ZXVlO1xuICAgICAgICBjb25zdCBhcmdzID0gbmV4dF9hcmdzO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV4dF9jb250ZXh0O1xuXG4gICAgICAgIHJlc29sdmVfcXVldWUgPSBbXTtcbiAgICAgICAgcmVqZWN0X3F1ZXVlID0gW107XG4gICAgICAgIG5leHRfYXJncyA9IFtdO1xuICAgICAgICBuZXh0X2NvbnRleHQgPSBudWxsO1xuICAgICAgICBxdWV1ZWQgPSBmYWxzZTtcbiAgICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNhbGxiYWNrLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgICAgZm9yIChjb25zdCByZXNvbHZlIG9mIHRoZXNlX3Jlc29sdmVzKSByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgZm9yIChjb25zdCByZWplY3Qgb2YgdGhlc2VfcmVqZWN0cykgcmVqZWN0KGVycik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBsYXN0X2VuZF90aW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgIGlmIChxdWV1ZWQpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICAgIHRpbWVyID0gc2V0VGltZW91dChydW5fZnVuY3Rpb24sIE1hdGgubWF4KGRlbGF5LCAwKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRpbWVyID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgbmV4dF9hcmdzID0gYXJncztcbiAgICAgICAgbmV4dF9jb250ZXh0ID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZV9xdWV1ZS5wdXNoKHJlc29sdmUpO1xuICAgICAgICAgICAgcmVqZWN0X3F1ZXVlLnB1c2gocmVqZWN0KTtcblxuICAgICAgICAgICAgLy8gTm90aGluZyBydW5uaW5nIGFuZCBub3RoaW5nIHNjaGVkdWxlZFxuICAgICAgICAgICAgaWYgKCFydW5uaW5nICYmICF0aW1lcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0X2NhbGwgPSBsYXN0X2VuZF90aW1lID09PSAwO1xuXG4gICAgICAgICAgICAgICAgaWYgKGltbWVkaWF0ZSAmJiBmaXJzdF9jYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bl9mdW5jdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2luY2UgPSBmaXJzdF9jYWxsID8gSW5maW5pdHkgOiBEYXRlLm5vdygpIC0gbGFzdF9lbmRfdGltZTtcbiAgICAgICAgICAgICAgICBpZiAoc2luY2UgPj0gZGVsYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcnVuX2Z1bmN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2FpdCA9IE1hdGgubWF4KGRlbGF5IC0gc2luY2UsIDApO1xuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQocnVuX2Z1bmN0aW9uLCB3YWl0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHJ1bm5pbmcgb3IgYSB0aW1lciBleGlzdHMsIGp1c3QgbWFyayBxdWV1ZWQuXG4gICAgICAgICAgICAvLyBUaGUgZmluYWxseXt9IG9mIHJ1bl9mdW5jdGlvbiBoYW5kbGVzIHNjaGVkdWxpbmcgYWZ0ZXIgZnVsbCBkZWxheS5cbiAgICAgICAgICAgIHF1ZXVlZCA9IHRydWU7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFJFQUQtV1JJVEUgTE9DSyBGVU5DVElPTlMgLSBEZWxlZ2F0ZWQgdG8gUmVhZFdyaXRlTG9jayBjbGFzc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEFjcXVpcmUgYW4gZXhjbHVzaXZlIHdyaXRlIGxvY2sgYnkgbmFtZS5cbiAqIE9ubHkgb25lIHdyaXRlciBydW5zIGF0IGEgdGltZTsgYmxvY2tzIHJlYWRlcnMgdW50aWwgZmluaXNoZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHsoKSA9PiBhbnl8UHJvbWlzZTxhbnk+fSBjYlxuICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAqL1xuZnVuY3Rpb24gcndsb2NrKG5hbWUsIGNiKSB7XG4gICAgcmV0dXJuIFJlYWRXcml0ZUxvY2suYWNxdWlyZShuYW1lLCBjYik7XG59XG5cbi8qKlxuICogQWNxdWlyZSBhIHNoYXJlZCByZWFkIGxvY2sgYnkgbmFtZS5cbiAqIE11bHRpcGxlIHJlYWRlcnMgcnVuIGluIHBhcmFsbGVsLCBidXQgcmVhZGVycyBhcmUgYmxvY2tlZCBieSBxdWV1ZWQvYWN0aXZlIHdyaXRlcnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHsoKSA9PiBhbnl8UHJvbWlzZTxhbnk+fSBjYlxuICogQHJldHVybnMge1Byb21pc2U8YW55Pn1cbiAqL1xuZnVuY3Rpb24gcndsb2NrX3JlYWQobmFtZSwgY2IpIHtcbiAgICByZXR1cm4gUmVhZFdyaXRlTG9jay5hY3F1aXJlX3JlYWQobmFtZSwgY2IpO1xufVxuXG4vKipcbiAqIEZvcmNlZnVsbHkgY2xlYXIgYWxsIGxvY2tzIGFuZCBxdWV1ZXMgZm9yIGEgZ2l2ZW4gbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKi9cbmZ1bmN0aW9uIHJ3bG9ja19mb3JjZV91bmxvY2sobmFtZSkge1xuICAgIFJlYWRXcml0ZUxvY2suZm9yY2VfdW5sb2NrKG5hbWUpO1xufVxuXG4vKipcbiAqIEluc3BlY3QgbG9jayBzdGF0ZSBmb3IgZGVidWdnaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHt7cmVhZGVyczpudW1iZXIsIHdyaXRlcl9hY3RpdmU6Ym9vbGVhbiwgcmVhZGVyX3E6bnVtYmVyLCB3cml0ZXJfcTpudW1iZXJ9fVxuICovXG5mdW5jdGlvbiByd2xvY2tfcGVuZGluZyhuYW1lKSB7XG4gICAgcmV0dXJuIFJlYWRXcml0ZUxvY2sucGVuZGluZyhuYW1lKTtcbn1cbiIsIi8qXG4gKiBDb3JlIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB0aGUgUlNwYWRlIGZyYW1ld29yay5cbiAqIFRoZXNlIGZ1bmN0aW9ucyBoYW5kbGUgdHlwZSBjaGVja2luZywgdHlwZSBjb252ZXJzaW9uLCBzdHJpbmcgbWFuaXB1bGF0aW9uLFxuICogYW5kIG9iamVjdC9hcnJheSB1dGlsaXRpZXMuIFRoZXkgbWlycm9yIGZ1bmN0aW9uYWxpdHkgZnJvbSBQSFAgZnVuY3Rpb25zLlxuICpcbiAqIE90aGVyIHV0aWxpdHkgZnVuY3Rpb25zIGFyZSBvcmdhbml6ZWQgaW46XG4gKiAtIGFzeW5jLmpzOiBBc3luYyB1dGlsaXRpZXMgKHNsZWVwLCBkZWJvdW5jZSwgbXV0ZXgpXG4gKiAtIGJyb3dzZXIuanM6IEJyb3dzZXIvRE9NIHV0aWxpdGllcyAoaXNfbW9iaWxlLCBzY3JvbGwgZnVuY3Rpb25zKVxuICogLSBkYXRldGltZS5qczogRGF0ZS90aW1lIHV0aWxpdGllc1xuICogLSBoYXNoLmpzOiBIYXNoaW5nIGFuZCBjb21wYXJpc29uXG4gKiAtIGVycm9yLmpzOiBFcnJvciBoYW5kbGluZ1xuICovXG5cbi8vIFRvZG86IHRlc3QgdGhhdCBwcm9kIGJ1aWxkIGlkZW50aWZpZXMgYW5kIHJlbW92ZXMgdW5jYWxsZWQgZnVuY3Rpb25zIGZyb20gdGhlIGZpbmFsIGJ1bmRsZS5cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQ09OU1RBTlRTIEFORCBIRUxQRVJTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8vIERlZmluZSBjb21tb25seSB1c2VkIGNvbnN0YW50c1xuY29uc3QgdW5kZWYgPSAndW5kZWZpbmVkJztcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGFycmF5cyBvciBvYmplY3RzIHdpdGggcHJvbWlzZSBzdXBwb3J0XG4gKlxuICogV29ya3Mgd2l0aCBib3RoIHN5bmNocm9ub3VzIGFuZCBhc3luY2hyb25vdXMgY2FsbGJhY2tzLiBJZiB0aGUgY2FsbGJhY2tcbiAqIHJldHVybnMgcHJvbWlzZXMsIHRoZXkgYXJlIGV4ZWN1dGVkIGluIHBhcmFsbGVsIGFuZCB0aGlzIGZ1bmN0aW9uIHJldHVybnNcbiAqIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIHBhcmFsbGVsIHRhc2tzIGNvbXBsZXRlLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBvYmogLSBDb2xsZWN0aW9uIHRvIGl0ZXJhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBpdGVtICh2YWx1ZSwga2V5KSAtIGNhbiBiZSBhc3luY1xuICogQHJldHVybnMge1Byb21pc2V8dW5kZWZpbmVkfSBQcm9taXNlIGlmIGFueSBjYWxsYmFja3MgcmV0dXJuIHByb21pc2VzLCB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFN5bmNocm9ub3VzIHVzYWdlXG4gKiBmb3JlYWNoKFsxLDIsM10sICh2YWwpID0+IGNvbnNvbGUubG9nKHZhbCkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBc3luY2hyb25vdXMgdXNhZ2UgLSB3YWl0cyBmb3IgYWxsIHRvIGNvbXBsZXRlXG4gKiBhd2FpdCBmb3JlYWNoKFsxLDIsM10sIGFzeW5jICh2YWwpID0+IHtcbiAqICAgICBhd2FpdCBmZXRjaCgnL2FwaS9wcm9jZXNzLycgKyB2YWwpO1xuICogfSk7XG4gKi9cbmZ1bmN0aW9uIGZvcmVhY2gob2JqLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgb2JqLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGNhbGxiYWNrKHZhbHVlLCBpbmRleCkpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goY2FsbGJhY2sob2JqW2tleV0sIGtleSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmlsdGVyIGZvciBwcm9taXNlc1xuICAgIGNvbnN0IHByb21pc2VzID0gcmVzdWx0cy5maWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0ICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gJ2Z1bmN0aW9uJyk7XG5cbiAgICAvLyBJZiB0aGVyZSBhcmUgYW55IHByb21pc2VzLCByZXR1cm4gUHJvbWlzZS5hbGwgdG8gd2FpdCBmb3IgYWxsIHRvIGNvbXBsZXRlXG4gICAgaWYgKHByb21pc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICB9XG5cbiAgICAvLyBObyBwcm9taXNlcyByZXR1cm5lZCwgc28gd2UncmUgZG9uZVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVFlQRSBDSEVDS0lORyBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBudW1lcmljXG4gKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgZmluaXRlIG51bWJlclxuICovXG5mdW5jdGlvbiBpc19udW1lcmljKG4pIHtcbiAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobikpICYmIGlzRmluaXRlKG4pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGEgc3RyaW5nXG4gKiBAcGFyYW0geyp9IHMgLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGlzX3N0cmluZyhzKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBzID09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqIEBwYXJhbSB7Kn0gbiAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYW4gaW50ZWdlclxuICovXG5mdW5jdGlvbiBpc19pbnRlZ2VyKG4pIHtcbiAgICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihuKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhIHByb21pc2UtbGlrZSBvYmplY3RcbiAqIEBwYXJhbSB7Kn0gb2JqIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBoYXMgYSB0aGVuIG1ldGhvZFxuICovXG5mdW5jdGlvbiBpc19wcm9taXNlKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqID09ICdvYmplY3QnICYmIHR5cGVvZiBvYmoudGhlbiA9PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGFuIGFycmF5XG4gKiBAcGFyYW0geyp9IG9iaiAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYW4gYXJyYXlcbiAqL1xuZnVuY3Rpb24gaXNfYXJyYXkob2JqKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkob2JqKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhbiBvYmplY3QgKGV4Y2x1ZGVzIG51bGwpXG4gKiBAcGFyYW0geyp9IG9iaiAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0IGFuZCBub3QgbnVsbFxuICovXG5mdW5jdGlvbiBpc19vYmplY3Qob2JqKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhIGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IGZ1bmN0aW9uX3RvX2NoZWNrIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIGlzX2Z1bmN0aW9uKGZ1bmN0aW9uX3RvX2NoZWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uX3RvX2NoZWNrICYmIHt9LnRvU3RyaW5nLmNhbGwoZnVuY3Rpb25fdG9fY2hlY2spID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcbiAqIFVzZXMgYSBwcmFjdGljYWwgUkZDIDUzMjIgY29tcGxpYW50IHJlZ2V4IHRoYXQgbWF0Y2hlcyA5OS45OSUgb2YgcmVhbC13b3JsZCBlbWFpbCBhZGRyZXNzZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbWFpbCAtIEVtYWlsIGFkZHJlc3MgdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBzdHJpbmcgaXMgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXG4gKi9cbmZ1bmN0aW9uIGlzX2VtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCFpc19zdHJpbmcoZW1haWwpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgcmVnZXggPSAvXlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSsoPzpcXC5bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKSpAKD86W2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pP1xcLikrW2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pPyQvaTtcbiAgICByZXR1cm4gcmVnZXgudGVzdChlbWFpbCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgZGVmaW5lZCAobm90IHVuZGVmaW5lZClcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgbm90IHVuZGVmaW5lZFxuICovXG5mdW5jdGlvbiBpc3NldCh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgIT0gdW5kZWY7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgZW1wdHkgKG51bGwsIHVuZGVmaW5lZCwgMCwgXCJcIiwgZW1wdHkgYXJyYXkvb2JqZWN0KVxuICogQHBhcmFtIHsqfSBvYmplY3QgLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGNvbnNpZGVyZWQgZW1wdHlcbiAqL1xuZnVuY3Rpb24gZW1wdHkob2JqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT0gdW5kZWYpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChvYmplY3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdzdHJpbmcnICYmIG9iamVjdCA9PSAnJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA9PSAwO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiAhb2JqZWN0Lmxlbmd0aDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRZUEUgQ09OVkVSU0lPTiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGEgZmxvYXRpbmcgcG9pbnQgbnVtYmVyXG4gKiBSZXR1cm5zIDAgZm9yIG51bGwsIHVuZGVmaW5lZCwgTmFOLCBvciBub24tbnVtZXJpYyB2YWx1ZXNcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gVmFsdWUgdG8gY29udmVydFxuICogQHJldHVybnMge251bWJlcn0gRmxvYXRpbmcgcG9pbnQgbnVtYmVyXG4gKi9cbmZ1bmN0aW9uIGZsb2F0KHZhbCkge1xuICAgIC8vIEhhbmRsZSBudWxsLCB1bmRlZmluZWQsIGVtcHR5IHN0cmluZ1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQgfHwgdmFsID09PSAnJykge1xuICAgICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIC8vIFRyeSB0byBwYXJzZSB0aGUgdmFsdWVcbiAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUZsb2F0KHZhbCk7XG5cbiAgICAvLyBDaGVjayBmb3IgTmFOIGFuZCByZXR1cm4gMCBpZiBwYXJzaW5nIGZhaWxlZFxuICAgIHJldHVybiBpc05hTihwYXJzZWQpID8gMC4wIDogcGFyc2VkO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgdmFsdWUgdG8gYW4gaW50ZWdlclxuICogUmV0dXJucyAwIGZvciBudWxsLCB1bmRlZmluZWQsIE5hTiwgb3Igbm9uLW51bWVyaWMgdmFsdWVzXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEludGVnZXIgdmFsdWVcbiAqL1xuZnVuY3Rpb24gaW50KHZhbCkge1xuICAgIC8vIEhhbmRsZSBudWxsLCB1bmRlZmluZWQsIGVtcHR5IHN0cmluZ1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQgfHwgdmFsID09PSAnJykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gcGFyc2UgdGhlIHZhbHVlXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VJbnQodmFsLCAxMCk7XG5cbiAgICAvLyBDaGVjayBmb3IgTmFOIGFuZCByZXR1cm4gMCBpZiBwYXJzaW5nIGZhaWxlZFxuICAgIHJldHVybiBpc05hTihwYXJzZWQpID8gMCA6IHBhcnNlZDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGEgc3RyaW5nXG4gKiBSZXR1cm5zIGVtcHR5IHN0cmluZyBmb3IgbnVsbCBvciB1bmRlZmluZWRcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gVmFsdWUgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gKi9cbmZ1bmN0aW9uIHN0cih2YWwpIHtcbiAgICAvLyBIYW5kbGUgbnVsbCBhbmQgdW5kZWZpbmVkIHNwZWNpYWxseVxuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIENvbnZlcnQgdG8gc3RyaW5nXG4gICAgcmV0dXJuIFN0cmluZyh2YWwpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIG51bWVyaWMgc3RyaW5ncyB0byBudW1iZXJzLCByZXR1cm5zIGFsbCBvdGhlciB2YWx1ZXMgdW5jaGFuZ2VkXG4gKiBVc2VkIHdoZW4geW91IG5lZWQgdG8gZW5zdXJlIG51bWVyaWMgdHlwZXMgYnV0IGRvbid0IHdhbnQgdG8gZm9yY2VcbiAqIGNvbnZlcnNpb24gb2Ygbm9uLW51bWVyaWMgdmFsdWVzICh3aGljaCB3b3VsZCBiZWNvbWUgMClcbiAqIEBwYXJhbSB7Kn0gdmFsIC0gVmFsdWUgdG8gY29udmVydFxuICogQHJldHVybnMgeyp9IE51bWJlciBpZiBpbnB1dCB3YXMgbnVtZXJpYyBzdHJpbmcsIG90aGVyd2lzZSB1bmNoYW5nZWRcbiAqL1xuZnVuY3Rpb24gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSh2YWwpIHtcbiAgICAvLyBJZiBpdCdzIGFscmVhZHkgYSBudW1iZXIsIHJldHVybiBpdFxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cblxuICAgIC8vIElmIGl0J3MgYSBzdHJpbmcgYW5kIG51bWVyaWMsIGNvbnZlcnQgaXRcbiAgICBpZiAoaXNfc3RyaW5nKHZhbCkgJiYgaXNfbnVtZXJpYyh2YWwpKSB7XG4gICAgICAgIC8vIFVzZSBwYXJzZUZsb2F0IHRvIGhhbmRsZSBib3RoIGludGVnZXJzIGFuZCBmbG9hdHNcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gZXZlcnl0aGluZyBlbHNlIHVuY2hhbmdlZCAobnVsbCwgb2JqZWN0cywgbm9uLW51bWVyaWMgc3RyaW5ncywgZXRjLilcbiAgICByZXR1cm4gdmFsO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBTVFJJTkcgTUFOSVBVTEFUSU9OIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEVzY2FwZXMgSFRNTCBzcGVjaWFsIGNoYXJhY3RlcnMgKHVzZXMgTG9kYXNoIGVzY2FwZSlcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gZXNjYXBlXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIVE1MLWVzY2FwZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGh0bWwoc3RyKSB7XG4gICAgcmV0dXJuIF8uZXNjYXBlKHN0cik7XG59XG5cbi8qKlxuICogQ29udmVydHMgbmV3bGluZXMgdG8gSFRNTCBsaW5lIGJyZWFrc1xuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgd2l0aCBuZXdsaW5lcyByZXBsYWNlZCBieSA8YnIgLz5cbiAqL1xuZnVuY3Rpb24gbmwyYnIoc3RyKSB7XG4gICAgaWYgKHR5cGVvZiBzdHIgPT09IHVuZGVmIHx8IHN0ciA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiAoc3RyICsgJycpLnJlcGxhY2UoLyhbXj5cXHJcXG5dPykoXFxyXFxufFxcblxccnxcXHJ8XFxuKS9nLCAnJDE8YnIgLz4kMicpO1xufVxuXG4vKipcbiAqIEVzY2FwZXMgSFRNTCBhbmQgY29udmVydHMgbmV3bGluZXMgdG8gPGJyIC8+XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIHByb2Nlc3NcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhUTUwtZXNjYXBlZCBzdHJpbmcgd2l0aCBsaW5lIGJyZWFrc1xuICovXG5mdW5jdGlvbiBodG1sYnIoc3RyKSB7XG4gICAgcmV0dXJuIG5sMmJyKGh0bWwoc3RyKSk7XG59XG5cbi8qKlxuICogVVJMLWVuY29kZXMgYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gZW5jb2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVUkwtZW5jb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gdXJsZW5jb2RlKHN0cikge1xuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyKTtcbn1cblxuLyoqXG4gKiBVUkwtZGVjb2RlcyBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byBkZWNvZGVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFVSTC1kZWNvZGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiB1cmxkZWNvZGUoc3RyKSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpO1xufVxuXG4vKipcbiAqIEpTT04tZW5jb2RlcyBhIHZhbHVlXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gVmFsdWUgdG8gZW5jb2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBKU09OIHN0cmluZ1xuICovXG5mdW5jdGlvbiBqc29uX2VuY29kZSh2YWx1ZSkge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG59XG5cbi8qKlxuICogSlNPTi1kZWNvZGVzIGEgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gSlNPTiBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyB7Kn0gRGVjb2RlZCB2YWx1ZVxuICovXG5mdW5jdGlvbiBqc29uX2RlY29kZShzdHIpIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShzdHIpO1xufVxuXG4vKipcbiAqIENvbnNvbGUgZGVidWcgb3V0cHV0IHdpdGggY2hhbm5lbCBmaWx0ZXJpbmdcbiAqIEFsaWFzIGZvciBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnXG4gKiBAcGFyYW0ge3N0cmluZ30gY2hhbm5lbCAtIERlYnVnIGNoYW5uZWwgbmFtZVxuICogQHBhcmFtIHsuLi4qfSB2YWx1ZXMgLSBWYWx1ZXMgdG8gbG9nXG4gKi9cbmZ1bmN0aW9uIGNvbnNvbGVfZGVidWcoY2hhbm5lbCwgLi4udmFsdWVzKSB7XG4gICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhjaGFubmVsLCAuLi52YWx1ZXMpO1xufVxuXG4vKipcbiAqIFJlcGxhY2VzIGFsbCBvY2N1cnJlbmNlcyBvZiBhIHN1YnN0cmluZyBpbiBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyAtIFN0cmluZyB0byBzZWFyY2ggaW5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzZWFyY2ggLSBTdWJzdHJpbmcgdG8gZmluZFxuICogQHBhcmFtIHtzdHJpbmd9IHJlcGxhY2UgLSBSZXBsYWNlbWVudCBzdWJzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyB3aXRoIGFsbCBvY2N1cnJlbmNlcyByZXBsYWNlZFxuICovXG5mdW5jdGlvbiByZXBsYWNlX2FsbChzdHJpbmcsIHNlYXJjaCwgcmVwbGFjZSkge1xuICAgIGlmICghaXNfc3RyaW5nKHN0cmluZykpIHtcbiAgICAgICAgc3RyaW5nID0gc3RyaW5nICsgJyc7XG4gICAgfVxuICAgIHJldHVybiBzdHJpbmcuc3BsaXQoc2VhcmNoKS5qb2luKHJlcGxhY2UpO1xufVxuXG4vKipcbiAqIENhcGl0YWxpemVzIHRoZSBmaXJzdCBsZXR0ZXIgb2YgZWFjaCB3b3JkXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgLSBTdHJpbmcgdG8gY2FwaXRhbGl6ZVxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHdpdGggZmlyc3QgbGV0dGVyIG9mIGVhY2ggd29yZCBjYXBpdGFsaXplZFxuICovXG5mdW5jdGlvbiB1Y3dvcmRzKGlucHV0KSB7XG4gICAgcmV0dXJuIGlucHV0XG4gICAgICAgIC5zcGxpdCgnICcpXG4gICAgICAgIC5tYXAoKHdvcmQpID0+IHdvcmQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB3b3JkLnNsaWNlKDEpKVxuICAgICAgICAuam9pbignICcpO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBPQkpFQ1QgQU5EIEFSUkFZIFVUSUxJVElFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIENvdW50cyB0aGUgbnVtYmVyIG9mIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0IG9yIGVsZW1lbnRzIGluIGFuIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gbyAtIE9iamVjdCBvciBhcnJheSB0byBjb3VudFxuICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIG93biBwcm9wZXJ0aWVzL2VsZW1lbnRzXG4gKi9cbmZ1bmN0aW9uIGNvdW50KG8pIHtcbiAgICBsZXQgYyA9IDA7XG4gICAgZm9yIChjb25zdCBrIGluIG8pIHtcbiAgICAgICAgaWYgKG8uaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICsrYztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc2hhbGxvdyBjbG9uZSBvZiBhbiBvYmplY3QsIGFycmF5LCBvciBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBvYmogLSBWYWx1ZSB0byBjbG9uZVxuICogQHJldHVybnMgeyp9IENsb25lZCB2YWx1ZVxuICovXG5mdW5jdGlvbiBjbG9uZShvYmopIHtcbiAgICBpZiAodHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZS5fX2Nsb25lID09IHVuZGVmKSB7XG4gICAgICAgIEZ1bmN0aW9uLnByb3RvdHlwZS5fX2Nsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy9odHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xODMzNTg4L2phdmFzY3JpcHQtY2xvbmUtYS1mdW5jdGlvblxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgdGVtcCA9IGZ1bmN0aW9uIGNsb25lZCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhhdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICB0ZW1wW2tleV0gPSB0aGlzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRlbXA7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gb2JqLl9fY2xvbmUoKTtcbiAgICB9IGVsc2UgaWYgKG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY29uc3RydWN0b3IgPT0gQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIG9iai5zbGljZSgwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MjgzNjAvaG93LWRvLWktY29ycmVjdGx5LWNsb25lLWEtamF2YXNjcmlwdC1vYmplY3QvMzAwNDI5NDgjMzAwNDI5NDhcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIG9iaik7XG4gICAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IG5vbi1udWxsL3VuZGVmaW5lZCB2YWx1ZSBmcm9tIGFyZ3VtZW50c1xuICogQHBhcmFtIHsuLi4qfSBhcmd1bWVudHMgLSBWYWx1ZXMgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHsqfSBGaXJzdCBub24tbnVsbC91bmRlZmluZWQgdmFsdWUsIG9yIG51bGwgaWYgbm9uZSBmb3VuZFxuICovXG5mdW5jdGlvbiBjb2FsZXNjZSgpIHtcbiAgICBsZXQgYXJncyA9IEFycmF5LmZyb20oYXJndW1lbnRzKTtcbiAgICBsZXQgcmV0dXJuX3ZhbCA9IG51bGw7XG4gICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgaWYgKHJldHVybl92YWwgPT09IG51bGwgJiYgdHlwZW9mIGFyZyAhPSB1bmRlZiAmJiBhcmcgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybl92YWwgPSBhcmc7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmV0dXJuX3ZhbDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBDU1Ygc3RyaW5nIHRvIGFycmF5LCB0cmltbWluZyBlYWNoIGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJfY3N2IC0gQ1NWIHN0cmluZyB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gQXJyYXkgb2YgdHJpbW1lZCB2YWx1ZXNcbiAqIEB0b2RvIEhhbmRsZSBxdW90ZWQvZXNjYXBlZCBjaGFyYWN0ZXJzXG4gKi9cbmZ1bmN0aW9uIGNzdl90b19hcnJheV90cmltKHN0cl9jc3YpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHN0cl9jc3Yuc3BsaXQoJywnKTtcbiAgICBjb25zdCByZXQgPSBbXTtcbiAgICBmb3JlYWNoKHBhcnRzLCAocGFydCkgPT4ge1xuICAgICAgICByZXQucHVzaChwYXJ0LnRyaW0oKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldDtcbn1cbiIsIi8qKlxuICogUXVpbGwgRWRpdG9yIC0gVXRpbGl0eSBGdW5jdGlvbnNcbiAqXG4gKiBQcm92aWRlcyB1dGlsaXR5IGZ1bmN0aW9ucyBmb3Igd29ya2luZyB3aXRoIFF1aWxsIGVkaXRvci5cbiAqL1xuXG4vKipcbiAqIEVuc3VyZXMgUXVpbGwgaXMgbG9hZGVkIGJlZm9yZSBleGVjdXRpbmcgY2FsbGJhY2tcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIFF1aWxsIGlzIHJlYWR5XG4gKi9cbmZ1bmN0aW9uIHF1aWxsX3JlYWR5KGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuUXVpbGwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiBxdWlsbF9yZWFkeShjYWxsYmFjayksIDUwKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNhdmUgY2xpZW50IGhhbmRsZXIgZm9yIEZvcm0gY29tcG9uZW50XG4gKiBAcGFyYW0ge09iamVjdH0gdmFsdWVzIC0gU2VyaWFsaXplZCBmb3JtIHZhbHVlc1xuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gUmVzcG9uc2Uge3N1Y2Nlc3M6IGJvb2wsIGVycm9ycz86IHt9LCByZWRpcmVjdD86IHN0cmluZ31cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2F2ZV9jbGllbnQodmFsdWVzKSB7XG4gICAgLy8gQ2hlY2sgaWYgZWRpdGluZyBleGlzdGluZyBjbGllbnRcbiAgICBjb25zdCBjbGllbnRfaWQgPSAkKCcjY2xpZW50LWlkJykudmFsKCk7XG4gICAgaWYgKGNsaWVudF9pZCkge1xuICAgICAgICB2YWx1ZXMuaWQgPSBjbGllbnRfaWQ7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogQ29sbGVjdCBhZGRpdGlvbmFsIGZpZWxkcyBub3QgeWV0IGluIEZvcm0gY29tcG9uZW50ICh0YWdzLCBldGMuKVxuICAgIC8vIEZvciBub3csIGp1c3Qgc3VibWl0IHRoZSBiYXNpYyBmaWVsZHMgZnJvbSB0aGUgRm9ybSBjb21wb25lbnRcblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLnNhdmUodmFsdWVzKTtcblxuICAgICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzcykge1xuICAgICAgICAgICAgLy8gUmVkaXJlY3QgdG8gY2xpZW50cyBsaXN0IG9uIHN1Y2Nlc3NcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZWRpcmVjdDogUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXInLCAnaW5kZXgnKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJldHVybiB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcnM6IHJlc3BvbnNlLmVycm9ycyB8fCB7X2dlbmVyYWw6IHJlc3BvbnNlLm1lc3NhZ2UgfHwgJ0FuIGVycm9yIG9jY3VycmVkJ31cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdTYXZlIGVycm9yOicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3JzOiB7X2dlbmVyYWw6ICdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBzYXZpbmcuIFBsZWFzZSB0cnkgYWdhaW4uJ31cbiAgICAgICAgfTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNhdmUgY29udGFjdCBoYW5kbGVyIGZvciBGb3JtIGNvbXBvbmVudFxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlcyAtIFNlcmlhbGl6ZWQgZm9ybSB2YWx1ZXNcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFJlc3BvbnNlIHtzdWNjZXNzOiBib29sLCBlcnJvcnM/OiB7fSwgcmVkaXJlY3Q/OiBzdHJpbmd9XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNhdmVfY29udGFjdCh2YWx1ZXMpIHtcbiAgICAvLyBDaGVjayBpZiBlZGl0aW5nIGV4aXN0aW5nIGNvbnRhY3RcbiAgICBjb25zdCBjb250YWN0X2lkID0gJCgnI2NvbnRhY3QtaWQnKS52YWwoKTtcbiAgICBpZiAoY29udGFjdF9pZCkge1xuICAgICAgICB2YWx1ZXMuaWQgPSBjb250YWN0X2lkO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5zYXZlKHZhbHVlcyk7XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIC8vIFJlZGlyZWN0IHRvIGNvbnRhY3QgdmlldyBvciBsaXN0IG9uIHN1Y2Nlc3NcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZWRpcmVjdDogcmVzcG9uc2UucmVkaXJlY3QgfHwgUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyJywgJ2luZGV4JylcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXR1cm4gdmFsaWRhdGlvbiBlcnJvcnNcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiByZXNwb25zZS5lcnJvcnMgfHwge19nZW5lcmFsOiByZXNwb25zZS5tZXNzYWdlIHx8ICdBbiBlcnJvciBvY2N1cnJlZCd9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignU2F2ZSBlcnJvcjonLCBlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yczoge19nZW5lcmFsOiAnQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgc2F2aW5nLiBQbGVhc2UgdHJ5IGFnYWluLid9XG4gICAgICAgIH07XG4gICAgfVxufVxuIiwiLyoqXG4gKiBNYW5pZmVzdCAtIEphdmFTY3JpcHQgY2xhc3MgcmVnaXN0cnkgYW5kIG1ldGFkYXRhIHN5c3RlbVxuICpcbiAqIFRoaXMgY2xhc3MgbWFpbnRhaW5zIGEgcmVnaXN0cnkgb2YgYWxsIEphdmFTY3JpcHQgY2xhc3NlcyBpbiB0aGUgYnVuZGxlLFxuICogdHJhY2tpbmcgdGhlaXIgbmFtZXMgYW5kIGluaGVyaXRhbmNlIHJlbGF0aW9uc2hpcHMuIEl0IHByb3ZpZGVzIHV0aWxpdGllc1xuICogZm9yIHdvcmtpbmcgd2l0aCBjbGFzcyBoaWVyYXJjaGllcyBhbmQgY2FsbGluZyBpbml0aWFsaXphdGlvbiBtZXRob2RzLlxuICovXG5jbGFzcyBNYW5pZmVzdCB7XG4gICAgLyoqXG4gICAgICogRGVmaW5lIGNsYXNzZXMgaW4gdGhlIG1hbmlmZXN0IChmcmFtZXdvcmsgaW50ZXJuYWwpXG4gICAgICogQHBhcmFtIHtBcnJheX0gaXRlbXMgLSBBcnJheSBvZiBjbGFzcyBkZWZpbml0aW9ucyBbW0NsYXNzLCBcIkNsYXNzTmFtZVwiLCBQYXJlbnRDbGFzcywgZGVjb3JhdG9yc10sIC4uLl1cbiAgICAgKi9cbiAgICBzdGF0aWMgX2RlZmluZShpdGVtcykge1xuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBjbGFzc2VzIG9iamVjdCBpZiBub3QgYWxyZWFkeSBkZWZpbmVkXG4gICAgICAgIGlmICh0eXBlb2YgTWFuaWZlc3QuX2NsYXNzZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBNYW5pZmVzdC5fY2xhc3NlcyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyBlYWNoIGNsYXNzIGRlZmluaXRpb25cbiAgICAgICAgaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgbGV0IGNsYXNzX29iamVjdCA9IGl0ZW1bMF07XG4gICAgICAgICAgICBsZXQgY2xhc3NfbmFtZSA9IGl0ZW1bMV07XG4gICAgICAgICAgICBsZXQgY2xhc3NfZXh0ZW5kcyA9IGl0ZW1bMl0gfHwgbnVsbDtcbiAgICAgICAgICAgIGxldCBkZWNvcmF0b3JzID0gaXRlbVszXSB8fCBudWxsO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgY2xhc3MgaW5mb3JtYXRpb24gKHVzaW5nIG9iamVjdCB0byBhdm9pZCBkdXBsaWNhdGVzKVxuICAgICAgICAgICAgTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV0gPSB7XG4gICAgICAgICAgICAgICAgY2xhc3M6IGNsYXNzX29iamVjdCxcbiAgICAgICAgICAgICAgICBuYW1lOiBjbGFzc19uYW1lLFxuICAgICAgICAgICAgICAgIGV4dGVuZHM6IGNsYXNzX2V4dGVuZHMsXG4gICAgICAgICAgICAgICAgZGVjb3JhdG9yczogZGVjb3JhdG9ycywgIC8vIFN0b3JlIGNvbXBhY3QgZGVjb3JhdG9yIGRhdGFcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIEFkZCBtZXRhZGF0YSB0byB0aGUgY2xhc3Mgb2JqZWN0IGl0c2VsZlxuICAgICAgICAgICAgY2xhc3Nfb2JqZWN0Ll9uYW1lID0gY2xhc3NfbmFtZTtcbiAgICAgICAgICAgIGNsYXNzX29iamVjdC5fZXh0ZW5kcyA9IGNsYXNzX2V4dGVuZHM7XG4gICAgICAgICAgICBjbGFzc19vYmplY3QuX2RlY29yYXRvcnMgPSBkZWNvcmF0b3JzO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBCdWlsZCB0aGUgc3ViY2xhc3MgaW5kZXggYWZ0ZXIgYWxsIGNsYXNzZXMgYXJlIGRlZmluZWRcbiAgICAgICAgTWFuaWZlc3QuX2J1aWxkX3N1YmNsYXNzX2luZGV4KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYW4gaW5kZXggb2Ygc3ViY2xhc3NlcyBmb3IgZWZmaWNpZW50IGxvb2t1cHNcbiAgICAgKiBUaGlzIGNyZWF0ZXMgYSBtYXBwaW5nIHdoZXJlIGVhY2ggY2xhc3MgbmFtZSBwb2ludHMgdG8gYW4gYXJyYXkgb2YgYWxsIGl0cyBzdWJjbGFzc2VzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2J1aWxkX3N1YmNsYXNzX2luZGV4KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBzdWJjbGFzcyBpbmRleFxuICAgICAgICBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXggPSB7fTtcblxuICAgICAgICAvLyBTdGVwIHRocm91Z2ggZWFjaCBjbGFzcyBhbmQgd2FsayB1cCBpdHMgcGFyZW50IGNoYWluXG4gICAgICAgIGZvciAobGV0IGNsYXNzX25hbWUgaW4gTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRfY2xhc3NfbmFtZSA9IGNsYXNzX25hbWU7XG4gICAgICAgICAgICBsZXQgY3VycmVudF9jbGFzc2RhdGEgPSBjbGFzc2RhdGE7XG5cbiAgICAgICAgICAgIC8vIFdhbGsgdXAgdGhlIHBhcmVudCBjaGFpbiB1bnRpbCB3ZSByZWFjaCB0aGUgcm9vdFxuICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnRfY2xhc3NkYXRhKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5kc19uYW1lID0gY3VycmVudF9jbGFzc2RhdGEuZXh0ZW5kcztcblxuICAgICAgICAgICAgICAgIGlmIChleHRlbmRzX25hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgcGFyZW50J3Mgc3ViY2xhc3MgYXJyYXkgaWYgbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGlmICghTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4W2V4dGVuZHNfbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleFtleHRlbmRzX25hbWVdID0gW107XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhpcyBjbGFzcyB0byBpdHMgcGFyZW50J3Mgc3ViY2xhc3MgbGlzdFxuICAgICAgICAgICAgICAgICAgICBpZiAoIU1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleFtleHRlbmRzX25hbWVdLmluY2x1ZGVzKGNsYXNzX25hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXhbZXh0ZW5kc19uYW1lXS5wdXNoKGNsYXNzX25hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTW92ZSB1cCB0byB0aGUgcGFyZW50J3MgbWV0YWRhdGEgKGlmIGl0IGV4aXN0cyBpbiBtYW5pZmVzdClcbiAgICAgICAgICAgICAgICAgICAgaWYgKE1hbmlmZXN0Ll9jbGFzc2VzW2V4dGVuZHNfbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfY2xhc3NkYXRhID0gTWFuaWZlc3QuX2NsYXNzZXNbZXh0ZW5kc19uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcmVudCBub3QgaW4gbWFuaWZlc3QgKGUuZy4sIG5hdGl2ZSBKYXZhU2NyaXB0IGNsYXNzKSwgc3RvcCBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzZGF0YSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBObyBwYXJlbnQsIHdlJ3ZlIHJlYWNoZWQgdGhlIHJvb3RcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudF9jbGFzc2RhdGEgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgY2xhc3NlcyB0aGF0IGV4dGVuZCBhIGdpdmVuIGJhc2UgY2xhc3NcbiAgICAgKiBAcGFyYW0ge0NsYXNzfHN0cmluZ30gYmFzZV9jbGFzcyAtIFRoZSBiYXNlIGNsYXNzIChvYmplY3Qgb3IgbmFtZSBzdHJpbmcpIHRvIGNoZWNrIGZvclxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2Ygb2JqZWN0cyB3aXRoIHtjbGFzc19uYW1lLCBjbGFzc19vYmplY3R9IGZvciBjbGFzc2VzIHRoYXQgZXh0ZW5kIHRoZSBiYXNlIGNsYXNzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9leHRlbmRpbmcoYmFzZV9jbGFzcykge1xuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9jbGFzc2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBjbGFzcyBvYmplY3QgaWYgbmVlZGVkXG4gICAgICAgIGxldCBiYXNlX2NsYXNzX29iamVjdCA9IGJhc2VfY2xhc3M7XG4gICAgICAgIGlmICh0eXBlb2YgYmFzZV9jbGFzcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGJhc2VfY2xhc3Nfb2JqZWN0ID0gTWFuaWZlc3QuZ2V0X2NsYXNzX2J5X25hbWUoYmFzZV9jbGFzcyk7XG4gICAgICAgICAgICBpZiAoIWJhc2VfY2xhc3Nfb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBCYXNlIGNsYXNzIG5vdCBmb3VuZDogJHtiYXNlX2NsYXNzfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGNsYXNzX25hbWUgaW4gTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICAgICAgaWYgKE1hbmlmZXN0LmpzX2lzX3N1YmNsYXNzX29mKGNsYXNzZGF0YS5jbGFzcywgYmFzZV9jbGFzc19vYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NfbmFtZTogY2xhc3NfbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3Nfb2JqZWN0OiBjbGFzc2RhdGEuY2xhc3MsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IGFscGhhYmV0aWNhbGx5IGJ5IGNsYXNzIG5hbWUgdG8gZW5zdXJlIGRldGVybWluaXN0aWMgYmVoYXZpb3IgYW5kIHByZXZlbnQgcmFjZSBjb25kaXRpb24gYnVnc1xuICAgICAgICBjbGFzc2VzLnNvcnQoKGEsIGIpID0+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+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ0pRSFRNTF9JTklUJywgYEluaXRpYWxpemluZyAke2NvbXBvbmVudHNfbmVlZGluZ19pbml0Lmxlbmd0aH0gRE9NIGNvbXBvbmVudHNgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbXBvbmVudHNfbmVlZGluZ19pbml0LmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuXG4gICAgICAgICAgICAvLyBTa2lwIGlmIGVsZW1lbnQgaXMgbm8gbG9uZ2VyIGF0dGFjaGVkIHRvIHRoZSBkb2N1bWVudFxuICAgICAgICAgICAgLy8gKG1heSBoYXZlIGJlZW4gcmVtb3ZlZCBieSBhIHBhcmVudCBjb21wb25lbnQncyAuZW1wdHkoKSBjYWxsKVxuICAgICAgICAgICAgaWYgKCFkb2N1bWVudC5jb250YWlucygkZWxlbWVudFswXSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGFueSBwYXJlbnQgaGFzIEpxaHRtbF9Db21wb25lbnRfSW5pdCBjbGFzcyAtIHNraXAgbmVzdGVkIGNvbXBvbmVudHNcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSAkZWxlbWVudFswXS5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdKcWh0bWxfQ29tcG9uZW50X0luaXQnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47IC8vIFNraXAgdGhpcyBlbGVtZW50LCBpdCdzIG5lc3RlZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50X25hbWUgPSAkZWxlbWVudC5hdHRyKCdkYXRhLWNvbXBvbmVudC1pbml0LW5hbWUnKTtcblxuICAgICAgICAgICAgLy8galF1ZXJ5J3MgLmRhdGEoKSBkb2Vzbid0IGF1dG8tcGFyc2UgSlNPTiAtIHdlIG5lZWQgdG8gcGFyc2UgaXQgbWFudWFsbHlcbiAgICAgICAgICAgIGxldCBjb21wb25lbnRfYXJncyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgYXJnc19zdHJpbmcgPSAkZWxlbWVudC5hdHRyKCdkYXRhLWNvbXBvbmVudC1hcmdzJyk7XG5cbiAgICAgICAgICAgIC8vIFVuc2V0IGNvbXBvbmVudC0gcGhwIHNpZGUgaW5pdGlhbGl6YXRpb24gYXJncywgaXQgaXMgbm8gbG9uZ2VyIG5lZWRlZCBhcyBhIGNvbXBpb25lbnQgYXR0cmlidXRlXG4gICAgICAgICAgICAvLyBVbnNldHRpbmcgYWxzbyBwcmV2ZW50cyB1bmRlc2lyZWQgYWNjZXNzIHRvIHRoaXMgY29kZSBpbiBvdGhlciBwYXJ0cyBvZiB0aGUgcHJvZ3JhbSwgcHJldmVuaW5nIGFuXG4gICAgICAgICAgICAvLyB1bndhbnRlZCBmdXR1cmUgZGVwZW5kZW5jeSBvbiB0aGlzIHBhcmFkaWdtXG4gICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVBdHRyKCdkYXRhLWNvbXBvbmVudC1pbml0LW5hbWUnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZUF0dHIoJ2RhdGEtY29tcG9uZW50LWFyZ3MnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZURhdGEoJ2NvbXBvbmVudC1pbml0LW5hbWUnKTtcbiAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZURhdGEoJ2NvbXBvbmVudC1hcmdzJyk7XG5cbiAgICAgICAgICAgIGlmIChhcmdzX3N0cmluZykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzID0gSlNPTi5wYXJzZShhcmdzX3N0cmluZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbSlFIVE1MIEludGVncmF0aW9uXSBGYWlsZWQgdG8gcGFyc2UgY29tcG9uZW50IGFyZ3MgZm9yICR7Y29tcG9uZW50X25hbWV9OmAsIGUpO1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJncyA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbXBvbmVudF9uYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJhbnNmb3JtICQgcHJlZml4ZWQga2V5cyB0byBkYXRhLSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkID0ge307XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29tcG9uZW50X2FyZ3MpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChrZXkuc3RhcnRzV2l0aCgnJCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkW2tleS5zdWJzdHJpbmcoMSldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ2RhdGEtJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkW2tleS5zdWJzdHJpbmcoNSldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJnc19maWx0ZXJlZFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSBpbm5lciBIVE1MIGFzIHN0cmluZyBmb3IgbmVzdGVkIGNvbXBvbmVudCBwcm9jZXNzaW5nXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzX2ZpbHRlcmVkLl9pbm5lcl9odG1sID0gJGVsZW1lbnQuaHRtbCgpO1xuICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5lbXB0eSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgaW5pdCBjbGFzcyBiZWZvcmUgaW5zdGFudGlhdGlvbiB0byBwcmV2ZW50IHJlLWluaXRpYWxpemF0aW9uXG4gICAgICAgICAgICAgICAgICAgICRlbGVtZW50LnJlbW92ZUNsYXNzKCdKcWh0bWxfQ29tcG9uZW50X0luaXQnKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgcHJvbWlzZSBmb3IgdGhpcyBjb21wb25lbnQncyBpbml0aWFsaXphdGlvblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wb25lbnRfcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgalF1ZXJ5IGNvbXBvbmVudCBwbHVnaW4gdG8gY3JlYXRlIHRoZSBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsdWdpbiBoYW5kbGVzIGVsZW1lbnQgaW50ZXJuYWxseSwganVzdCBwYXNzIGFyZ3NcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgdXBkYXRlZCAkZWxlbWVudCBmcm9tXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJGVsZW1lbnQuY29tcG9uZW50KGNvbXBvbmVudF9uYW1lLCBjb21wb25lbnRfYXJnc19maWx0ZXJlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudC5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbGxlY3QgcHJvbWlzZXMgZnJvbSBuZXN0ZWQgY29tcG9uZW50c1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0dGluZyB0aGUgdXBkYXRlZCBjb21wb25lbnQgaGVyZSAtIGlmIHRoZSB0YWcgbmFtZSB3YXMgbm90IGRpdiwgdGhlIGVsZW1lbnQgd291bGQgaGF2ZSBiZWVuIHJlY3JlYXRlZCwgc28gd2UgbmVlZCB0byBnZXQgdGhlIGVsZW1lbnQgc2V0IG9uIHRoZSBjb21wb25lbnQsIG5vdCBmcm9tIG91ciBlYXJsaWVyIHNlbGVjdG9yXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXN0ZWRfcHJvbWlzZXMgPSBKcWh0bWxfSW50ZWdyYXRpb24uX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQoY29tcG9uZW50LiQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goLi4ubmVzdGVkX3Byb21pc2VzKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgdGhpcyBjb21wb25lbnQncyBwcm9taXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkuJDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjb21wb25lbnRfcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTCBJbnRlZ3JhdGlvbl0gRmFpbGVkIHRvIGluaXRpYWxpemUgY29tcG9uZW50ICR7Y29tcG9uZW50X25hbWV9OmAsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZGV0YWlsczonLCBlcnJvci5zdGFjayB8fCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUb3AtbGV2ZWwgY2FsbDogc3Bhd24gYXN5bmMgaGFuZGxlciB0byB3YWl0IGZvciBhbGwgcHJvbWlzZXMsIHRoZW4gdHJpZ2dlciBldmVudFxuICAgICAgICBpZiAoaXNfdG9wX2xldmVsKSB7XG4gICAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBSc3guX3JzeF9jYWxsX2FsbF9jbGFzc2VzKCdvbl9qcWh0bWxfcmVhZHknKTtcbiAgICAgICAgICAgICAgICBSc3gudHJpZ2dlcignanFodG1sX3JlYWR5Jyk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVjdXJzaXZlIGNhbGw6IHJldHVybiBwcm9taXNlcyBmb3IgcGFyZW50IHRvIGNvbGxlY3RcbiAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgcmVnaXN0ZXJlZCBjb21wb25lbnQgbmFtZXNcbiAgICAgKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gQXJyYXkgb2YgY29tcG9uZW50IG5hbWVzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9jb21wb25lbnRfbmFtZXMoKSB7XG4gICAgICAgIHJldHVybiBqcWh0bWwuZ2V0X2NvbXBvbmVudF9uYW1lcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGEgY29tcG9uZW50IGlzIHJlZ2lzdGVyZWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBDb21wb25lbnQgbmFtZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGNvbXBvbmVudCBpcyByZWdpc3RlcmVkXG4gICAgICovXG4gICAgc3RhdGljIGhhc19jb21wb25lbnQobmFtZSkge1xuICAgICAgICByZXR1cm4ganFodG1sLmhhc19jb21wb25lbnQobmFtZSk7XG4gICAgfVxufVxuXG4vLyBSU1ggbWFuaWZlc3QgYXV0b21hdGljYWxseSBtYWtlcyBjbGFzc2VzIGdsb2JhbCAtIG5vIG1hbnVhbCBhc3NpZ25tZW50IG5lZWRlZFxuIiwiLyoqXG4gKiBEYXRhR3JpZCBDb21wb25lbnQgKFBoYXNlIDEpXG4gKlxuICogRHVlIHRvIHRoZSBtb3JlIGR5bmFtaWMgbmF0dXJlIG9mIHRoaXMgY29tcG9uZW50LCB3ZSBhcmUgaGFuZGxpbmcgbG9hZCAvIHJlbmRlciBsaWZlY3ljbGVzXG4gKiBkaXJlY3RseSBpbiB0aGlzIGNsYXNzIHJhdGhlciB0aGFuIHVzaW5nIHRoZSBvbl9sb2FkIGxpZmVjeWNsZSBldmVudFxuICpcbiAqICoqRmVhdHVyZXMqKjpcbiAqIC0gQWpheCBkYXRhIGZldGNoaW5nXG4gKiAtIFNvcnRpbmcgKGNsaWNrIGhlYWRlcnMpXG4gKiAtIFBhZ2luYXRpb24gKG5leHQvcHJldi9wYWdlIHNlbGVjdClcbiAqIC0gUm93IHNlbGVjdGlvbiAoY2hlY2tib3hlcylcbiAqIC0gQ1NWIGV4cG9ydCAoc2VsZWN0ZWQgcm93cywgY3VycmVudCBwYWdlKVxuICogLSBVUkwgc3RhdGUgc3luY2hyb25pemF0aW9uXG4gKlxuICogKipVc2FnZSoqOlxuICogYGBgaHRtbFxuICogPENvbnRhY3RzX0RhdGFHcmlkICRhcGk9XCJGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyXCIgLz5cbiAqIGBgYFxuICpcbiAqICoqUmVxdWlyZWQgQXJncyoqOlxuICogLSBgYXBpYCAtIENvbnRyb2xsZXIgY2xhc3MgbmFtZSB3aXRoIGRhdGFncmlkX2ZldGNoKCkgQWpheCBlbmRwb2ludFxuICpcbiAqICoqT3B0aW9uYWwgQXJncyoqOlxuICogLSBgcGVyX3BhZ2VgIC0gRGVmYXVsdCByb3dzIHBlciBwYWdlIChkZWZhdWx0OiAyNSlcbiAqIC0gYHNvcnRgIC0gRGVmYXVsdCBzb3J0IGNvbHVtbiAoZGVmYXVsdDogZmlyc3QgY29sdW1uKVxuICogLSBgb3JkZXJgIC0gRGVmYXVsdCBzb3J0IG9yZGVyIChkZWZhdWx0OiAnYXNjJylcbiAqL1xuY2xhc3MgRGF0YUdyaWRfQWJzdHJhY3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBJbml0aWFsaXplIGRhdGEgYmVmb3JlIGZpcnN0IHJlbmRlclxuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgZGF0YSBzdGF0ZSBpbW1lZGlhdGVseSBzbyB0ZW1wbGF0ZSBjYW4gcmVuZGVyXG4gICAgICAgIHRoYXQuZGF0YS5yb3dzID0gW107XG4gICAgICAgIHRoYXQuZGF0YS5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhhdC5kYXRhLmlzX2VtcHR5ID0gZmFsc2U7XG4gICAgICAgIHRoYXQuZGF0YS5sb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgdGhhdC5kYXRhLnRvdGFsX3BhZ2VzID0gMDtcbiAgICB9XG5cbiAgICAvLyBDYWxscyB3aGVuIGRhdGFncmlkIGZpcnN0IGluaXRpYWxpemVkXG4gICAgYXN5bmMgb25fcmVhZHkoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICBpZiAoIXRoYXQuYXJncy5kYXRhX3NvdXJjZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRGF0YWdyaWQgJyArIHRoYXQuY29tcG9uZW50X25hbWUoKSArICcgcmVxdWlyZXMgYXJncy5kYXRhX3NvdXJjZSBzZXQgdG8gYSBBamF4X0VuZHBvaW50IG9iamVjdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RvcmUgZGVmYXVsdHMgZm9yIGxhdGVyIGNvbXBhcmlzb25cbiAgICAgICAgdGhhdC5kYXRhLmRlZmF1bHRfcGFnZSA9IDE7XG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X3Blcl9wYWdlID0gdGhhdC5hcmdzLnBlcl9wYWdlID8/IDE1O1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0ID0gdGhhdC5hcmdzLnNvcnQgPz8gbnVsbDtcbiAgICAgICAgdGhhdC5kYXRhLmRlZmF1bHRfb3JkZXIgPSB0aGF0LmFyZ3Mub3JkZXIgPz8gJ2FzYyc7XG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X2ZpbHRlciA9ICcnO1xuXG4gICAgICAgIC8vIFNldCBjb25maWd1cmVkIHZhbHVlc1xuICAgICAgICB0aGF0LmRhdGEucGVyX3BhZ2UgPSB0aGF0LmRhdGEuZGVmYXVsdF9wZXJfcGFnZTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHN0YXRlIGZyb20gVVJMIGhhc2ggaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHVzZSBkZWZhdWx0c1xuICAgICAgICBjb25zdCBoYXNoX3BhZ2UgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19wYWdlJyk7XG4gICAgICAgIGNvbnN0IGhhc2hfc29ydCA9IFJzeC5nZXRfcGFnZV9zdGF0ZSh0aGF0Ll9jaWQgKyAnX3NvcnQnKTtcbiAgICAgICAgY29uc3QgaGFzaF9vcmRlciA9IFJzeC5nZXRfcGFnZV9zdGF0ZSh0aGF0Ll9jaWQgKyAnX29yZGVyJyk7XG4gICAgICAgIGNvbnN0IGhhc2hfZmlsdGVyID0gUnN4LmdldF9wYWdlX3N0YXRlKHRoYXQuX2NpZCArICdfZmlsdGVyJyk7XG5cbiAgICAgICAgdGhhdC5kYXRhLnBhZ2UgPSBoYXNoX3BhZ2UgPyBpbnQoaGFzaF9wYWdlKSA6IHRoYXQuZGF0YS5kZWZhdWx0X3BhZ2U7XG4gICAgICAgIHRoYXQuZGF0YS5zb3J0ID0gaGFzaF9zb3J0IHx8IHRoYXQuZGF0YS5kZWZhdWx0X3NvcnQ7XG4gICAgICAgIHRoYXQuZGF0YS5vcmRlciA9IGhhc2hfb3JkZXIgfHwgdGhhdC5kYXRhLmRlZmF1bHRfb3JkZXI7XG4gICAgICAgIHRoYXQuZGF0YS5maWx0ZXIgPSBoYXNoX2ZpbHRlciB8fCB0aGF0LmRhdGEuZGVmYXVsdF9maWx0ZXI7XG5cbiAgICAgICAgdGhhdC5yZWdpc3Rlcl9yZW5kZXJfY2FsbGJhY2tzKCk7XG4gICAgICAgIHRoYXQucmVnaXN0ZXJfZmlsdGVyX2hhbmRsZXJzKCk7XG5cbiAgICAgICAgLy8gSWYgaGFzaCBoYWQgYSBmaWx0ZXIgdmFsdWUsIHBvcHVsYXRlIHRoZSBmaWx0ZXIgaW5wdXRcbiAgICAgICAgaWYgKHRoYXQuZGF0YS5maWx0ZXIpIHtcbiAgICAgICAgICAgIGNvbnN0ICRmaWx0ZXIgPSB0aGF0LiRpZCgnZmlsdGVyX2lucHV0Jyk7XG4gICAgICAgICAgICBpZiAoJGZpbHRlciAmJiAkZmlsdGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAkZmlsdGVyLnZhbCh0aGF0LmRhdGEuZmlsdGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1lYXN1cmUgcm93IGhlaWdodCBhbmQgc2V0IGZpeGVkIHRib2R5IGhlaWdodCAoYWxsIGluIG9uZSBmcmFtZSlcbiAgICAgICAgYXdhaXQgdGhhdC5tZWFzdXJlX2FuZF9zZXRfZml4ZWRfaGVpZ2h0KCk7XG5cbiAgICAgICAgLy8gRmV0Y2ggdGhlIGluaXRpYWwgcGFnZSAocmVzcGVjdHMgaGFzaCBzdGF0ZSlcbiAgICAgICAgdGhhdC5sb2FkX3BhZ2UodGhhdC5kYXRhLnBhZ2UpO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBoZWFkZXIgb25seSBpZiBzb3J0L29yZGVyIGNoYW5nZWRcbiAgICB1cGRhdGVfaGVhZGVyKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gVHJhY2sgbGFzdCByZW5kZXJlZCBzdGF0ZVxuICAgICAgICBpZiAoIXRoYXQuX2xhc3RfaGVhZGVyX3N0YXRlKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZSA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3VycmVudCA9IHtcbiAgICAgICAgICAgIHNvcnQ6IHRoYXQuZGF0YS5zb3J0LFxuICAgICAgICAgICAgb3JkZXI6IHRoYXQuZGF0YS5vcmRlcixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBPbmx5IHJlbmRlciBpZiB2YWx1ZXMgY2hhbmdlZFxuICAgICAgICBpZiAodGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUuc29ydCAhPT0gY3VycmVudC5zb3J0IHx8IHRoYXQuX2xhc3RfaGVhZGVyX3N0YXRlLm9yZGVyICE9PSBjdXJyZW50Lm9yZGVyKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZSA9IGN1cnJlbnQ7XG4gICAgICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBwYWdpbmF0aW9uIG9ubHkgaWYgdmFsdWVzIGNoYW5nZWRcbiAgICB1cGRhdGVfcGFnaW5hdGlvbigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRyYWNrIGxhc3QgcmVuZGVyZWQgc3RhdGVcbiAgICAgICAgaWYgKCF0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUpIHtcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZSA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3VycmVudCA9IHtcbiAgICAgICAgICAgIHBhZ2U6IHRoYXQuZGF0YS5wYWdlLFxuICAgICAgICAgICAgcGVyX3BhZ2U6IHRoYXQuZGF0YS5wZXJfcGFnZSxcbiAgICAgICAgICAgIHRvdGFsOiB0aGF0LmRhdGEudG90YWwsXG4gICAgICAgICAgICB0b3RhbF9wYWdlczogdGhhdC5kYXRhLnRvdGFsX3BhZ2VzLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE9ubHkgcmVuZGVyIGlmIHZhbHVlcyBjaGFuZ2VkXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZS5wYWdlICE9PSBjdXJyZW50LnBhZ2UgfHxcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZS5wZXJfcGFnZSAhPT0gY3VycmVudC5wZXJfcGFnZSB8fFxuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlLnRvdGFsICE9PSBjdXJyZW50LnRvdGFsIHx8XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUudG90YWxfcGFnZXMgIT09IGN1cnJlbnQudG90YWxfcGFnZXNcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUgPSBjdXJyZW50O1xuICAgICAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9pbmZvJykucmVuZGVyKCk7XG4gICAgICAgICAgICB0aGF0LmlkKCdwYWdpbmF0aW9uX2NvbnRyb2xzJykucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMb2FkIGRhdGEgZm9yIHNwZWNpZmllZCBwYWdlIGFuZCByZS1yZW5kZXIgZGF0YVxuICAgIGFzeW5jIGxvYWRfcGFnZShwYWdlKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBTZXQgbG9hZGluZyBzdGF0ZVxuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoYXQuZGF0YS5wYWdlID0gcGFnZTtcblxuICAgICAgICAvLyBVcGRhdGUgVUkgd2l0aCByZXF1ZXN0ZWQgdmFsdWVzIChvcHRpbWlzdGljIHVwZGF0ZSlcbiAgICAgICAgdGhhdC51cGRhdGVfaGVhZGVyKCk7XG4gICAgICAgIHRoYXQudXBkYXRlX3BhZ2luYXRpb24oKTtcblxuICAgICAgICAvLyBPbmx5IHJlbmRlciBsb2FkaW5nIHN0YXRlIGlmIG5vIGRhdGEgeWV0IChpbml0aWFsIGxvYWQpXG4gICAgICAgIGlmICh0aGF0LmRhdGEucm93cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5yZW5kZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgQWpheC5jYWxsKHRoYXQuYXJncy5kYXRhX3NvdXJjZSwge1xuICAgICAgICAgICAgcGFnZTogcGFnZSxcbiAgICAgICAgICAgIHBlcl9wYWdlOiB0aGF0LmRhdGEucGVyX3BhZ2UsXG4gICAgICAgICAgICBzb3J0OiB0aGF0LmRhdGEuc29ydCxcbiAgICAgICAgICAgIG9yZGVyOiB0aGF0LmRhdGEub3JkZXIsXG4gICAgICAgICAgICBmaWx0ZXI6IHRoYXQuZGF0YS5maWx0ZXIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBkYXRhXG4gICAgICAgIHRoYXQuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoYXQuZGF0YS5sb2FkZWQgPSB0cnVlO1xuICAgICAgICB0aGF0LmRhdGEucm93cyA9IHJlc3BvbnNlLnJlY29yZHM7XG4gICAgICAgIHRoYXQuZGF0YS5wYWdlID0gcmVzcG9uc2UucGFnZTtcbiAgICAgICAgdGhhdC5kYXRhLnBlcl9wYWdlID0gcmVzcG9uc2UucGVyX3BhZ2U7XG4gICAgICAgIHRoYXQuZGF0YS50b3RhbCA9IHJlc3BvbnNlLnRvdGFsO1xuICAgICAgICB0aGF0LmRhdGEudG90YWxfcGFnZXMgPSByZXNwb25zZS50b3RhbF9wYWdlcztcbiAgICAgICAgdGhhdC5kYXRhLnNvcnQgPSByZXNwb25zZS5zb3J0O1xuICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSByZXNwb25zZS5vcmRlcjtcbiAgICAgICAgdGhhdC5kYXRhLmlzX2VtcHR5ID0gcmVzcG9uc2UucmVjb3Jkcy5sZW5ndGggPT09IDA7XG5cbiAgICAgICAgLy8gUGVyc2lzdCBzdGF0ZSB0byBVUkwgaGFzaCBmb3IgYm9va21hcmtpbmcvc2hhcmluZ1xuICAgICAgICAvLyBPbmx5IHNldCB2YWx1ZXMgdGhhdCBkaWZmZXIgZnJvbSBkZWZhdWx0cyAobnVsbCByZW1vdmVzIHRoZSBrZXkpXG4gICAgICAgIGNvbnN0IHN0YXRlID0ge307XG4gICAgICAgIHN0YXRlW3RoYXQuX2NpZCArICdfcGFnZSddID0gdGhhdC5kYXRhLnBhZ2UgIT09IHRoYXQuZGF0YS5kZWZhdWx0X3BhZ2UgPyB0aGF0LmRhdGEucGFnZSA6IG51bGw7XG4gICAgICAgIHN0YXRlW3RoYXQuX2NpZCArICdfc29ydCddID0gdGhhdC5kYXRhLnNvcnQgIT09IHRoYXQuZGF0YS5kZWZhdWx0X3NvcnQgPyB0aGF0LmRhdGEuc29ydCA6IG51bGw7XG4gICAgICAgIHN0YXRlW3RoYXQuX2NpZCArICdfb3JkZXInXSA9IHRoYXQuZGF0YS5vcmRlciAhPT0gdGhhdC5kYXRhLmRlZmF1bHRfb3JkZXIgPyB0aGF0LmRhdGEub3JkZXIgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX2ZpbHRlciddID0gdGhhdC5kYXRhLmZpbHRlciAhPT0gdGhhdC5kYXRhLmRlZmF1bHRfZmlsdGVyID8gdGhhdC5kYXRhLmZpbHRlciA6IG51bGw7XG5cbiAgICAgICAgUnN4LnNldF9hbGxfcGFnZV9zdGF0ZShzdGF0ZSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIFVJIHdpdGggc2VydmVyIHJlc3BvbnNlIChvbmx5IHJlbmRlcnMgaWYgY2hhbmdlZClcbiAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfYm9keScpLnJlbmRlcigpO1xuICAgICAgICB0aGF0LnVwZGF0ZV9oZWFkZXIoKTtcbiAgICAgICAgdGhhdC51cGRhdGVfcGFnaW5hdGlvbigpO1xuXG4gICAgICAgIC8vIFNjcm9sbCB0byB0b3Agb2YgZGF0YWdyaWQgaWYgaXQncyBub3QgY3VycmVudGx5IHZpc2libGVcbiAgICAgICAgdGhhdC5zY3JvbGxfdG9fdG9wX2lmX25lZWRlZCgpO1xuICAgIH1cblxuICAgIC8vIFRoZSBjYWxsYmFja3MgaW4gdGhpcyBmdW5jdGlvbiBmaXJlIGFmdGVyIGVhY2ggdGFyZ2V0ZWQgY29tcG9uZW50IHJlLXJlbmRlcnNcbiAgICByZWdpc3Rlcl9yZW5kZXJfY2FsbGJhY2tzKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gQXR0YWNoIHJvdyBjbGljayBoYW5kbGVyIC0gcmUtcnVucyBldmVyeSB0aW1lIGRhdGFncmlkX3RhYmxlX2JvZHkgcmVuZGVyc1xuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5Jykub24oJ3JlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdER1RCX1InKTtcbiAgICAgICAgICAgIC8vIFN0ZXAgMTogV3JhcCBjZWxscyBpbiBkYXRhLWhyZWYgcm93cyB3aXRoIGFuY2hvciB0YWdzXG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ3RyW2RhdGEtaHJlZl0nKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICRyb3cgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgaHJlZiA9ICRyb3cuYXR0cignZGF0YS1ocmVmJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgJHJvdy5maW5kKCd0ZCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGV0ICRjb2wgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gLy8gU2tpcCBpZiBjZWxsIGFscmVhZHkgY29udGFpbnMgaW50ZXJhY3RpdmUgZWxlbWVudHNcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmICgkY29sLmZpbmQoJ2EsIGJ1dHRvbiwgaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gLy8gV3JhcCBlbnRpcmUgY2VsbCBjb250ZW50cyBpbiBhbiBhbmNob3IgKHByZXNlcnZlIERPTSBub2RlcyBmb3IgY29tcG9uZW50IGxpZmVjeWNsZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxldCAkYW5jaG9yID0gJCgnPGE+Jywge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGhyZWY6IGhyZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgY2xhc3M6ICdkYXRhZ3JpZC1yb3ctbGluaydcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gLy8gTW92ZSBleGlzdGluZyBjaGlsZCBub2RlcyBpbnRvIGFuY2hvciAocHJlc2VydmVzIGNvbXBvbmVudHMgYW5kIHRoZWlyIHN0YXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gJGNvbC5jb250ZW50cygpLmFwcGVuZFRvKCRhbmNob3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gLy8gQWRkIGFuY2hvciB0byBjZWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAkY29sLmFwcGVuZCgkYW5jaG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFN0ZXAgMjogRmluZCBhbGwgY2VsbHMgd2l0aCBzaW5nbGUgYW5jaG9yIGFzIG9ubHkgY2hpbGQgYW5kIGFwcGx5IGZ1bGwtd2lkdGggc3R5bGluZ1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0ZCcpXG4gICAgICAgICAgICAgICAgLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGNvbCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCAkY2hpbGRyZW4gPSAkY29sLmNoaWxkcmVuKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2VsbCBjb250YWlucyBleGFjdGx5IG9uZSBkaXJlY3QgY2hpbGQgdGhhdCBpcyBhbiBhbmNob3JcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRjaGlsZHJlbi5sZW5ndGggPT09IDEgJiYgJGNoaWxkcmVuLmZpcnN0KCkuaXMoJ2EnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGNsYXNzIHRvIHRyYW5zZmVyIHBhZGRpbmcgZnJvbSBjZWxsIHRvIGFuY2hvclxuICAgICAgICAgICAgICAgICAgICAgICAgJGNvbC5hZGRDbGFzcygnaGFzLWZ1bGwtbGluaycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNlbGwgY29udGFpbnMgb25seSB0ZXh0IChubyBjaGlsZCBlbGVtZW50cylcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoJGNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGNsYXNzIHRvIGFwcGx5IHZlcnRpY2FsIHBhZGRpbmcgdG8gdGV4dC1vbmx5IGNlbGxzXG4gICAgICAgICAgICAgICAgICAgICAgICAkY29sLmFkZENsYXNzKCdoYXMtb25seS10ZXh0Jyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXR0YWNoIHNvcnRhYmxlIGhlYWRlciBjbGljayBoYW5kbGVyIC0gcmUtcnVucyBldmVyeSB0aW1lIGRhdGFncmlkX3RhYmxlX2hlYWRlciByZW5kZXJzXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2hlYWRlcicpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBUcmFuc2Zvcm0gdGhbZGF0YS1zb3J0YnldIGVsZW1lbnRzIGJ5IHdyYXBwaW5nIGNvbnRlbnRzIGluIGNsaWNrYWJsZSBsaW5rXG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ3RoW2RhdGEtc29ydGJ5XScpXG4gICAgICAgICAgICAgICAgLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgJHRoID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHNvcnRieSA9ICR0aC5hdHRyKCdkYXRhLXNvcnRieScpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IEZpbmQgb3V0IHdoeSB0aGlzIG9uKCdyZW5kZXInKSBjYWxsYmFjayBpcyBiZWluZyBjYWxsZWQgdHdpY2Uvb24gYWxyZWFkeS1wcm9jZXNzZWQgSFRNTFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHVud3JhcCBsb2dpYyBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5IC0gdGVtcGxhdGUgc2hvdWxkIHJlbmRlciBmcmVzaCBlYWNoIHRpbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIG5vdywgdW53cmFwIGFscmVhZHktd3JhcHBlZCBjb250ZW50IHRvIHByZXZlbnQgZG91YmxlLXdyYXBwaW5nXG4gICAgICAgICAgICAgICAgICAgIGxldCAkZXhpc3RpbmdfbGluayA9ICR0aC5maW5kKCdhLnNvcnRhYmxlLWhlYWRlcicpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgY29udGVudHM7XG4gICAgICAgICAgICAgICAgICAgIGlmICgkZXhpc3RpbmdfbGluay5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVbndyYXAgLSBnZXQgdGhlIHRleHQgY29udGVudCB3aXRob3V0IHRoZSB3cmFwcGVyIGFuZCBhcnJvd3NcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gJGV4aXN0aW5nX2xpbmsuY2xvbmUoKS5maW5kKCdpLmJpJykucmVtb3ZlKCkuZW5kKCkuaHRtbCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudHMgPSAkdGguaHRtbCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVpbGQgdGhlIGFycm93IGljb24gSFRNTCBpZiB0aGlzIGNvbHVtbiBpcyBjdXJyZW50bHkgc29ydGVkXG4gICAgICAgICAgICAgICAgICAgIGxldCBhcnJvdyA9ICcnO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5kYXRhLnNvcnQgPT09IHNvcnRieSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJyb3cgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZGF0YS5vcmRlciA9PT0gJ2Rlc2MnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi11cCBtcy0xXCI+PC9pPidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLWRvd24gbXMtMVwiPjwvaT4nO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVwbGFjZSBjb250ZW50cyB3aXRoIHdyYXBwZWQgbGluayAoZnJlc2ggd3JhcHBlciBldmVyeSB0aW1lKVxuICAgICAgICAgICAgICAgICAgICAkdGguaHRtbChgPGEgaHJlZj1cIiNcIiBjbGFzcz1cInNvcnRhYmxlLWhlYWRlclwiIGRhdGEtc29ydGJ5PVwiJHtzb3J0Ynl9XCI+JHtjb250ZW50c30ke2Fycm93fTwvYT5gKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQXR0YWNoIGNsaWNrIGhhbmRsZXJzIHRvIHRoZSBzb3J0YWJsZSBsaW5rcyB3ZSBqdXN0IGNyZWF0ZWRcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnYS5zb3J0YWJsZS1oZWFkZXJbZGF0YS1zb3J0YnldJylcbiAgICAgICAgICAgICAgICAub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3J0YnkgPSAkKHRoaXMpLmF0dHIoJ2RhdGEtc29ydGJ5Jyk7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuc29ydF9ieShzb3J0YnkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBBdHRhY2ggcGFnaW5hdGlvbiBjbGljayBoYW5kbGVyIC0gcmUtcnVucyBldmVyeSB0aW1lIHBhZ2luYXRpb25fY29udHJvbHMgcmVuZGVyc1xuICAgICAgICB0aGF0LmlkKCdwYWdpbmF0aW9uX2NvbnRyb2xzJykub24oJ3JlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnLnBhZ2UtbGluaycpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCAkbGluayA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhZ2UgPSBpbnQoJGxpbmsuYXR0cignZGF0YS1wYWdlJykpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBkaXNhYmxlZC9lbGxpcHNpcyBjbGlja3NcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYWdlIHx8IGlzTmFOKHBhZ2UpIHx8ICRsaW5rLnBhcmVudCgpLmhhc0NsYXNzKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBMb2FkIHRoZSByZXF1ZXN0ZWQgcGFnZVxuICAgICAgICAgICAgICAgICAgICB0aGF0LmxvYWRfcGFnZShwYWdlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXR0YWNoIGNsZWFyIGZpbHRlciBidXR0b24gaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9ib2R5IHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfYm9keScpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCAkY2xlYXJfYnRuID0gdGhhdC4kaWQoJ2NsZWFyX2ZpbHRlcl9idG4nKTtcbiAgICAgICAgICAgIGlmICgkY2xlYXJfYnRuICYmICRjbGVhcl9idG4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICRjbGVhcl9idG4ub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LmNsZWFyX2ZpbHRlcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBTb3J0IGJ5IHNwZWNpZmllZCBjb2x1bW4sIHRvZ2dsaW5nIG9yZGVyIGlmIGFscmVhZHkgc29ydGVkIGJ5IHRoYXQgY29sdW1uXG4gICAgc29ydF9ieShjb2x1bW4pIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRvZ2dsZSBvcmRlciBpZiBjbGlja2luZyBzYW1lIGNvbHVtbiwgb3RoZXJ3aXNlIGRlZmF1bHQgdG8gYXNjXG4gICAgICAgIGlmICh0aGF0LmRhdGEuc29ydCA9PT0gY29sdW1uKSB7XG4gICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSB0aGF0LmRhdGEub3JkZXIgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGF0LmRhdGEuc29ydCA9IGNvbHVtbjtcbiAgICAgICAgICAgIHRoYXQuZGF0YS5vcmRlciA9ICdhc2MnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVsb2FkIGN1cnJlbnQgcGFnZSB3aXRoIG5ldyBzb3J0XG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2hlYWRlcicpLnJlbmRlcigpO1xuICAgICAgICB0aGF0LmxvYWRfcGFnZSh0aGF0LmRhdGEucGFnZSk7XG4gICAgfVxuXG4gICAgLy8gUmVnaXN0ZXIgZmlsdGVyIGlucHV0IGhhbmRsZXJzXG4gICAgcmVnaXN0ZXJfZmlsdGVyX2hhbmRsZXJzKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gRmluZCBmaWx0ZXIgaW5wdXQgYnkgY29tbW9uIGlkZW50aWZpZXJzXG4gICAgICAgIGxldCAkZmlsdGVyID0gdGhhdC4kaWQoJ2ZpbHRlcl9pbnB1dCcpO1xuICAgICAgICBpZiAoISRmaWx0ZXIgfHwgJGZpbHRlci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICRmaWx0ZXIgPSB0aGF0LiQuZmluZCgnaW5wdXRbdHlwZT1cInNlYXJjaFwiXSwgaW5wdXRbdHlwZT1cInRleHRcIl0uZmlsdGVyLWlucHV0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJGZpbHRlciAmJiAkZmlsdGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICRmaWx0ZXIub24oJ2lucHV0IGtleXVwJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcl92YWx1ZSA9ICQodGhpcykudmFsKCk7XG4gICAgICAgICAgICAgICAgdGhhdC5maWx0ZXJfY2hhbmdlZChmaWx0ZXJfdmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaWx0ZXJfY2hhbmdlZChmaWx0ZXIpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIHRoYXQuZGF0YS5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgICAgIHRoYXQubG9hZF9wYWdlKDEpO1xuICAgIH1cblxuICAgIC8vIFNjcm9sbCB0byBkYXRhZ3JpZCB0b3AgaWYgdGhlIHRvcCBlZGdlIGlzIG5vdCBjdXJyZW50bHkgdmlzaWJsZSBpbiB2aWV3cG9ydFxuICAgIHNjcm9sbF90b190b3BfaWZfbmVlZGVkKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgY29uc3QgJGRhdGFncmlkID0gdGhhdC4kO1xuICAgICAgICBjb25zdCBkYXRhZ3JpZFRvcCA9ICRkYXRhZ3JpZC5vZmZzZXQoKS50b3A7XG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9ICQod2luZG93KS5zY3JvbGxUb3AoKTtcblxuICAgICAgICAvLyBJZiBkYXRhZ3JpZCB0b3AgaXMgYWJvdmUgdGhlIGN1cnJlbnQgdmlld3BvcnQsIHNjcm9sbCB0byBzaG93IGl0XG4gICAgICAgIGlmIChkYXRhZ3JpZFRvcCA8IHNjcm9sbFRvcCkge1xuICAgICAgICAgICAgLy8gSWYgZGF0YWdyaWQgaXMgd2l0aGluIDMwMHB4IG9mIHBhZ2UgdG9wLCBzY3JvbGwgdG8gMFxuICAgICAgICAgICAgaWYgKGRhdGFncmlkVG9wIDw9IDMwMCkge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyh7IHRvcDogMCwgYmVoYXZpb3I6ICdpbnN0YW50JyB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2Nyb2xsIHRvIDIwcHggYWJvdmUgZGF0YWdyaWRcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IGRhdGFncmlkVG9wIC0gMjAsIGJlaGF2aW9yOiAnaW5zdGFudCcgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNZWFzdXJlIGFjdHVhbCByb3cgaGVpZ2h0IGFuZCBzZXQgZml4ZWQgdGJvZHkgbWluLWhlaWdodFxuICAgIC8vIEFsbCBoYXBwZW5zIGluIG9uZSBhbmltYXRpb24gZnJhbWUgc28gdXNlciBkb2Vzbid0IHNlZSBpdFxuICAgIGFzeW5jIG1lYXN1cmVfYW5kX3NldF9maXhlZF9oZWlnaHQoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBXYWl0IGZvciBuZXh0IGFuaW1hdGlvbiBmcmFtZSB0byBlbnN1cmUgRE9NIGlzIHJlYWR5XG4gICAgICAgIGF3YWl0IHNsZWVwKDApO1xuXG4gICAgICAgIGNvbnN0ICR0Ym9keSA9IHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS4kO1xuXG4gICAgICAgIC8vIFRlbXBvcmFyaWx5IHJlbmRlciBhIHNpbmdsZSBtZWFzdXJlbWVudCByb3dcbiAgICAgICAgY29uc3QgJG1lYXN1cmVtZW50X3JvdyA9ICQoJzx0cj4nKS5jc3MoJ3Zpc2liaWxpdHknLCAnaGlkZGVuJykuaHRtbCgnPHRkPk1lYXN1cmluZy4uLjwvdGQ+Jyk7XG4gICAgICAgICR0Ym9keS5hcHBlbmQoJG1lYXN1cmVtZW50X3Jvdyk7XG5cbiAgICAgICAgLy8gTWVhc3VyZSB0aGUgcm93IGhlaWdodFxuICAgICAgICBjb25zdCByb3dfaGVpZ2h0ID0gJG1lYXN1cmVtZW50X3Jvdy5vdXRlckhlaWdodCgpO1xuXG4gICAgICAgIC8vIFJlbW92ZSBtZWFzdXJlbWVudCByb3dcbiAgICAgICAgJG1lYXN1cmVtZW50X3Jvdy5yZW1vdmUoKTtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgYW5kIHNldCBtaW4taGVpZ2h0IGJhc2VkIG9uIHBlcl9wYWdlXG4gICAgICAgIGNvbnN0IG1pbl9oZWlnaHQgPSByb3dfaGVpZ2h0ICogdGhhdC5kYXRhLnBlcl9wYWdlO1xuICAgICAgICAkdGJvZHkuY3NzKCdtaW4taGVpZ2h0JywgbWluX2hlaWdodCArICdweCcpO1xuXG4gICAgICAgIC8vIFN0b3JlIGZvciBmdXR1cmUgcmVmZXJlbmNlXG4gICAgICAgIHRoYXQuZGF0YS5yb3dfaGVpZ2h0ID0gcm93X2hlaWdodDtcbiAgICAgICAgdGhhdC5kYXRhLnRib2R5X21pbl9oZWlnaHQgPSBtaW5faGVpZ2h0O1xuICAgIH1cblxuICAgIC8vIENsZWFyIGZpbHRlciBhbmQgcmVzZXQgdG8gcGFnZSAxXG4gICAgY2xlYXJfZmlsdGVyKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdGhhdC5kYXRhLmZpbHRlciA9ICcnO1xuXG4gICAgICAgIC8vIENsZWFyIHRoZSBmaWx0ZXIgaW5wdXRcbiAgICAgICAgY29uc3QgJGZpbHRlciA9IHRoYXQuJGlkKCdmaWx0ZXJfaW5wdXQnKTtcbiAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyLnZhbCgnJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWxvYWQgZnJvbSBwYWdlIDFcbiAgICAgICAgdGhhdC5sb2FkX3BhZ2UoMSk7XG4gICAgfVxufVxuIiwiY2xhc3MgQWN0aXZpdHlfRmVlZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5hY3Rpdml0aWVzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5hY3Rpdml0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuYWN0aXZpdGllcyA9IHRoaXMuYXJncy5hY3Rpdml0aWVzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE9wdGlvbmFsOiBBdXRvLXJlZnJlc2hcbiAgICAgICAgaWYgKHRoaXMuYXJncy5hdXRvX3JlZnJlc2gpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRfYXV0b19yZWZyZXNoKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFydF9hdXRvX3JlZnJlc2goKSB7XG4gICAgICAgIGNvbnN0IGludGVydmFsID0gdGhpcy5hcmdzLnJlZnJlc2hfaW50ZXJ2YWwgfHwgMzAwMDA7IC8vIERlZmF1bHQgMzAgc2Vjb25kc1xuXG4gICAgICAgIHRoaXMucmVmcmVzaF90aW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkX2RhdGEoKTtcbiAgICAgICAgfSwgaW50ZXJ2YWwpO1xuICAgIH1cblxuICAgIHN0b3BfYXV0b19yZWZyZXNoKCkge1xuICAgICAgICBpZiAodGhpcy5yZWZyZXNoX3RpbWVyKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMucmVmcmVzaF90aW1lcik7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hfdGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgcmVsb2FkX2RhdGEoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5hY3Rpdml0aWVzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEFjdG9yX1JlZmVyZW5jZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgQm9vdHN0cmFwIHN0eWxpbmcgLSBubyBKYXZhU2NyaXB0IG5lZWRlZFxufVxuIiwiY2xhc3MgQWR2YW5jZWRfU2VhcmNoX1BhbmVsIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFBvcHVsYXRlIGRyb3Bkb3ducyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNhdGVnb3JpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdjYXRlZ29yeScpLnNldF9vcHRpb25zKHRoaXMuYXJncy5jYXRlZ29yaWVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudGFncykge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3RhZ3MnKS5zZXRfb3B0aW9ucyh0aGlzLmFyZ3MudGFncyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWFyY2ggYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdzZWFyY2hfYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMucGVyZm9ybV9zZWFyY2goKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVzZXQgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdyZXNldF9idG4nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDbG9zZSBidXR0b25cbiAgICAgICAgdGhpcy4kaWQoJ2Nsb3NlX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2xvc2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2xvc2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRm9ybSBzdWJtaXRcbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaF9mb3JtJykub24oJ3N1Ym1pdCcsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnBlcmZvcm1fc2VhcmNoKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHBlcmZvcm1fc2VhcmNoKCkge1xuICAgICAgICBjb25zdCBjcml0ZXJpYSA9IHtcbiAgICAgICAgICAgIGtleXdvcmRzOiB0aGlzLiRpZCgna2V5d29yZHMnKS5nZXRfdmFsdWUoKSxcbiAgICAgICAgICAgIGNhdGVnb3J5OiB0aGlzLiRpZCgnY2F0ZWdvcnknKS5nZXRfdmFsdWUoKSxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMuJGlkKCd0YWdzJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICBmcm9tX2RhdGU6IHRoaXMuJGlkKCdmcm9tX2RhdGUnKS5nZXRfdmFsdWUoKSxcbiAgICAgICAgICAgIHRvX2RhdGU6IHRoaXMuJGlkKCd0b19kYXRlJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICBzb3J0X2J5OiB0aGlzLiRpZCgnc29ydF9ieScpLnZhbCgpLFxuICAgICAgICAgICAgZXhhY3RfbWF0Y2g6IHRoaXMuJGlkKCdleGFjdF9tYXRjaCcpLmlzKCc6Y2hlY2tlZCcpXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmVtb3ZlIGVtcHR5IHZhbHVlc1xuICAgICAgICBPYmplY3Qua2V5cyhjcml0ZXJpYSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjcml0ZXJpYVtrZXldIHx8IChpc19hcnJheShjcml0ZXJpYVtrZXldKSAmJiBjcml0ZXJpYVtrZXldLmxlbmd0aCA9PT0gMCkpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgY3JpdGVyaWFba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zZWFyY2gpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9zZWFyY2goY3JpdGVyaWEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdrZXl3b3JkcycpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdjYXRlZ29yeScpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCd0YWdzJykuc2V0X3ZhbHVlKFtdKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Zyb21fZGF0ZScpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCd0b19kYXRlJykuc2V0X3ZhbHVlKCcnKTtcbiAgICAgICAgdGhpcy4kaWQoJ3NvcnRfYnknKS52YWwoJ3JlbGV2YW5jZScpO1xuICAgICAgICB0aGlzLiRpZCgnZXhhY3RfbWF0Y2gnKS5wcm9wKCdjaGVja2VkJywgZmFsc2UpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fcmVzZXQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9yZXNldCgpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgQWxlcnRfQmFubmVyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IHR5cGUgZnJvbSBhcmdzIChzdWNjZXNzLCBkYW5nZXIsIHdhcm5pbmcsIGluZm8pXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudHlwZSkge1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCdhbGVydC1pbmZvJykuYWRkQ2xhc3MoYGFsZXJ0LSR7dGhpcy5hcmdzLnR5cGV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgZGlzbWlzc2libGUgaWYgbm90IG5lZWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc21pc3NpYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCdhbGVydC1kaXNtaXNzaWJsZScpO1xuICAgICAgICAgICAgdGhpcy4kLmZpbmQoJy5idG4tY2xvc2UnKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEF2YXRhciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTZXQgc3JjIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLnNyYykge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ3NyYycsIHRoaXMuYXJncy5zcmMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHNpemUgKHhzLCBzbSwgbWQsIGxnLCB4bClcbiAgICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuYXJncy5zaXplIHx8ICdtZCc7XG4gICAgICAgIGNvbnN0IHNpemVfbWFwID0ge1xuICAgICAgICAgICAgJ3hzJzogJzI0cHgnLFxuICAgICAgICAgICAgJ3NtJzogJzMycHgnLFxuICAgICAgICAgICAgJ21kJzogJzQ4cHgnLFxuICAgICAgICAgICAgJ2xnJzogJzY0cHgnLFxuICAgICAgICAgICAgJ3hsJzogJzk2cHgnXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy4kLmNzcyh7XG4gICAgICAgICAgICAnd2lkdGgnOiBzaXplX21hcFtzaXplXSxcbiAgICAgICAgICAgICdoZWlnaHQnOiBzaXplX21hcFtzaXplXSxcbiAgICAgICAgICAgICdvYmplY3QtZml0JzogJ2NvdmVyJ1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBBbHRlcm5hdGl2ZSByZW5kZXJpbmc6IHNob3cgaW5pdGlhbHMgd2hlbiBubyBpbWFnZSBzb3VyY2UgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3Muc3JjICYmIHRoaXMuYXJncy5uYW1lKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dfaW5pdGlhbHModGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2hvd19pbml0aWFscyhuYW1lKSB7XG4gICAgICAgIC8vIENvbnZlcnQgaW1nIHRvIGRpdiB3aXRoIGluaXRpYWxzXG4gICAgICAgIGNvbnN0IGluaXRpYWxzID0gbmFtZS5zcGxpdCgnICcpLm1hcChuID0+IG5bMF0pLmpvaW4oJycpLnRvVXBwZXJDYXNlKCkuc2xpY2UoMCwgMik7XG4gICAgICAgIGNvbnN0ICRkaXYgPSAkKCc8ZGl2PicpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ3JvdW5kZWQtY2lyY2xlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlciBiZy1wcmltYXJ5IHRleHQtd2hpdGUgZnctYm9sZCcpXG4gICAgICAgICAgICAuY3NzKHtcbiAgICAgICAgICAgICAgICAnd2lkdGgnOiB0aGlzLiQuY3NzKCd3aWR0aCcpLFxuICAgICAgICAgICAgICAgICdoZWlnaHQnOiB0aGlzLiQuY3NzKCdoZWlnaHQnKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50ZXh0KGluaXRpYWxzKTtcblxuICAgICAgICB0aGlzLiQucmVwbGFjZVdpdGgoJGRpdik7XG4gICAgICAgIHRoaXMuJCA9ICRkaXY7XG4gICAgfVxufVxuIiwiY2xhc3MgQmxvY2txdW90ZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yXG4gICAgfVxufVxuIiwiY2xhc3MgQnJlYWRjcnVtYnMgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQbGFjZWhvbGRlciBjb21wb25lbnQgLSBjdXJyZW50bHkgZW1wdHkgaW4gZGFzaGJvYXJkIHVzYWdlXG59XG4iLCJjbGFzcyBCdWxrX0FjdGlvbl9CYXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQ2xlYXIgc2VsZWN0aW9uIG9uIGNsb3NlXG4gICAgICAgIHRoaXMuJGlkKCdjbG9zZV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLiQuaGlkZSgpO1xuICAgICAgICAgICAgLy8gVW5jaGVjayBhbGwgYm94ZXNcbiAgICAgICAgICAgIGNvbnN0ICR0YWJsZSA9IHRoaXMuJC5jbG9zZXN0KCcuY2FyZCcpLmZpbmQoJ3RhYmxlJyk7XG4gICAgICAgICAgICAkdGFibGUuZmluZCgnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykucHJvcCgnY2hlY2tlZCcsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2V0X2NvdW50KGNvdW50KSB7XG4gICAgICAgIHRoaXMuJC5maW5kKCcuY291bnQnKS50ZXh0KGNvdW50KTtcbiAgICB9XG59XG4iLCJjbGFzcyBCdWxrX1NlbGVjdGlvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkY2hlY2tib3ggPSB0aGlzLiRpZCgnY2hlY2tib3gnKTtcblxuICAgICAgICAvLyBUb2dnbGUgYWxsIGNoZWNrYm94ZXMgaW4gdGFibGUgYm9keVxuICAgICAgICAkY2hlY2tib3gub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjaGVja2VkID0gZS50YXJnZXQuY2hlY2tlZDtcbiAgICAgICAgICAgIGNvbnN0ICR0YWJsZSA9IHRoaXMuJC5jbG9zZXN0KCd0YWJsZScpO1xuICAgICAgICAgICAgJHRhYmxlLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBjaGVja2VkKTtcblxuICAgICAgICAgICAgLy8gVHJpZ2dlciB1cGRhdGUgZXZlbnRcbiAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShjaGVja2VkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgQnV0dG9uX0dyb3VwIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gQ29udGFpbmVyIGZvciBncm91cGVkIGJ1dHRvbnMgd2l0aCBjb25uZWN0ZWQgYm9yZGVyc1xuICAgIC8vIEJvb3RzdHJhcCBidG4tZ3JvdXAgaGFuZGxlcyBhbGwgdmlzdWFsIGdyb3VwaW5nXG59XG4iLCJjbGFzcyBCdXR0b25fUHJpbWFyeSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFByaW1hcnkgYWN0aW9uIGJ1dHRvbiAtIGhpZ2hlc3QgdmlzdWFsIGhpZXJhcmNoeVxuICAgIC8vIEJvb3RzdHJhcCBidG4tcHJpbWFyeSBwcm92aWRlcyBhbGwgc3R5bGluZ1xufVxuIiwiY2xhc3MgQnV0dG9uX1NlY29uZGFyeSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFNlY29uZGFyeSBhY3Rpb24gYnV0dG9uIC0gbG93ZXIgcHJvbWluZW5jZSB0aGFuIHByaW1hcnlcbiAgICAvLyBCb290c3RyYXAgYnRuLXNlY29uZGFyeSBwcm92aWRlcyBncmF5IGNvbG9yIHNjaGVtZVxufVxuIiwiY2xhc3MgQnV0dG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gQmFzZSBidXR0b24gY29tcG9uZW50IC0gbm8gc3BlY2lhbCBiZWhhdmlvciBuZWVkZWRcbiAgICAvLyBCb290c3RyYXAgaGFuZGxlcyBhbGwgc3RhdGVzIChob3ZlciwgYWN0aXZlLCBmb2N1cywgZGlzYWJsZWQpXG59XG4iLCJjbGFzcyBDYWxlbmRhcl9FdmVudCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NsaWNrKSB7XG4gICAgICAgICAgICB0aGlzLiQub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jbGljayh0aGlzLmFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIb3ZlciBlZmZlY3RcbiAgICAgICAgdGhpcy4kLm9uKCdtb3VzZWVudGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdzaGFkb3ctc20nKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy4kLm9uKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCdzaGFkb3ctc20nKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgQ2FsZW5kYXJfR3JpZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRfZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG5cbiAgICAgICAgdGhpcy4kaWQoJ3ByZXZfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50X2RhdGUuc2V0TW9udGgodGhpcy5jdXJyZW50X2RhdGUuZ2V0TW9udGgoKSAtIDEpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJfY2FsZW5kYXIoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy4kaWQoJ25leHRfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50X2RhdGUuc2V0TW9udGgodGhpcy5jdXJyZW50X2RhdGUuZ2V0TW9udGgoKSArIDEpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJfY2FsZW5kYXIoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy4kaWQoJ3RvZGF5X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudF9kYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlbmRlcl9jYWxlbmRhcigpIHtcbiAgICAgICAgY29uc3QgeWVhciA9IHRoaXMuY3VycmVudF9kYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgIGNvbnN0IG1vbnRoID0gdGhpcy5jdXJyZW50X2RhdGUuZ2V0TW9udGgoKTtcblxuICAgICAgICAvLyBVcGRhdGUgdGl0bGVcbiAgICAgICAgY29uc3QgbW9udGhfbmFtZXMgPSBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLFxuICAgICAgICAgICAgJ0p1bHknLCAnQXVndXN0JywgJ1NlcHRlbWJlcicsICdPY3RvYmVyJywgJ05vdmVtYmVyJywgJ0RlY2VtYmVyJ107XG4gICAgICAgIHRoaXMuJGlkKCdtb250aF90aXRsZScpLnRleHQoYCR7bW9udGhfbmFtZXNbbW9udGhdfSAke3llYXJ9YCk7XG5cbiAgICAgICAgLy8gR2V0IGZpcnN0IGRheSBvZiBtb250aCBhbmQgdG90YWwgZGF5c1xuICAgICAgICBjb25zdCBmaXJzdF9kYXkgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSkuZ2V0RGF5KCk7XG4gICAgICAgIGNvbnN0IGRheXNfaW5fbW9udGggPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCArIDEsIDApLmdldERhdGUoKTtcblxuICAgICAgICBjb25zdCAkdGJvZHkgPSB0aGlzLiRpZCgnY2FsZW5kYXJfYm9keScpO1xuICAgICAgICAkdGJvZHkuZW1wdHkoKTtcblxuICAgICAgICBsZXQgZGF5ID0gMTtcbiAgICAgICAgbGV0ICR0ciA9IG51bGw7XG5cbiAgICAgICAgLy8gQnVpbGQgY2FsZW5kYXIgZ3JpZFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY7IGkrKykge1xuICAgICAgICAgICAgJHRyID0gJCgnPHRyPicpO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IDc7IGorKykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICR0ZCA9ICQoJzx0ZD4nKS5jc3Moe1xuICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JzogJzEwMHB4JyxcbiAgICAgICAgICAgICAgICAgICAgJ3ZlcnRpY2FsLWFsaWduJzogJ3RvcCcsXG4gICAgICAgICAgICAgICAgICAgICdwYWRkaW5nJzogJzhweCdcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmIChpID09PSAwICYmIGogPCBmaXJzdF9kYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRW1wdHkgY2VsbCBiZWZvcmUgbW9udGggc3RhcnRzXG4gICAgICAgICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnYmctbGlnaHQnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRheSA+IGRheXNfaW5fbW9udGgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRW1wdHkgY2VsbCBhZnRlciBtb250aCBlbmRzXG4gICAgICAgICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnYmctbGlnaHQnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBEYXkgY2VsbFxuICAgICAgICAgICAgICAgICAgICBjb25zdCAkZGF5X251bSA9ICQoJzxkaXY+JykuYWRkQ2xhc3MoJ2Z3LWJvbGQgbWItMicpLnRleHQoZGF5KTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBIaWdobGlnaHQgdG9kYXlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGF5ID09PSB0b2RheS5nZXREYXRlKCkgJiYgbW9udGggPT09IHRvZGF5LmdldE1vbnRoKCkgJiYgeWVhciA9PT0gdG9kYXkuZ2V0RnVsbFllYXIoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJGRheV9udW0uYWRkQ2xhc3MoJ3RleHQtcHJpbWFyeScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgJHRkLmFkZENsYXNzKCdib3JkZXItcHJpbWFyeScpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgJHRkLmFwcGVuZCgkZGF5X251bSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGV2ZW50cyBmb3IgdGhpcyBkYXkgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5ldmVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHRoaXMuZ2V0X2V2ZW50c19mb3JfZGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAkZXZlbnQgPSAkKCc8ZGl2PicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnYmFkZ2UgYmctcHJpbWFyeSB0ZXh0LXRydW5jYXRlIHctMTAwIG1iLTEgdGV4dC1zdGFydCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jc3MoJ2N1cnNvcicsICdwb2ludGVyJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRleHQoZXZlbnQudGl0bGUpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGV2ZW50Lm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9ldmVudF9jbGljaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2V2ZW50X2NsaWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRkLmFwcGVuZCgkZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAkdGQuYXR0cignZGF0YS1kYXRlJywgYCR7eWVhcn0tJHtzdHIobW9udGggKyAxKS5wYWRTdGFydCgyLCAnMCcpfS0ke3N0cihkYXkpLnBhZFN0YXJ0KDIsICcwJyl9YCk7XG4gICAgICAgICAgICAgICAgICAgICR0ZC5jc3MoJ2N1cnNvcicsICdwb2ludGVyJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgJHRkLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2RhdGVfY2xpY2sgJiYgISQoZS50YXJnZXQpLmhhc0NsYXNzKCdiYWRnZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2RhdGVfY2xpY2soJHRkLmF0dHIoJ2RhdGEtZGF0ZScpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgZGF5Kys7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG5cbiAgICAgICAgICAgIGlmIChkYXkgPiBkYXlzX2luX21vbnRoKSBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9ldmVudHNfZm9yX2RhdGUoeWVhciwgbW9udGgsIGRheSkge1xuICAgICAgICBpZiAoIXRoaXMuYXJncy5ldmVudHMpIHJldHVybiBbXTtcblxuICAgICAgICBjb25zdCBkYXRlX3N0ciA9IGAke3llYXJ9LSR7c3RyKG1vbnRoICsgMSkucGFkU3RhcnQoMiwgJzAnKX0tJHtzdHIoZGF5KS5wYWRTdGFydCgyLCAnMCcpfWA7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXJncy5ldmVudHMuZmlsdGVyKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHJldHVybiBldmVudC5kYXRlID09PSBkYXRlX3N0cjtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBDYXJkIC0gQm9vdHN0cmFwIDUgQ29udGVudCBDb250YWluZXIgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogUHJpbWFyeSBjb250ZW50IGNvbnRhaW5lciB1c2luZyBCb290c3RyYXAgLmNhcmQgY2xhc3NcbiAqIERlc2lnbjogUHVyZSBCb290c3RyYXAgLSBib3JkZXItMCB3aXRoIHNoYWRvdyBmb3IgbW9kZXJuIFZvbHQgYWVzdGhldGljXG4gKi9cbmNsYXNzIENhcmQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBDYXJkIGlzIGEgcHVyZSBjb250YWluZXIgY29tcG9uZW50IC0gbm8gbGlmZWN5Y2xlIG1ldGhvZHMgbmVlZGVkXG4gICAgLy8gQWxsIHN0eWxpbmcgY29tZXMgZnJvbSBCb290c3RyYXAgY2xhc3NlczogY2FyZCwgYm9yZGVyLTAsIHNoYWRvd1xufVxuIiwiY2xhc3MgQ2hhcnRfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUGxhY2Vob2xkZXIgY29tcG9uZW50IC0gbm8gZnVuY3Rpb25hbGl0eSB5ZXRcbn1cbiIsIi8qKlxuICogQ2hlY2tib3ggLSBCb290c3RyYXAgNSBDaGVja2JveCBJbnB1dCBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBTaW5nbGUgY2hlY2tib3ggZm9yIHllcy9ubywgdHJ1ZS9mYWxzZSBzZWxlY3Rpb25zXG4gKiBEZXNpZ246IEJvb3RzdHJhcCAuZm9ybS1jaGVjay1pbnB1dCBzdHlsaW5nXG4gKiBXcmFwcGVyOiBUeXBpY2FsbHkgdXNlZCB3aXRoaW4gPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj4gZm9yIHByb3BlciBsYXlvdXRcbiAqL1xuY2xhc3MgQ2hlY2tib3ggZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IGNoZWNrZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jaGVja2VkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgnY2hlY2tlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHZhbHVlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuJC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBjdXN0b20gY2xhc3NlcyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3ModGhpcy5hcmdzLmNsYXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkaXNhYmxlZCBzdGF0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCByZXF1aXJlZCBhdHRyaWJ1dGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBDb2RlX0Jsb2NrIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3IgKHN5bnRheCBoaWdobGlnaHRpbmcgY291bGQgYmUgYWRkZWQgbGF0ZXIpXG4gICAgfVxufVxuIiwiY2xhc3MgQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEJ1aWxkIGNvbHVtbiBjaGVja2JveGVzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sdW1ucykge1xuICAgICAgICAgICAgdGhpcy5idWlsZF9tZW51KHRoaXMuYXJncy5jb2x1bW5zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGJ1aWxkX21lbnUoY29sdW1ucykge1xuICAgICAgICBjb25zdCAkbWVudSA9IHRoaXMuJGlkKCdtZW51Jyk7XG4gICAgICAgICRtZW51LmVtcHR5KCk7XG5cbiAgICAgICAgY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+Jyk7XG4gICAgICAgICAgICBjb25zdCAkbGFiZWwgPSAkKCc8bGFiZWw+JykuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWl0ZW0nKTtcbiAgICAgICAgICAgIGNvbnN0ICRjaGVja2JveCA9ICQoJzxpbnB1dD4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnZm9ybS1jaGVjay1pbnB1dCBtZS0yJylcbiAgICAgICAgICAgICAgICAuYXR0cigndHlwZScsICdjaGVja2JveCcpXG4gICAgICAgICAgICAgICAgLnByb3AoJ2NoZWNrZWQnLCBjb2x1bW4udmlzaWJsZSAhPT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtY29sdW1uLWluZGV4JywgaW5kZXgpO1xuXG4gICAgICAgICAgICAkbGFiZWwuYXBwZW5kKCRjaGVja2JveCkuYXBwZW5kKGNvbHVtbi5sYWJlbCB8fCBjb2x1bW4ubmFtZSk7XG4gICAgICAgICAgICAkbGkuYXBwZW5kKCRsYWJlbCk7XG4gICAgICAgICAgICAkbWVudS5hcHBlbmQoJGxpKTtcblxuICAgICAgICAgICAgJGNoZWNrYm94Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlX2NvbHVtbihpbmRleCwgZS50YXJnZXQuY2hlY2tlZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdG9nZ2xlX2NvbHVtbihpbmRleCwgdmlzaWJsZSkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3RvZ2dsZSkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX3RvZ2dsZShpbmRleCwgdmlzaWJsZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIHRhYmxlIGFuZCB0b2dnbGUgY29sdW1uIHZpc2liaWxpdHlcbiAgICAgICAgY29uc3QgJHRhYmxlID0gdGhpcy5hcmdzLnRhYmxlID8gJCh0aGlzLmFyZ3MudGFibGUpIDogdGhpcy4kLmNsb3Nlc3QoJy5jYXJkJykuZmluZCgndGFibGUnKTtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSBgdGg6bnRoLWNoaWxkKCR7aW5kZXggKyAxfSksIHRkOm50aC1jaGlsZCgke2luZGV4ICsgMX0pYDtcblxuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgICAgJHRhYmxlLmZpbmQoc2VsZWN0b3IpLnNob3coKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR0YWJsZS5maW5kKHNlbGVjdG9yKS5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRfY29sdW1ucyhjb2x1bW5zKSB7XG4gICAgICAgIHRoaXMuYnVpbGRfbWVudShjb2x1bW5zKTtcbiAgICB9XG59XG4iLCJjbGFzcyBDb21tZW50X1RocmVhZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb21tZW50cyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuY29tbWVudHMpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb21tZW50cyA9IHRoaXMuYXJncy5jb21tZW50cztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTdWJtaXQgbmV3IGNvbW1lbnRcbiAgICAgICAgdGhpcy4kaWQoJ3N1Ym1pdF9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN1Ym1pdF9jb21tZW50KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlcGx5IGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5yZXBseS1idG4nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGNvbW1lbnQgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KCdbZGF0YS1jb21tZW50LWlkXScpO1xuICAgICAgICAgICAgY29uc3QgY29tbWVudF9pZCA9ICRjb21tZW50LmF0dHIoJ2RhdGEtY29tbWVudC1pZCcpO1xuICAgICAgICAgICAgdGhpcy5zaG93X3JlcGx5X2Zvcm0oY29tbWVudF9pZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEVkaXQgYnV0dG9uc1xuICAgICAgICB0aGlzLiQuZmluZCgnLmVkaXQtYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRjb21tZW50ID0gJChlLnRhcmdldCkuY2xvc2VzdCgnW2RhdGEtY29tbWVudC1pZF0nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRfaWQgPSAkY29tbWVudC5hdHRyKCdkYXRhLWNvbW1lbnQtaWQnKTtcbiAgICAgICAgICAgIHRoaXMuZWRpdF9jb21tZW50KGNvbW1lbnRfaWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZWxldGUgYnV0dG9uc1xuICAgICAgICB0aGlzLiQuZmluZCgnLmRlbGV0ZS1idG4nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGNvbW1lbnQgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KCdbZGF0YS1jb21tZW50LWlkXScpO1xuICAgICAgICAgICAgY29uc3QgY29tbWVudF9pZCA9ICRjb21tZW50LmF0dHIoJ2RhdGEtY29tbWVudC1pZCcpO1xuICAgICAgICAgICAgdGhpcy5kZWxldGVfY29tbWVudChjb21tZW50X2lkKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgc3VibWl0X2NvbW1lbnQoKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSB0aGlzLiRpZCgnY29tbWVudF9pbnB1dCcpLnZhbCgpLnRyaW0oKTtcbiAgICAgICAgaWYgKCF0ZXh0KSByZXR1cm47XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zdWJtaXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYXJncy5vbl9zdWJtaXQodGV4dCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2NvbW1lbnRfaW5wdXQnKS52YWwoJycpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVsb2FkX2RhdGEoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNob3dfcmVwbHlfZm9ybShjb21tZW50X2lkKSB7XG4gICAgICAgIC8vIFRPRE86IEltcGxlbWVudCByZXBseSBmb3JtIFVJXG4gICAgICAgIGNvbnNvbGUubG9nKCdSZXBseSB0byBjb21tZW50OicsIGNvbW1lbnRfaWQpO1xuICAgIH1cblxuICAgIGVkaXRfY29tbWVudChjb21tZW50X2lkKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZWRpdCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2VkaXQoY29tbWVudF9pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBkZWxldGVfY29tbWVudChjb21tZW50X2lkKSB7XG4gICAgICAgIGlmICghY29uZmlybSgnRGVsZXRlIHRoaXMgY29tbWVudD8nKSkgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZGVsZXRlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmFyZ3Mub25fZGVsZXRlKGNvbW1lbnRfaWQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVsb2FkX2RhdGEoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHJlbG9hZF9kYXRhKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29tbWVudHMgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgRGF0ZV9QaWNrZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWx1ZSkge1xuICAgICAgICAgICAgJGlucHV0LnZhbCh0aGlzLmFyZ3MudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5uYW1lKSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubWluKSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbWluJywgdGhpcy5hcmdzLm1pbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm1heCkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ21heCcsIHRoaXMuYXJncy5tYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVhZG9ubHknLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRHJvcGRvd25fTWVudSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGJhcmUgdGV4dCBjaGlsZHJlbiBpbiA8bGk+PGE+IHN0cnVjdHVyZVxuICAgICAgICBjb25zdCAkbWVudSA9IHRoaXMuJGlkKCdtZW51Jyk7XG4gICAgICAgICRtZW51LmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSAkY2hpbGQudGV4dCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhyZWYgPSAkY2hpbGQuYXR0cignaHJlZicpIHx8ICcjJztcbiAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+JykuYXBwZW5kKFxuICAgICAgICAgICAgICAgICAgICAkKCc8YT4nKS5hZGRDbGFzcygnZHJvcGRvd24taXRlbScpLmF0dHIoJ2hyZWYnLCBocmVmKS50ZXh0KHRleHQpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQucmVwbGFjZVdpdGgoJGxpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgRW1wdHlfU3RhdGUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIEV4cG9ydF9CdXR0b24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHRoaXMuJC5maW5kKCdbZGF0YS1mb3JtYXRdJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdCA9ICQoZS5jdXJyZW50VGFyZ2V0KS5hdHRyKCdkYXRhLWZvcm1hdCcpO1xuICAgICAgICAgICAgdGhhdC5leHBvcnRfZGF0YShmb3JtYXQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBleHBvcnRfZGF0YShmb3JtYXQpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9leHBvcnQpIHtcbiAgICAgICAgICAgIC8vIEN1c3RvbSBleHBvcnQgaGFuZGxlclxuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2V4cG9ydChmb3JtYXQpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5kYXRhKSB7XG4gICAgICAgICAgICAvLyBBdXRvLWV4cG9ydCBwcm92aWRlZCBkYXRhXG4gICAgICAgICAgICB0aGlzLmF1dG9fZXhwb3J0KGZvcm1hdCwgdGhpcy5hcmdzLmRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5leHBvcnRfdXJsKSB7XG4gICAgICAgICAgICAvLyBGZXRjaCBleHBvcnQgZnJvbSBVUkxcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYXJncy5leHBvcnRfdXJsfT9mb3JtYXQ9JHtmb3JtYXR9YDtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdXJsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXV0b19leHBvcnQoZm9ybWF0LCBkYXRhKSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09ICdjc3YnKSB7XG4gICAgICAgICAgICB0aGlzLmV4cG9ydF9jc3YoZGF0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnanNvbicpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwb3J0X2pzb24oZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0F1dG8tZXhwb3J0IG9ubHkgc3VwcG9ydHMgQ1NWIGFuZCBKU09OLiBJbXBsZW1lbnQgY3VzdG9tIGhhbmRsZXIgZm9yIG90aGVyIGZvcm1hdHMuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBleHBvcnRfY3N2KGRhdGEpIHtcbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgLy8gR2VuZXJhdGUgQ1NWXG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBPYmplY3Qua2V5cyhkYXRhWzBdKTtcbiAgICAgICAgbGV0IGNzdiA9IGhlYWRlcnMuam9pbignLCcpICsgJ1xcbic7XG5cbiAgICAgICAgZGF0YS5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBoZWFkZXJzLm1hcChoZWFkZXIgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcm93W2hlYWRlcl0gfHwgJyc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcIiR7c3RyKHZhbHVlKS5yZXBsYWNlKC9cIi9nLCAnXCJcIicpfVwiYDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY3N2ICs9IHZhbHVlcy5qb2luKCcsJykgKyAnXFxuJztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRG93bmxvYWRcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjc3ZdLCB7IHR5cGU6ICd0ZXh0L2NzdicgfSk7XG4gICAgICAgIGNvbnN0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBjb25zdCAkYSA9ICQoJzxhPicpO1xuICAgICAgICAkYS5hdHRyKCdocmVmJywgdXJsKTtcbiAgICAgICAgJGEuYXR0cignZG93bmxvYWQnLCBgZXhwb3J0XyR7RGF0ZS5ub3coKX0uY3N2YCk7XG4gICAgICAgICRhWzBdLmNsaWNrKCk7XG4gICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfVxuXG4gICAgZXhwb3J0X2pzb24oZGF0YSkge1xuICAgICAgICBjb25zdCBqc29uID0ganNvbl9lbmNvZGUoZGF0YSk7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbanNvbl0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3QgJGEgPSAkKCc8YT4nKTtcbiAgICAgICAgJGEuYXR0cignaHJlZicsIHVybCk7XG4gICAgICAgICRhLmF0dHIoJ2Rvd25sb2FkJywgYGV4cG9ydF8ke0RhdGUubm93KCl9Lmpzb25gKTtcbiAgICAgICAgJGFbMF0uY2xpY2soKTtcbiAgICAgICAgd2luZG93LlVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGaWxlX1VwbG9hZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpO1xuICAgICAgICBjb25zdCAkZHJvcF96b25lID0gdGhpcy4kaWQoJ2Ryb3Bfem9uZScpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYWNjZXB0KSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignYWNjZXB0JywgdGhpcy5hcmdzLmFjY2VwdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm11bHRpcGxlKSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbXVsdGlwbGUnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENsaWNrIHRvIHVwbG9hZFxuICAgICAgICAkZHJvcF96b25lLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICRpbnB1dC5jbGljaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBGaWxlIHNlbGVjdGVkXG4gICAgICAgICRpbnB1dC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVzID0gZS50YXJnZXQuZmlsZXM7XG4gICAgICAgICAgICBpZiAoZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlX2ZpbGVzKGZpbGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRHJhZyBhbmQgZHJvcFxuICAgICAgICAkZHJvcF96b25lLm9uKCdkcmFnb3ZlcicsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGRyb3Bfem9uZS5hZGRDbGFzcygnYm9yZGVyLXByaW1hcnkgYmctbGlnaHQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJGRyb3Bfem9uZS5vbignZHJhZ2xlYXZlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAkZHJvcF96b25lLnJlbW92ZUNsYXNzKCdib3JkZXItcHJpbWFyeSBiZy1saWdodCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICAkZHJvcF96b25lLm9uKCdkcm9wJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAkZHJvcF96b25lLnJlbW92ZUNsYXNzKCdib3JkZXItcHJpbWFyeSBiZy1saWdodCcpO1xuXG4gICAgICAgICAgICBjb25zdCBmaWxlcyA9IGUub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXIuZmlsZXM7XG4gICAgICAgICAgICBpZiAoZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlX2ZpbGVzKGZpbGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGJ1dHRvblxuICAgICAgICB0aGlzLiRpZCgncmVtb3ZlX2J0bicpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBoYW5kbGVfZmlsZXMoZmlsZXMpIHtcbiAgICAgICAgY29uc3QgZmlsZSA9IGZpbGVzWzBdOyAvLyBTaW5nbGUgZmlsZSBmb3Igbm93XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZmlsZSBzaXplXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubWF4X3NpemVfYnl0ZXMgJiYgZmlsZS5zaXplID4gdGhpcy5hcmdzLm1heF9zaXplX2J5dGVzKSB7XG4gICAgICAgICAgICBhbGVydChgRmlsZSBpcyB0b28gbGFyZ2UuIE1heCBzaXplIGlzICR7dGhpcy5mb3JtYXRfc2l6ZSh0aGlzLmFyZ3MubWF4X3NpemVfYnl0ZXMpfWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZF9maWxlID0gZmlsZTtcblxuICAgICAgICAvLyBTaG93IGZpbGUgaW5mb1xuICAgICAgICB0aGlzLiRpZCgncGxhY2Vob2xkZXInKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX2luZm8nKS5zaG93KCk7XG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX25hbWUnKS50ZXh0KGZpbGUubmFtZSk7XG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX3NpemUnKS50ZXh0KHRoaXMuZm9ybWF0X3NpemUoZmlsZS5zaXplKSk7XG5cbiAgICAgICAgLy8gQXV0by11cGxvYWQgaWYgZW5kcG9pbnQgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy51cGxvYWRfdXJsKSB7XG4gICAgICAgICAgICB0aGlzLnVwbG9hZCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX3NlbGVjdChmaWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHVwbG9hZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkX2ZpbGUgfHwgIXRoaXMuYXJncy51cGxvYWRfdXJsKSByZXR1cm47XG5cbiAgICAgICAgLy8gU2hvdyBwcm9ncmVzc1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbmZvJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgncHJvZ3Jlc3MnKS5zaG93KCk7XG5cbiAgICAgICAgY29uc3QgZm9ybV9kYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1fZGF0YS5hcHBlbmQoJ2ZpbGUnLCB0aGlzLnNlbGVjdGVkX2ZpbGUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy51cGxvYWRfdXJsLCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgYm9keTogZm9ybV9kYXRhXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICAgICAgICAvLyBIaWRlIHByb2dyZXNzXG4gICAgICAgICAgICB0aGlzLiRpZCgncHJvZ3Jlc3MnKS5oaWRlKCk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbmZvJykuc2hvdygpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3VwbG9hZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl91cGxvYWQocmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdVcGxvYWQgZmFpbGVkOiAnICsgZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICB0aGlzLiRpZCgncHJvZ3Jlc3MnKS5oaWRlKCk7XG4gICAgICAgICAgICB0aGlzLiRpZCgncGxhY2Vob2xkZXInKS5zaG93KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZF9maWxlID0gbnVsbDtcbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS52YWwoJycpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbmZvJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgncHJvZ3Jlc3MnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdwbGFjZWhvbGRlcicpLnNob3coKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NsZWFyKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9maWxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZF9maWxlO1xuICAgIH1cblxuICAgIGZvcm1hdF9zaXplKGJ5dGVzKSB7XG4gICAgICAgIGlmIChieXRlcyA8IDEwMjQpIHJldHVybiBieXRlcyArICcgQic7XG4gICAgICAgIGlmIChieXRlcyA8IDEwMjQgKiAxMDI0KSByZXR1cm4gKGJ5dGVzIC8gMTAyNCkudG9GaXhlZCgxKSArICcgS0InO1xuICAgICAgICByZXR1cm4gKGJ5dGVzIC8gKDEwMjQgKiAxMDI0KSkudG9GaXhlZCgxKSArICcgTUInO1xuICAgIH1cbn1cbiIsImNsYXNzIEZpbHRlcl9CYXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVfZmlsdGVycyA9IHt9O1xuXG4gICAgICAgIC8vIFBvcHVsYXRlIHN0YXR1cyBvcHRpb25zIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc3RhdHVzX29wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0ICRzdGF0dXMgPSB0aGlzLiRpZCgnc3RhdHVzJyk7XG4gICAgICAgICAgICB0aGlzLmFyZ3Muc3RhdHVzX29wdGlvbnMuZm9yRWFjaChvcHQgPT4ge1xuICAgICAgICAgICAgICAgICRzdGF0dXMuYXBwZW5kKCQoJzxvcHRpb24+JykudmFsKG9wdC52YWx1ZSkudGV4dChvcHQubGFiZWwpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGF0ZSByYW5nZSBjaGFuZ2UgaGFuZGxlclxuICAgICAgICB0aGlzLiRpZCgnZGF0ZV9yYW5nZScpLm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGUudGFyZ2V0LnZhbHVlID09PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXMnKS5zaG93KCk7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2N1c3RvbV9kYXRlc19lbmQnKS5zaG93KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXMnKS5oaWRlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2N1c3RvbV9kYXRlc19lbmQnKS5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNlYXJjaCB3aXRoIGRlYm91bmNlXG4gICAgICAgIGxldCBzZWFyY2hfdGltZW91dDtcbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaCcpLiQuZmluZCgnaW5wdXQnKS5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHNlYXJjaF90aW1lb3V0KTtcbiAgICAgICAgICAgIHNlYXJjaF90aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRfZmlsdGVyKCdzZWFyY2gnLCBlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBBcHBseSBidXR0b25cbiAgICAgICAgdGhpcy4kaWQoJ2FwcGx5X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlfZmlsdGVycygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDbGVhciBidXR0b25cbiAgICAgICAgdGhpcy4kaWQoJ2NsZWFyX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJfZmlsdGVycygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRfZmlsdGVyKGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZV9maWx0ZXJzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmFjdGl2ZV9maWx0ZXJzW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKTtcbiAgICB9XG5cbiAgICBhcHBseV9maWx0ZXJzKCkge1xuICAgICAgICAvLyBDb2xsZWN0IGFsbCBmaWx0ZXIgdmFsdWVzXG4gICAgICAgIGNvbnN0IHNlYXJjaCA9IHRoaXMuJGlkKCdzZWFyY2gnKS5nZXRfdmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gdGhpcy4kaWQoJ3N0YXR1cycpLnZhbCgpO1xuICAgICAgICBjb25zdCBkYXRlX3JhbmdlID0gdGhpcy4kaWQoJ2RhdGVfcmFuZ2UnKS52YWwoKTtcblxuICAgICAgICB0aGlzLmFjdGl2ZV9maWx0ZXJzID0ge307XG5cbiAgICAgICAgaWYgKHNlYXJjaCkgdGhpcy5hY3RpdmVfZmlsdGVycy5zZWFyY2ggPSBzZWFyY2g7XG4gICAgICAgIGlmIChzdGF0dXMpIHRoaXMuYWN0aXZlX2ZpbHRlcnMuc3RhdHVzID0gc3RhdHVzO1xuICAgICAgICBpZiAoZGF0ZV9yYW5nZSkgdGhpcy5hY3RpdmVfZmlsdGVycy5kYXRlX3JhbmdlID0gZGF0ZV9yYW5nZTtcblxuICAgICAgICBpZiAoZGF0ZV9yYW5nZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0X2RhdGUgPSB0aGlzLiRpZCgnc3RhcnRfZGF0ZScpLmdldF92YWx1ZSgpO1xuICAgICAgICAgICAgY29uc3QgZW5kX2RhdGUgPSB0aGlzLiRpZCgnZW5kX2RhdGUnKS5nZXRfdmFsdWUoKTtcbiAgICAgICAgICAgIGlmIChzdGFydF9kYXRlKSB0aGlzLmFjdGl2ZV9maWx0ZXJzLnN0YXJ0X2RhdGUgPSBzdGFydF9kYXRlO1xuICAgICAgICAgICAgaWYgKGVuZF9kYXRlKSB0aGlzLmFjdGl2ZV9maWx0ZXJzLmVuZF9kYXRlID0gZW5kX2RhdGU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZV9maWx0ZXJfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fYXBwbHkpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9hcHBseSh0aGlzLmFjdGl2ZV9maWx0ZXJzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsZWFyX2ZpbHRlcnMoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlX2ZpbHRlcnMgPSB7fTtcblxuICAgICAgICB0aGlzLiRpZCgnc2VhcmNoJykuc2V0X3ZhbHVlKCcnKTtcbiAgICAgICAgdGhpcy4kaWQoJ3N0YXR1cycpLnZhbCgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdkYXRlX3JhbmdlJykudmFsKCcnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2N1c3RvbV9kYXRlcycpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2N1c3RvbV9kYXRlc19lbmQnKS5oaWRlKCk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NsZWFyKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZV9maWx0ZXJfZGlzcGxheSgpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSBPYmplY3Qua2V5cyh0aGlzLmFjdGl2ZV9maWx0ZXJzKS5sZW5ndGg7XG4gICAgICAgIGNvbnN0ICRjb250YWluZXIgPSB0aGlzLiRpZCgnYWN0aXZlX2ZpbHRlcnMnKTtcbiAgICAgICAgY29uc3QgJHRhZ3MgPSB0aGlzLiRpZCgnZmlsdGVyX3RhZ3MnKTtcblxuICAgICAgICBpZiAoY291bnQgPT09IDApIHtcbiAgICAgICAgICAgICRjb250YWluZXIuaGlkZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgJGNvbnRhaW5lci5zaG93KCk7XG4gICAgICAgICR0YWdzLmVtcHR5KCk7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIHRoaXMuYWN0aXZlX2ZpbHRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0ICR0YWcgPSAkKCc8c3Bhbj4nKS5hZGRDbGFzcygnYmFkZ2UgYmctcHJpbWFyeSBtZS0xJyk7XG4gICAgICAgICAgICAkdGFnLnRleHQoYCR7a2V5fTogJHt0aGlzLmFjdGl2ZV9maWx0ZXJzW2tleV19YCk7XG5cbiAgICAgICAgICAgIGNvbnN0ICRyZW1vdmUgPSAkKCc8aT4nKS5hZGRDbGFzcygnYmkgYmkteC1jaXJjbGUgbXMtMScpLmNzcygnY3Vyc29yJywgJ3BvaW50ZXInKTtcbiAgICAgICAgICAgICRyZW1vdmUub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmFjdGl2ZV9maWx0ZXJzW2tleV07XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFwcGx5X2ZpbHRlcnMoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkdGFnLmFwcGVuZCgkcmVtb3ZlKTtcbiAgICAgICAgICAgICR0YWdzLmFwcGVuZCgkdGFnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9maWx0ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVfZmlsdGVycztcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fQWN0aW9uc19Db21wb25lbnQgLSBKUUhUTUwgQ29tcG9uZW50XG4gKlxuICogTGlmZWN5Y2xlIG1ldGhvZHMgYXJlIGNhbGxlZCBpbiB0aGlzIG9yZGVyOlxuICogMS4gb25fY3JlYXRlKCkgLSBRdWljayBVSSBzZXR1cCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICogMi4gb25fbG9hZCgpIC0gRmV0Y2ggZGF0YSBmcm9tIEFQSXMgKHBhcmFsbGVsIGV4ZWN1dGlvbiwgbm8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gKiAzLiBvbl9yZWFkeSgpIC0gQ29tcG9uZW50IGZ1bGx5IGluaXRpYWxpemVkLCBydW5zIGJvdHRvbS11cCB0aHJvdWdoIGNvbXBvbmVudCB0cmVlXG4gKi9cbmNsYXNzIEZvcm1fQWN0aW9uc19Db21wb25lbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgYWZ0ZXIgcmVuZGVyLCBxdWljayBVSSBzZXR1cCAoYm90dG9tLXVwKVxuICAgICAqIFVzZSBmb3I6IEluaXRpYWwgc3RhdGUsIGV2ZW50IGJpbmRpbmdzLCBzaG93aW5nIGxvYWRpbmcgaW5kaWNhdG9yc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy4kaWQoJ2xvYWRpbmcnKS5zaG93KCk7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJC5hZGRDbGFzcygnaW5pdGlhbGl6aW5nJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggZGF0YSBmcm9tIEFQSXMgKHBhcmFsbGVsLCBOTyBET00gbW9kaWZpY2F0aW9ucylcbiAgICAgKiBVc2UgZm9yOiBMb2FkaW5nIGRhdGEgZnJvbSBzZXJ2ZXIsIGZldGNoaW5nIGNvbmZpZ3VyYXRpb25zXG4gICAgICogV0FSTklORzogRG8gTk9UIG1vZGlmeSBET00gaGVyZSAtIG9ubHkgbG9hZCBkYXRhXG4gICAgICovXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5kYXRhLnVzZXJzID0gYXdhaXQgVXNlcnNfQ29udHJvbGxlci5nZXRfdXNlcnNfYXBpKCk7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS5jb25maWcgPSBhd2FpdCB0aGlzLmxvYWRfY29uZmlnKCk7XG4gICAgICAgIC8vIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCAoYm90dG9tLXVwKVxuICAgICAqIFVzZSBmb3I6IEZpbmFsIFVJIHNldHVwLCBoaWRpbmcgbG9hZGluZyBpbmRpY2F0b3JzLCBzdGFydGluZyBhbmltYXRpb25zXG4gICAgICovXG4gICAgYXN5bmMgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuaGlkZSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLnNldHVwX2V2ZW50X2xpc3RlbmVycygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsaWNrIGhhbmRsZXIgZm9yIHRoZSBoZWxsbyBidXR0b25cbiAgICAgKiBSZWZlcmVuY2VkIGluIHRlbXBsYXRlIHZpYSBAY2xpY2s9dGhpcy5vbl9jbGlja19oZWxsb1xuICAgICAqL1xuICAgIG9uX2NsaWNrX2hlbGxvKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5uZXJfaHRtbCcpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2hlbGxvX3dvcmxkJykuc2hvdygpO1xuICAgIH1cblxuICAgIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uOiBwaHAgYXJ0aXNhbiByc3g6bWFuIGpxaHRtbFxufSIsImNsYXNzIEZvcm1fRmllbGRfR3JvdXAgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gT3B0aW9uYWw6IEFkZCBjb2xsYXBzaWJsZSBmdW5jdGlvbmFsaXR5XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sbGFwc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMubWFrZV9jb2xsYXBzaWJsZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbWFrZV9jb2xsYXBzaWJsZSgpIHtcbiAgICAgICAgY29uc3QgJGhlYWRlciA9IHRoaXMuJC5maW5kKCcuY2FyZC1oZWFkZXInKTtcbiAgICAgICAgY29uc3QgJGJvZHkgPSB0aGlzLiQuZmluZCgnLmNhcmQtYm9keScpO1xuICAgICAgICBjb25zdCBjb2xsYXBzZV9pZCA9ICdjb2xsYXBzZV8nICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDkpO1xuXG4gICAgICAgICRib2R5LmF0dHIoJ2lkJywgY29sbGFwc2VfaWQpLmFkZENsYXNzKCdjb2xsYXBzZSBzaG93Jyk7XG5cbiAgICAgICAgY29uc3QgJHRvZ2dsZSA9ICQoJzxidXR0b24+JylcbiAgICAgICAgICAgIC5hdHRyKCd0eXBlJywgJ2J1dHRvbicpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2J0biBidG4tbGluayBidG4tc20gZmxvYXQtZW5kIHRleHQtZGVjb3JhdGlvbi1ub25lJylcbiAgICAgICAgICAgIC5hdHRyKCdkYXRhLWJzLXRvZ2dsZScsICdjb2xsYXBzZScpXG4gICAgICAgICAgICAuYXR0cignZGF0YS1icy10YXJnZXQnLCAnIycgKyBjb2xsYXBzZV9pZClcbiAgICAgICAgICAgIC5odG1sKCc8aSBjbGFzcz1cImJpIGJpLWNoZXZyb24tdXBcIj48L2k+Jyk7XG5cbiAgICAgICAgJGhlYWRlci5maW5kKCdoNScpLmFwcGVuZCgkdG9nZ2xlKTtcblxuICAgICAgICAkYm9keS5vbignc2hvdy5icy5jb2xsYXBzZScsICgpID0+IHtcbiAgICAgICAgICAgICR0b2dnbGUuaHRtbCgnPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLXVwXCI+PC9pPicpO1xuICAgICAgICB9KTtcblxuICAgICAgICAkYm9keS5vbignaGlkZS5icy5jb2xsYXBzZScsICgpID0+IHtcbiAgICAgICAgICAgICR0b2dnbGUuaHRtbCgnPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLWRvd25cIj48L2k+Jyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qKlxuICogRm9ybV9Hcm91cF9Db21wb25lbnQgLSBKUUhUTUwgQ29tcG9uZW50XG4gKlxuICogTGlmZWN5Y2xlIG1ldGhvZHMgYXJlIGNhbGxlZCBpbiB0aGlzIG9yZGVyOlxuICogMS4gb25fY3JlYXRlKCkgLSBRdWljayBVSSBzZXR1cCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICogMi4gb25fbG9hZCgpIC0gRmV0Y2ggZGF0YSBmcm9tIEFQSXMgKHBhcmFsbGVsIGV4ZWN1dGlvbiwgbm8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gKiAzLiBvbl9yZWFkeSgpIC0gQ29tcG9uZW50IGZ1bGx5IGluaXRpYWxpemVkLCBydW5zIGJvdHRvbS11cCB0aHJvdWdoIGNvbXBvbmVudCB0cmVlXG4gKi9cbmNsYXNzIEZvcm1fR3JvdXBfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlciwgcXVpY2sgVUkgc2V0dXAgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBJbml0aWFsIHN0YXRlLCBldmVudCBiaW5kaW5ncywgc2hvd2luZyBsb2FkaW5nIGluZGljYXRvcnNcbiAgICAgKi9cbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEFwcGx5IHJlc3BvbnNpdmUgY29sdW1uIGNsYXNzZXNcbiAgICAgICAgY29uc3QgY29sX2NsYXNzID0gdGhpcy5hcmdzLmNvbF9jbGFzcyB8fCAnY29sLTEyIGNvbC1tZC02IGNvbC14bC00JztcbiAgICAgICAgdGhpcy4kLmFkZENsYXNzKGNvbF9jbGFzcyArICcgbWItMycpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogRm9ybV9Sb3dfQ29tcG9uZW50IC0gSlFIVE1MIENvbXBvbmVudFxuICpcbiAqIExpZmVjeWNsZSBtZXRob2RzIGFyZSBjYWxsZWQgaW4gdGhpcyBvcmRlcjpcbiAqIDEuIG9uX2NyZWF0ZSgpIC0gUXVpY2sgVUkgc2V0dXAsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqIDIuIG9uX2xvYWQoKSAtIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCBleGVjdXRpb24sIG5vIERPTSBtb2RpZmljYXRpb25zKVxuICogMy4gb25fcmVhZHkoKSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICovXG5jbGFzcyBGb3JtX1Jvd19Db21wb25lbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgYWZ0ZXIgcmVuZGVyLCBxdWljayBVSSBzZXR1cCAoYm90dG9tLXVwKVxuICAgICAqIFVzZSBmb3I6IEluaXRpYWwgc3RhdGUsIGV2ZW50IGJpbmRpbmdzLCBzaG93aW5nIGxvYWRpbmcgaW5kaWNhdG9yc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy4kaWQoJ2xvYWRpbmcnKS5zaG93KCk7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJC5hZGRDbGFzcygnaW5pdGlhbGl6aW5nJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggZGF0YSBmcm9tIEFQSXMgKHBhcmFsbGVsLCBOTyBET00gbW9kaWZpY2F0aW9ucylcbiAgICAgKiBVc2UgZm9yOiBMb2FkaW5nIGRhdGEgZnJvbSBzZXJ2ZXIsIGZldGNoaW5nIGNvbmZpZ3VyYXRpb25zXG4gICAgICogV0FSTklORzogRG8gTk9UIG1vZGlmeSBET00gaGVyZSAtIG9ubHkgbG9hZCBkYXRhXG4gICAgICovXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5kYXRhLnVzZXJzID0gYXdhaXQgVXNlcnNfQ29udHJvbGxlci5nZXRfdXNlcnNfYXBpKCk7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS5jb25maWcgPSBhd2FpdCB0aGlzLmxvYWRfY29uZmlnKCk7XG4gICAgICAgIC8vIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCAoYm90dG9tLXVwKVxuICAgICAqIFVzZSBmb3I6IEZpbmFsIFVJIHNldHVwLCBoaWRpbmcgbG9hZGluZyBpbmRpY2F0b3JzLCBzdGFydGluZyBhbmltYXRpb25zXG4gICAgICovXG4gICAgYXN5bmMgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuaGlkZSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLnNldHVwX2V2ZW50X2xpc3RlbmVycygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsaWNrIGhhbmRsZXIgZm9yIHRoZSBoZWxsbyBidXR0b25cbiAgICAgKiBSZWZlcmVuY2VkIGluIHRlbXBsYXRlIHZpYSBAY2xpY2s9dGhpcy5vbl9jbGlja19oZWxsb1xuICAgICAqL1xuICAgIG9uX2NsaWNrX2hlbGxvKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5uZXJfaHRtbCcpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2hlbGxvX3dvcmxkJykuc2hvdygpO1xuICAgIH1cblxuICAgIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uOiBwaHAgYXJ0aXNhbiByc3g6bWFuIGpxaHRtbFxufSIsIi8qKlxuICogRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UgLSBCb290c3RyYXAgNSBWYWxpZGF0aW9uIEZlZWRiYWNrIENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IERpc3BsYXkgdmFsaWRhdGlvbiBmZWVkYmFjayBtZXNzYWdlcyAoc3VjY2Vzcy9lcnJvcikgYmVsb3cgZm9ybSBpbnB1dHNcbiAqIERlc2lnbjogQm9vdHN0cmFwIC5pbnZhbGlkLWZlZWRiYWNrIChkZWZhdWx0KSBvciAudmFsaWQtZmVlZGJhY2sgc3R5bGluZ1xuICogVmlzaWJpbGl0eTogT25seSBzaG93cyB3aGVuIHNpYmxpbmcgaW5wdXQgaGFzIC5pcy12YWxpZCBvciAuaXMtaW52YWxpZCBjbGFzc1xuICovXG5jbGFzcyBGb3JtX1ZhbGlkYXRpb25fTWVzc2FnZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWQgKGUuZy4sIHN3aXRjaGluZyB0byB2YWxpZC1mZWVkYmFjaylcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgLy8gUmVwbGFjZSBkZWZhdWx0IGludmFsaWQtZmVlZGJhY2sgd2l0aCBwcm92aWRlZCBjbGFzc1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCdpbnZhbGlkLWZlZWRiYWNrJyk7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3ModGhpcy5hcmdzLmNsYXNzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEdhbnR0X0NoYXJ0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kYXRhX3NvdXJjZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS50YXNrcyA9IGRhdGEudGFza3M7XG4gICAgICAgICAgICB0aGlzLmRhdGEubW9udGhzID0gZGF0YS5tb250aHM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcmdzLnRhc2tzKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEudGFza3MgPSB0aGlzLmFyZ3MudGFza3M7XG4gICAgICAgICAgICB0aGlzLmRhdGEubW9udGhzID0gdGhpcy5hcmdzLm1vbnRocyB8fCB0aGlzLmdlbmVyYXRlX21vbnRocygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfbW9udGhzKCkge1xuICAgICAgICBjb25zdCBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ107XG4gICAgICAgIHJldHVybiBtb250aHM7XG4gICAgfVxufVxuIiwiY2xhc3MgSWNvbl9CdXR0b24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQWRkIGFyaWEtbGFiZWwgZm9yIGFjY2Vzc2liaWxpdHkgKGljb24tb25seSBidXR0b25zIG5lZWQgbGFiZWxzKVxuICAgICAgICBpZiAodGhpcy5hcmdzLmxhYmVsKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignYXJpYS1sYWJlbCcsIHRoaXMuYXJncy5sYWJlbCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgdGl0bGUgZm9yIHRvb2x0aXAgb24gaG92ZXJcbiAgICAgICAgaWYgKHRoaXMuYXJncy50aXRsZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ3RpdGxlJywgdGhpcy5hcmdzLnRpdGxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN1cHBvcnQgY3VzdG9tIGJ1dHRvbiBjbGFzc2VzIChidG4tcHJpbWFyeSwgYnRuLWRhbmdlciwgZXRjLilcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBJY29uX1dpdGhfTGFiZWwgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIEljb25fV2l0aF9UZXh0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUHVyZSBCb290c3RyYXAgc3R5bGluZyAtIG5vIEphdmFTY3JpcHQgbmVlZGVkXG59XG4iLCJjbGFzcyBJY29uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gU1ZHIGljb24gY29udGFpbmVyIHdpdGggc2l6ZSB2YXJpYW50c1xufVxuIiwiY2xhc3MgSW5mb19Cb3ggZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYm9yZGVyLXByaW1hcnknKS5hZGRDbGFzcyhgYm9yZGVyLSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgSW5saW5lX0VkaXRfRmllbGQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50X3ZhbHVlID0gdGhpcy5hcmdzLnZhbHVlIHx8ICcnO1xuXG4gICAgICAgIC8vIEVudGVyIGVkaXQgbW9kZVxuICAgICAgICB0aGlzLiRpZCgnZGlzcGxheV9tb2RlJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbnRlcl9lZGl0X21vZGUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2F2ZVxuICAgICAgICB0aGlzLiRpZCgnc2F2ZV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNhdmUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2FuY2VsXG4gICAgICAgIHRoaXMuJGlkKCdjYW5jZWxfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2F2ZSBvbiBFbnRlciwgY2FuY2VsIG9uIEVzY2FwZVxuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5vbigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGUua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBlbnRlcl9lZGl0X21vZGUoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICAkaW5wdXQudmFsKHRoaXMuY3VycmVudF92YWx1ZSk7XG5cbiAgICAgICAgdGhpcy4kaWQoJ2Rpc3BsYXlfbW9kZScpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRfbW9kZScpLnNob3coKTtcblxuICAgICAgICAkaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgJGlucHV0LnNlbGVjdCgpO1xuICAgIH1cblxuICAgIGV4aXRfZWRpdF9tb2RlKCkge1xuICAgICAgICB0aGlzLiRpZCgnZWRpdF9tb2RlJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgnZGlzcGxheV9tb2RlJykuc2hvdygpO1xuICAgIH1cblxuICAgIHNhdmUoKSB7XG4gICAgICAgIGNvbnN0IG5ld192YWx1ZSA9IHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChuZXdfdmFsdWUgPT09IHRoaXMuY3VycmVudF92YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3NhdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuYXJncy5vbl9zYXZlKG5ld192YWx1ZSwgdGhpcy5jdXJyZW50X3ZhbHVlKTtcblxuICAgICAgICAgICAgLy8gSWYgY2FsbGJhY2sgcmV0dXJucyBmYWxzZSwgZG9uJ3Qgc2F2ZVxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybnMgYSBwcm9taXNlLCB3YWl0IGZvciBpdFxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dfc2F2aW5nKCk7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRfdmFsdWUgPSBuZXdfdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVudF92YWx1ZSA9IG5ld192YWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgICAgICB0aGlzLmV4aXRfZWRpdF9tb2RlKCk7XG4gICAgfVxuXG4gICAgY2FuY2VsKCkge1xuICAgICAgICB0aGlzLmV4aXRfZWRpdF9tb2RlKCk7XG4gICAgfVxuXG4gICAgdXBkYXRlX2Rpc3BsYXkoKSB7XG4gICAgICAgIGNvbnN0IGRpc3BsYXkgPSB0aGlzLmN1cnJlbnRfdmFsdWUgfHwgdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdDbGljayB0byBlZGl0JztcbiAgICAgICAgdGhpcy4kaWQoJ3ZhbHVlX2Rpc3BsYXknKS50ZXh0KGRpc3BsYXkpO1xuICAgIH1cblxuICAgIHNob3dfc2F2aW5nKCkge1xuICAgICAgICB0aGlzLiRpZCgnc2F2ZV9idG4nKS5wcm9wKCdkaXNhYmxlZCcsIHRydWUpLmh0bWwoJzxzcGFuIGNsYXNzPVwic3Bpbm5lci1ib3JkZXIgc3Bpbm5lci1ib3JkZXItc21cIj48L3NwYW4+Jyk7XG4gICAgICAgIHRoaXMuJGlkKCdjYW5jZWxfYnRuJykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICB9XG5cbiAgICBnZXRfdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRfdmFsdWU7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuY3VycmVudF92YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG4gICAgfVxufVxuIiwiY2xhc3MgSW5wdXRfV2l0aF9JY29uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgICRpbnB1dC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVhZG9ubHkpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZWFkb25seScsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9pbnB1dCkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2lucHV0KGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgSW5wdXRfV2l0aF9WYWxpZGF0aW9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgICRpbnB1dC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZWFkb25seSkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlYWRvbmx5JywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWFsLXRpbWUgdmFsaWRhdGlvblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbGlkYXRlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2JsdXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJC5oYXNDbGFzcygnd2FzLXZhbGlkYXRlZCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhbGlkYXRlKCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ3dhcy12YWxpZGF0ZWQnKTtcblxuICAgICAgICAvLyBSdW4gdmFsaWRhdGlvbiBmdW5jdGlvblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbGlkYXRlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmFyZ3MudmFsaWRhdGUodmFsdWUpO1xuXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB0cnVlIHx8IHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0X3ZhbGlkKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0X2Vycm9yKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmFzaWMgcmVxdWlyZWQgY2hlY2tcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCAmJiAhdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0X2Vycm9yKCdUaGlzIGZpZWxkIGlzIHJlcXVpcmVkJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldF92YWxpZCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBzZXRfZXJyb3IobWVzc2FnZSkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgY29uc3QgJGVycm9yID0gdGhpcy4kaWQoJ2Vycm9yJyk7XG5cbiAgICAgICAgJGlucHV0LnJlbW92ZUNsYXNzKCdpcy12YWxpZCcpLmFkZENsYXNzKCdpcy1pbnZhbGlkJyk7XG4gICAgICAgICRlcnJvci50ZXh0KG1lc3NhZ2UpLmNzcygnZGlzcGxheScsICdibG9jaycpO1xuICAgICAgICB0aGlzLiRpZCgnc3VjY2VzcycpLmNzcygnZGlzcGxheScsICdub25lJyk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbGlkKG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgIGNvbnN0ICRzdWNjZXNzID0gdGhpcy4kaWQoJ3N1Y2Nlc3MnKTtcblxuICAgICAgICAkaW5wdXQucmVtb3ZlQ2xhc3MoJ2lzLWludmFsaWQnKS5hZGRDbGFzcygnaXMtdmFsaWQnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Vycm9yJykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcblxuICAgICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICAgICAgJHN1Y2Nlc3MudGV4dChtZXNzYWdlKS5jc3MoJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRzdWNjZXNzLmNzcygnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcl92YWxpZGF0aW9uKCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgJGlucHV0LnJlbW92ZUNsYXNzKCdpcy12YWxpZCBpcy1pbnZhbGlkJyk7XG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcicpLmNzcygnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIHRoaXMuJGlkKCdzdWNjZXNzJykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcbiAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCd3YXMtdmFsaWRhdGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh2YWx1ZSk7XG4gICAgICAgIGlmICh0aGlzLiQuaGFzQ2xhc3MoJ3dhcy12YWxpZGF0ZWQnKSkge1xuICAgICAgICAgICAgdGhpcy52YWxpZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBJbnB1dCAtIEJvb3RzdHJhcCA1IFRleHQgSW5wdXQgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogU2luZ2xlLWxpbmUgdGV4dCBpbnB1dCBmaWVsZCBmb3IgdXNlciBkYXRhIGVudHJ5XG4gKiBEZXNpZ246IEJvb3RzdHJhcCAuZm9ybS1jb250cm9sIHN0eWxpbmdcbiAqIFR5cGVzOiB0ZXh0LCBlbWFpbCwgcGFzc3dvcmQsIG51bWJlciwgdGVsLCB1cmwsIGRhdGUsIGV0Yy5cbiAqL1xuY2xhc3MgSW5wdXQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHR5cGUgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudHlwZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ3R5cGUnLCB0aGlzLmFyZ3MudHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcGxhY2Vob2xkZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ3BsYWNlaG9sZGVyJywgdGhpcy5hcmdzLnBsYWNlaG9sZGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgS2FuYmFuX0JvYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kYXRhX3NvdXJjZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNvbHVtbnMgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcmdzLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb2x1bW5zID0gdGhpcy5hcmdzLmNvbHVtbnM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRHJhZyBhbmQgZHJvcCBmdW5jdGlvbmFsaXR5XG4gICAgICAgIHRoaXMuc2V0dXBfZHJhZ19hbmRfZHJvcCgpO1xuICAgIH1cblxuICAgIHNldHVwX2RyYWdfYW5kX2Ryb3AoKSB7XG4gICAgICAgIGxldCBkcmFnZ2VkX2NhcmQgPSBudWxsO1xuXG4gICAgICAgIC8vIE1ha2UgY2FyZHMgZHJhZ2dhYmxlXG4gICAgICAgIHRoaXMuJC5maW5kKCdbZGF0YS1jYXJkLWlkXScpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2FyZCA9ICQodGhpcyk7XG5cbiAgICAgICAgICAgICRjYXJkLm9uKCdkcmFnc3RhcnQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgZHJhZ2dlZF9jYXJkID0gdGhpcztcbiAgICAgICAgICAgICAgICAkKHRoaXMpLmNzcygnb3BhY2l0eScsICcwLjUnKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkY2FyZC5vbignZHJhZ2VuZCcsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAkKHRoaXMpLmNzcygnb3BhY2l0eScsICcxJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTWFrZSBjb2x1bW5zIGRyb3BwYWJsZVxuICAgICAgICB0aGlzLiQuZmluZCgnW2RhdGEtY29sdW1uLWNhcmRzXScpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY29sdW1uID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgJGNvbHVtbi5vbignZHJhZ292ZXInLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICRjb2x1bW4uYWRkQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGNvbHVtbi5vbignZHJhZ2xlYXZlJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgICRjb2x1bW4ucmVtb3ZlQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGNvbHVtbi5vbignZHJvcCcsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgJGNvbHVtbi5yZW1vdmVDbGFzcygnYmctbGlnaHQnKTtcblxuICAgICAgICAgICAgICAgIGlmIChkcmFnZ2VkX2NhcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgJGNvbHVtbi5hcHBlbmQoZHJhZ2dlZF9jYXJkKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FyZF9pZCA9ICQoZHJhZ2dlZF9jYXJkKS5hdHRyKCdkYXRhLWNhcmQtaWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbHVtbl9pZCA9ICRjb2x1bW4uYXR0cignZGF0YS1jb2x1bW4tY2FyZHMnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9tb3ZlKGNhcmRfaWQsIGNvbHVtbl9pZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgIH1cbn1cbiIsImNsYXNzIExpbmsgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU3VwcG9ydCAkaHJlZiBhdHRyaWJ1dGUgZm9yIGR5bmFtaWMgVVJMc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmhyZWYpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdocmVmJywgdGhpcy5hcmdzLmhyZWYpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgTGlzdCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBZGQgbGlzdC1ncm91cC1pdGVtIGNsYXNzIHRvIGVhY2ggZGlyZWN0IGNoaWxkXG4gICAgICAgIHRoaXMuJC5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkZWxlbWVudCA9ICQodGhpcyk7XG4gICAgICAgICAgICAkZWxlbWVudC5hZGRDbGFzcygnbGlzdC1ncm91cC1pdGVtJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIExvYWRpbmdfU2tlbGV0b24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgbGluZXMgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubGluZXMpIHtcbiAgICAgICAgICAgIHRoaXMuJC5lbXB0eSgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmFyZ3MubGluZXM7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gMTIgLSAoaSAqIDIpO1xuICAgICAgICAgICAgICAgIGNvbnN0ICRzcGFuID0gJCgnPHNwYW4+JykuYWRkQ2xhc3MoYHBsYWNlaG9sZGVyIGNvbC0ke01hdGgubWF4KHdpZHRoLCA2KX1gKTtcbiAgICAgICAgICAgICAgICB0aGlzLiQuYXBwZW5kKCRzcGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIE1ldHJpY19DYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUHVyZSBjb250YWluZXIgLSBjaGlsZHJlbiBhbHJlYWR5IHN0eWxlZFxufVxuIiwiY2xhc3MgTW9iaWxlX0hlYWRlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yXG4gICAgfVxufVxuIiwiY2xhc3MgTW9kYWxfRGlhbG9nIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgQm9vdHN0cmFwIG1vZGFsXG4gICAgICAgIHRoaXMubW9kYWwgPSBuZXcgYm9vdHN0cmFwLk1vZGFsKHRoaXMuJFswXSk7XG4gICAgfVxuXG4gICAgc2hvdygpIHtcbiAgICAgICAgdGhpcy5tb2RhbC5zaG93KCk7XG4gICAgfVxuXG4gICAgaGlkZSgpIHtcbiAgICAgICAgdGhpcy5tb2RhbC5oaWRlKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgTXVsdGlfU2VsZWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzID0gdGhpcy5hcmdzLnZhbHVlIHx8IFtdO1xuICAgICAgICB0aGlzLmFsbF9vcHRpb25zID0gdGhpcy5hcmdzLm9wdGlvbnMgfHwgW107XG5cbiAgICAgICAgaWYgKHRoaXMuYWxsX29wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyh0aGlzLmFsbF9vcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlYXJjaCBmdW5jdGlvbmFsaXR5XG4gICAgICAgIGNvbnN0ICRzZWFyY2ggPSB0aGlzLiRpZCgnc2VhcmNoJyk7XG4gICAgICAgICRzZWFyY2gub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyX29wdGlvbnMoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBQcmV2ZW50IGRyb3Bkb3duIGNsb3NlIHdoZW4gY2xpY2tpbmcgaW5zaWRlXG4gICAgICAgIHRoaXMuJGlkKCdtZW51Jykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENsZWFyL1NlbGVjdCBhbGwgYnV0dG9uc1xuICAgICAgICB0aGlzLiRpZCgnY2xlYXJfYWxsJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbGVhcl9hbGwoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy4kaWQoJ3NlbGVjdF9hbGwnKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdF9hbGwoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIGRpc3BsYXlcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgIH1cblxuICAgIHJlbmRlcl9vcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgJGNvbnRhaW5lciA9IHRoaXMuJGlkKCdvcHRpb25zJyk7XG4gICAgICAgICRjb250YWluZXIuZW1wdHkoKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICRjb250YWluZXIuYXBwZW5kKCQoJzxkaXY+JykuYWRkQ2xhc3MoJ3B4LTMgcHktMiB0ZXh0LW11dGVkJykudGV4dCgnTm8gb3B0aW9ucyBmb3VuZCcpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMuZm9yRWFjaChvcHRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3QgJGxhYmVsID0gJCgnPGxhYmVsPicpLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtIG1iLTAnKTtcbiAgICAgICAgICAgIGNvbnN0ICRjaGVja2JveCA9ICQoJzxpbnB1dD4nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCd0eXBlJywgJ2NoZWNrYm94JylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2Zvcm0tY2hlY2staW5wdXQgbWUtMicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtdmFsdWUnLCBvcHRpb24udmFsdWUpXG4gICAgICAgICAgICAgICAgLnByb3AoJ2NoZWNrZWQnLCB0aGlzLnNlbGVjdGVkX3ZhbHVlcy5pbmNsdWRlcyhvcHRpb24udmFsdWUpKTtcblxuICAgICAgICAgICAgJGNoZWNrYm94Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlX29wdGlvbihvcHRpb24udmFsdWUsIGUudGFyZ2V0LmNoZWNrZWQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRsYWJlbC5hcHBlbmQoJGNoZWNrYm94KS5hcHBlbmQob3B0aW9uLmxhYmVsKTtcbiAgICAgICAgICAgICRjb250YWluZXIuYXBwZW5kKCRsYWJlbCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZpbHRlcl9vcHRpb25zKHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gdGhpcy5hbGxfb3B0aW9ucy5maWx0ZXIob3B0ID0+XG4gICAgICAgICAgICBvcHQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeS50b0xvd2VyQ2FzZSgpKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcl9vcHRpb25zKGZpbHRlcmVkKTtcbiAgICB9XG5cbiAgICB0b2dnbGVfb3B0aW9uKHZhbHVlLCBjaGVja2VkKSB7XG4gICAgICAgIGlmIChjaGVja2VkKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRfdmFsdWVzLmluY2x1ZGVzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZF92YWx1ZXMgPSB0aGlzLnNlbGVjdGVkX3ZhbHVlcy5maWx0ZXIodiA9PiB2ICE9PSB2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UodGhpcy5zZWxlY3RlZF92YWx1ZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlX2Rpc3BsYXkoKSB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gdGhpcy5zZWxlY3RlZF92YWx1ZXMubGVuZ3RoO1xuICAgICAgICBjb25zdCAkdGV4dCA9IHRoaXMuJGlkKCdzZWxlY3RlZF90ZXh0Jyk7XG5cbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAkdGV4dC50ZXh0KHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IG9wdGlvbnMnKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5hbGxfb3B0aW9ucy5maW5kKG9wdCA9PiBvcHQudmFsdWUgPT09IHRoaXMuc2VsZWN0ZWRfdmFsdWVzWzBdKTtcbiAgICAgICAgICAgICR0ZXh0LnRleHQob3B0aW9uID8gb3B0aW9uLmxhYmVsIDogJzEgc2VsZWN0ZWQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR0ZXh0LnRleHQoYCR7Y291bnR9IHNlbGVjdGVkYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcl9hbGwoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzID0gW107XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykucHJvcCgnY2hlY2tlZCcsIGZhbHNlKTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKHRoaXMuc2VsZWN0ZWRfdmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdF9hbGwoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzID0gdGhpcy5hbGxfb3B0aW9ucy5tYXAob3B0ID0+IG9wdC52YWx1ZSk7XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykucHJvcCgnY2hlY2tlZCcsIHRydWUpO1xuICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UodGhpcy5zZWxlY3RlZF92YWx1ZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZF92YWx1ZXM7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlcykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IHZhbHVlcztcbiAgICAgICAgdGhpcy4kaWQoJ29wdGlvbnMnKS5maW5kKCdpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5lYWNoKChpLCBlbCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGVsID0gJChlbCk7XG4gICAgICAgICAgICAkZWwucHJvcCgnY2hlY2tlZCcsIHZhbHVlcy5pbmNsdWRlcygkZWwuYXR0cignZGF0YS12YWx1ZScpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG4gICAgfVxuXG4gICAgc2V0X29wdGlvbnMob3B0aW9ucykge1xuICAgICAgICB0aGlzLmFsbF9vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyhvcHRpb25zKTtcbiAgICB9XG59XG4iLCJjbGFzcyBOb3RpZmljYXRpb25fQmFkZ2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGNvdW50ID0gdGhpcy4kaWQoJ2NvdW50Jyk7XG4gICAgICAgIC8vIFVwZGF0ZSBjb3VudCBkeW5hbWljYWxseVxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvdW50ID09PSAwIHx8IHRoaXMuYXJncy5jb3VudCA9PT0gJzAnKSB7XG4gICAgICAgICAgICAkY291bnQuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X2NvdW50KGNvdW50KSB7XG4gICAgICAgIGNvbnN0ICRjb3VudCA9IHRoaXMuJGlkKCdjb3VudCcpO1xuICAgICAgICAkY291bnQudGV4dChjb3VudCk7XG4gICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICAgICRjb3VudC5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkY291bnQuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgTm90aWZpY2F0aW9uX0Ryb3Bkb3duIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBPdmVyZHVlX0luZGljYXRvciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgQm9vdHN0cmFwIHN0eWxpbmcgLSBubyBKYXZhU2NyaXB0IG5lZWRlZFxufVxuIiwiLyoqXG4gKiBQYWdlX0hlYWRlciAtIEJvb3RzdHJhcCA1IFBhZ2UgQWN0aW9uIEJhciBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBUb3Agc2VjdGlvbiBvZiBwYWdlIGNvbnRhaW5pbmcgdGl0bGUsIGJyZWFkY3J1bWJzLCBhbmQgYWN0aW9uc1xuICogRGVzaWduOiBGbGV4Ym94IGxheW91dCB1c2luZyBCb290c3RyYXAgdXRpbGl0eSBjbGFzc2VzXG4gKiBMYXlvdXQ6IFRpdGxlL2JyZWFkY3J1bWJzIG9uIGxlZnQsIGFjdGlvbnMvYnV0dG9ucyBvbiByaWdodFxuICovXG5jbGFzcyBQYWdlX0hlYWRlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFBhZ2VfSGVhZGVyIGlzIGEgcHVyZSBjb250YWluZXIgY29tcG9uZW50IC0gbm8gbGlmZWN5Y2xlIG1ldGhvZHMgbmVlZGVkXG4gICAgLy8gQWxsIGxheW91dCBmcm9tIEJvb3RzdHJhcCB1dGlsaXRpZXM6IGQtZmxleCwganVzdGlmeS1jb250ZW50LWJldHdlZW4sIGFsaWduLWl0ZW1zLWNlbnRlciwgcHktNFxufVxuIiwiY2xhc3MgUGFnZV9TZWN0aW9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gQ29udGVudCBzZWN0aW9uIHdpdGggc3BhY2luZyAtIG5vIHNwZWNpYWwgYmVoYXZpb3IgbmVlZGVkXG59XG4iLCJjbGFzcyBQYWdlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gU2VtYW50aWMgcGFnZSBjb250YWluZXIgLSBubyBzcGVjaWFsIGJlaGF2aW9yIG5lZWRlZFxufVxuIiwiY2xhc3MgUG9wb3ZlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTZXQgcG9wb3ZlciBjb250ZW50IGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLnRpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy10aXRsZScsIHRoaXMuYXJncy50aXRsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdkYXRhLWJzLWNvbnRlbnQnLCB0aGlzLmFyZ3MuY29udGVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdHJpZ2dlciAoaG92ZXIsIGNsaWNrLCBmb2N1cylcbiAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtYnMtdHJpZ2dlcicsIHRoaXMuYXJncy50cmlnZ2VyIHx8ICdjbGljaycpO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgQm9vdHN0cmFwIHBvcG92ZXJcbiAgICAgICAgbmV3IGJvb3RzdHJhcC5Qb3BvdmVyKHRoaXMuJFswXSk7XG4gICAgfVxufVxuIiwiY2xhc3MgUHJvZ3Jlc3NfQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRiYXIgPSB0aGlzLiRpZCgnYmFyJyk7XG5cbiAgICAgICAgLy8gQXBwbHkgY29sb3IgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sb3IpIHtcbiAgICAgICAgICAgICRiYXIuYWRkQ2xhc3MoYGJnLSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyB2YWx1ZSB0ZXh0IGlmIHJlcXVlc3RlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfdmFsdWUpIHtcbiAgICAgICAgICAgICRiYXIudGV4dChgJHt0aGlzLmFyZ3MudmFsdWUgfHwgMH0lYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRfdmFsdWUodmFsdWUpIHtcbiAgICAgICAgY29uc3QgJGJhciA9IHRoaXMuJGlkKCdiYXInKTtcbiAgICAgICAgJGJhci5jc3MoJ3dpZHRoJywgYCR7dmFsdWV9JWApLmF0dHIoJ2FyaWEtdmFsdWVub3cnLCB2YWx1ZSk7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2hvd192YWx1ZSkge1xuICAgICAgICAgICAgJGJhci50ZXh0KGAke3ZhbHVlfSVgKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8qKlxuICogUmFkaW9fQnV0dG9uIC0gQm9vdHN0cmFwIDUgUmFkaW8gSW5wdXQgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogUmFkaW8gYnV0dG9uIGZvciBtdXR1YWxseSBleGNsdXNpdmUgc2VsZWN0aW9ucyB3aXRoaW4gYSBncm91cFxuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY2hlY2staW5wdXQgc3R5bGluZyB3aXRoIGNpcmN1bGFyIHNoYXBlXG4gKiBDUklUSUNBTDogQWxsIHJhZGlvcyBpbiBzYW1lIGdyb3VwIG11c3QgaGF2ZSBzYW1lIFwibmFtZVwiIGF0dHJpYnV0ZVxuICogV3JhcHBlcjogVHlwaWNhbGx5IHVzZWQgd2l0aGluIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+IGFuZCA8ZmllbGRzZXQ+XG4gKi9cbmNsYXNzIFJhZGlvX0J1dHRvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTZXQgbmFtZSBhdHRyaWJ1dGUgKENSSVRJQ0FMIGZvciBncm91cGluZylcbiAgICAgICAgaWYgKHRoaXMuYXJncy5uYW1lKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBjaGVja2VkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2hlY2tlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgUmljaF9UZXh0X0VkaXRvciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkZWRpdG9yID0gdGhpcy4kaWQoJ2VkaXRvcicpO1xuXG4gICAgICAgIC8vIFRvb2xiYXIgYnV0dG9uIGhhbmRsZXJzXG4gICAgICAgIHRoaXMuJGlkKCd0b29sYmFyJykuZmluZCgnW2RhdGEtY29tbWFuZF0nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgY29uc3QgY29tbWFuZCA9ICQoZS5jdXJyZW50VGFyZ2V0KS5hdHRyKCdkYXRhLWNvbW1hbmQnKTtcblxuICAgICAgICAgICAgaWYgKGNvbW1hbmQgPT09ICdjcmVhdGVMaW5rJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IHByb21wdCgnRW50ZXIgVVJMOicpO1xuICAgICAgICAgICAgICAgIGlmICh1cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIHVybCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbnVsbCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICRlZGl0b3IuZm9jdXMoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVHJhY2sgY2hhbmdlc1xuICAgICAgICAkZWRpdG9yLm9uKCdpbnB1dCcsICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZSh0aGlzLmdldF92YWx1ZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUHJldmVudCBkZWZhdWx0IGJlaGF2aW9yIG9uIHBhc3RlIChvcHRpb25hbCAtIGNhbiBiZSBjdXN0b21pemVkKVxuICAgICAgICAkZWRpdG9yLm9uKCdwYXN0ZScsIChlKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLnBsYWluX3RleHRfcGFzdGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IGUub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnaW5zZXJ0VGV4dCcsIGZhbHNlLCB0ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2VkaXRvcicpLmh0bWwoKTtcbiAgICB9XG5cbiAgICBnZXRfdGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdlZGl0b3InKS50ZXh0KCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKGh0bWwpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRvcicpLmh0bWwoaHRtbCk7XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdlZGl0b3InKS5lbXB0eSgpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnZWRpdG9yJykuZm9jdXMoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBSb3dfQWN0aW9uX01lbnUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBjaGlsZHJlbiBpbiBkcm9wZG93biBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgJG1lbnUgPSB0aGlzLiRpZCgnbWVudScpO1xuICAgICAgICAkbWVudS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSA9PT0gJ0hSJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+JykuYXBwZW5kKCQoJzxocj4nKS5hZGRDbGFzcygnZHJvcGRvd24tZGl2aWRlcicpKTtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLnJlcGxhY2VXaXRoKCRsaSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKTtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLndyYXAoJGxpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qKlxuICogU2FtcGxlX0RhdGFncmlkX0NvbXBvbmVudFxuICpcbiAqIEZ1bGwtZmVhdHVyZWQgZGF0YSB0YWJsZSB3aXRoOlxuICogLSBSb3cgc2VsZWN0aW9uIChjaGVja2JveGVzKVxuICogLSBQYWdpbmF0aW9uXG4gKiAtIFJvdyBhY3Rpb25zICh2aWV3LCBlZGl0LCBkZWxldGUpXG4gKiAtIExvYWRpbmcgc3RhdGVzIHdpdGggcGxhY2Vob2xkZXJzXG4gKiAtIEVtcHR5IHN0YXRlc1xuICpcbiAqIFVzYWdlOlxuICogPFNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcbiAqICAgJHRpdGxlPVwiQ2xpZW50IExpc3RcIlxuICogICAkZW50aXR5X25hbWU9XCJjbGllbnRzXCJcbiAqICAgJHNlbGVjdGFibGU9dHJ1ZVxuICogICAkcGFnaW5hdGlvbj10cnVlXG4gKiAgICRhbGxvd19kZWxldGU9dHJ1ZVxuICogICAkdmlld191cmw9XCIvY2xpZW50cy97aWR9XCJcbiAqICAgJGVkaXRfdXJsPVwiL2NsaWVudHMve2lkfS9lZGl0XCJcbiAqICAgJGFwaV91cmw9XCIvYXBpL2NsaWVudHNcIlxuICogICAkY29sdW1ucz1jb2x1bW5zX2RlZmluaXRpb25cbiAqIC8+XG4gKi9cbmNsYXNzIFNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcblxuICBhc3luYyBvbl9sb2FkKCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIC8vIElmIEFQSSBVUkwgcHJvdmlkZWQsIGZldGNoIGRhdGFcbiAgICBpZiAodGhhdC5hcmdzLmFwaV91cmwpIHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhhdC5hcmdzLmFwaV91cmwpO1xuICAgICAgdGhhdC5kYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBHZW5lcmF0ZSBzYW1wbGUgZGF0YSBmb3IgZGVtb25zdHJhdGlvblxuICAgICAgdGhhdC5kYXRhID0gdGhhdC5nZW5lcmF0ZV9zYW1wbGVfZGF0YSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uX3JlYWR5KCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIC8vIFNlbGVjdCBhbGwgY2hlY2tib3hcbiAgICBpZiAodGhhdC5hcmdzLnNlbGVjdGFibGUpIHtcbiAgICAgIHRoYXQuJGlkKCdzZWxlY3RfYWxsJykub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoZWNrZWQgPSBlLnRhcmdldC5jaGVja2VkO1xuICAgICAgICB0aGF0LiQuZmluZCgndGJvZHkgaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykucHJvcCgnY2hlY2tlZCcsIGNoZWNrZWQpO1xuICAgICAgICB0aGF0LnVwZGF0ZV9zZWxlY3Rpb25fY291bnQoKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBJbmRpdmlkdWFsIHJvdyBjaGVja2JveGVzXG4gICAgICB0aGF0LiQuZmluZCgndGJvZHkgaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhhdC51cGRhdGVfc2VsZWN0aW9uX2NvdW50KCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEZWxldGUgYnV0dG9uc1xuICAgIGlmICh0aGF0LmFyZ3MuYWxsb3dfZGVsZXRlKSB7XG4gICAgICB0aGF0LiQuZmluZCgnYnV0dG9uW2RhdGEtaWRdJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgY29uc3QgJGJ1dHRvbiA9ICQoZS5jdXJyZW50VGFyZ2V0KTtcbiAgICAgICAgY29uc3QgaWQgPSAkYnV0dG9uLmRhdGEoJ2lkJyk7XG4gICAgICAgIHRoYXQuY29uZmlybV9kZWxldGUoaWQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUGFnaW5hdGlvblxuICAgIGlmICh0aGF0LmFyZ3MucGFnaW5hdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgIHRoYXQuJGlkKCdwcmV2X3BhZ2UnKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoYXQuZ29fdG9fcGFnZSh0aGF0LmRhdGEucGFnaW5hdGlvbi5jdXJyZW50X3BhZ2UgLSAxKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGF0LiRpZCgnbmV4dF9wYWdlJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGF0LmdvX3RvX3BhZ2UodGhhdC5kYXRhLnBhZ2luYXRpb24uY3VycmVudF9wYWdlICsgMSk7XG4gICAgICB9KTtcblxuICAgICAgdGhhdC4kLmZpbmQoJy5wYWdlLWxpbmtbZGF0YS1wYWdlXScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgJGxpbmsgPSAkKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSBpbnQoJGxpbmsuZGF0YSgncGFnZScpKTtcbiAgICAgICAgdGhhdC5nb190b19wYWdlKHBhZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBVSSB0byBzaG93IGhvdyBtYW55IHJvd3MgYXJlIHNlbGVjdGVkXG4gICAqL1xuICB1cGRhdGVfc2VsZWN0aW9uX2NvdW50KCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhhdC4kLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXTpjaGVja2VkJykubGVuZ3RoO1xuXG4gICAgaWYgKHNlbGVjdGVkID4gMCkge1xuICAgICAgLy8gQ291bGQgc2hvdyBhIGJhbm5lcjogXCIzIGl0ZW1zIHNlbGVjdGVkXCJcbiAgICAgIGNvbnNvbGUubG9nKGAke3NlbGVjdGVkfSBpdGVtcyBzZWxlY3RlZGApO1xuXG4gICAgICAvLyBGaXJlIGV2ZW50IGZvciBwYXJlbnQgY29tcG9uZW50cyB0byBsaXN0ZW4gdG9cbiAgICAgIHRoYXQuJC50cmlnZ2VyKCdzZWxlY3Rpb246Y2hhbmdlZCcsIHsgY291bnQ6IHNlbGVjdGVkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXJyYXkgb2Ygc2VsZWN0ZWQgSURzXG4gICAqL1xuICBnZXRfc2VsZWN0ZWRfaWRzKCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIGNvbnN0IGlkcyA9IFtdO1xuICAgIHRoYXQuJC5maW5kKCd0Ym9keSBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZCcpLmVhY2goKGksIGNoZWNrYm94KSA9PiB7XG4gICAgICBjb25zdCAkY2hlY2tib3ggPSAkKGNoZWNrYm94KTtcbiAgICAgIGNvbnN0IGlkID0gJGNoZWNrYm94LmRhdGEoJ2lkJyk7XG4gICAgICBpZiAoaWQpIGlkcy5wdXNoKGlkKTtcbiAgICB9KTtcbiAgICByZXR1cm4gaWRzO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBzZWxlY3Rpb25zXG4gICAqL1xuICBjbGVhcl9zZWxlY3Rpb24oKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgdGhhdC4kLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgdGhhdC51cGRhdGVfc2VsZWN0aW9uX2NvdW50KCk7XG4gIH1cblxuICAvKipcbiAgICogQ29uZmlybSBkZWxldGlvbiBvZiBhIHJvd1xuICAgKi9cbiAgY29uZmlybV9kZWxldGUoaWQpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyBJbiBhIHJlYWwgYXBwLCBzaG93IGEgQm9vdHN0cmFwIG1vZGFsXG4gICAgaWYgKGNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBpdGVtPycpKSB7XG4gICAgICB0aGF0LmRlbGV0ZV9yb3coaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSByb3cgKHdvdWxkIHR5cGljYWxseSBtYWtlIEFQSSBjYWxsKVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlX3JvdyhpZCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIHRyeSB7XG4gICAgICAvLyBNYWtlIEFQSSBjYWxsXG4gICAgICAvLyBhd2FpdCBmZXRjaChgJHt0aGF0LmFyZ3MuYXBpX3VybH0vJHtpZH1gLCB7IG1ldGhvZDogJ0RFTEVURScgfSk7XG5cbiAgICAgIC8vIFJlbW92ZSByb3cgZnJvbSBkYXRhXG4gICAgICB0aGF0LmRhdGEucm93cyA9IHRoYXQuZGF0YS5yb3dzLmZpbHRlcihyb3cgPT4gcm93LmlkICE9PSBpZCk7XG5cbiAgICAgIC8vIFJlLXJlbmRlciBjb21wb25lbnRcbiAgICAgIHRoYXQucmVmcmVzaCgpO1xuXG4gICAgICAvLyBTaG93IHN1Y2Nlc3MgbWVzc2FnZVxuICAgICAgY29uc29sZS5sb2coYERlbGV0ZWQgaXRlbSAke2lkfWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdEZWxldGUgZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIGFsZXJ0KCdGYWlsZWQgdG8gZGVsZXRlIGl0ZW0nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTmF2aWdhdGUgdG8gYSBzcGVjaWZpYyBwYWdlXG4gICAqL1xuICBhc3luYyBnb190b19wYWdlKHBhZ2UpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBpZiAocGFnZSA8IDEgfHwgcGFnZSA+IHRoYXQuZGF0YS5wYWdpbmF0aW9uLnRvdGFsX3BhZ2VzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2hvdyBsb2FkaW5nIHN0YXRlXG4gICAgdGhhdC4kLmZpbmQoJ3Rib2R5JykuY3NzKCdvcGFjaXR5JywgJzAuNScpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEZldGNoIG5ldyBwYWdlXG4gICAgICBjb25zdCB1cmwgPSBgJHt0aGF0LmFyZ3MuYXBpX3VybH0/cGFnZT0ke3BhZ2V9YDtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICAgIHRoYXQuZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgLy8gUmUtcmVuZGVyXG4gICAgICB0aGF0LnJlZnJlc2goKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignUGFnaW5hdGlvbiBmYWlsZWQ6JywgZXJyb3IpO1xuICAgICAgdGhhdC4kLmZpbmQoJ3Rib2R5JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVmcmVzaCB0aGUgdGFibGUgKHJlbG9hZCBkYXRhIGFuZCByZS1yZW5kZXIpXG4gICAqL1xuICBhc3luYyByZWxvYWRfZGF0YSgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICB0aGF0LmRhdGEgPSB7fTsgLy8gQ2xlYXIgZGF0YSB0byBzaG93IGxvYWRpbmcgc3RhdGVcbiAgICB0aGF0LnJlZnJlc2goKTtcblxuICAgIGF3YWl0IHRoYXQub25fbG9hZCgpO1xuICAgIHRoYXQucmVmcmVzaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHNhbXBsZSBkYXRhIGZvciBkZW1vbnN0cmF0aW9uIHB1cnBvc2VzXG4gICAqL1xuICBnZW5lcmF0ZV9zYW1wbGVfZGF0YSgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCBzdGF0dXNlcyA9IFtcbiAgICAgIHsgbGFiZWw6ICdBY3RpdmUnLCBjb2xvcjogJ3N1Y2Nlc3MnIH0sXG4gICAgICB7IGxhYmVsOiAnUGVuZGluZycsIGNvbG9yOiAnd2FybmluZycgfSxcbiAgICAgIHsgbGFiZWw6ICdJbmFjdGl2ZScsIGNvbG9yOiAnc2Vjb25kYXJ5JyB9LFxuICAgICAgeyBsYWJlbDogJ1N1c3BlbmRlZCcsIGNvbG9yOiAnZGFuZ2VyJyB9XG4gICAgXTtcblxuICAgIGNvbnN0IGZpcnN0X25hbWVzID0gWydKb2huJywgJ1NhcmFoJywgJ01pY2hhZWwnLCAnRW1pbHknLCAnRGF2aWQnLCAnTGlzYScsICdSb2JlcnQnLCAnSmVubmlmZXInLCAnV2lsbGlhbScsICdBbWFuZGEnXTtcbiAgICBjb25zdCBsYXN0X25hbWVzID0gWydTbWl0aCcsICdKb2huc29uJywgJ0Jyb3duJywgJ0dhcmNpYScsICdNYXJ0aW5leicsICdMZWUnLCAnQW5kZXJzb24nLCAnVGhvbXBzb24nLCAnV2hpdGUnLCAnRGF2aXMnXTtcbiAgICBjb25zdCBjb21wYW5pZXMgPSBbJ0FjbWUgQ29ycCcsICdUZWNoIFNvbHV0aW9ucycsICdHbG9iYWwgRW50ZXJwcmlzZXMnLCAnSW5ub3ZhdGlvbiBMYWJzJywgJ0RpZ2l0YWwgU3lzdGVtcycsICdDbG91ZCBTZXJ2aWNlcycsICdTbWFydCBJbmR1c3RyaWVzJywgJ0Z1dHVyZSBOZXR3b3JrcycsICdQcmltZSBDb25zdWx0aW5nJywgJ0VsaXRlIFBhcnRuZXJzJ107XG5cbiAgICBjb25zdCByb3dzID0gW107XG4gICAgY29uc3QgY291bnQgPSB0aGF0LmFyZ3Muc2hvd2luZyB8fCAxMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgY29uc3QgZmlyc3RfbmFtZSA9IGZpcnN0X25hbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGZpcnN0X25hbWVzLmxlbmd0aCldO1xuICAgICAgY29uc3QgbGFzdF9uYW1lID0gbGFzdF9uYW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsYXN0X25hbWVzLmxlbmd0aCldO1xuICAgICAgY29uc3QgY29tcGFueSA9IGNvbXBhbmllc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjb21wYW5pZXMubGVuZ3RoKV07XG4gICAgICBjb25zdCBzdGF0dXMgPSBzdGF0dXNlc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBzdGF0dXNlcy5sZW5ndGgpXTtcblxuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgaWQ6IGBDJHtzdHIoaSArIDEpLnBhZFN0YXJ0KDMsICcwJyl9YCxcbiAgICAgICAgbmFtZTogYCR7Zmlyc3RfbmFtZX0gJHtsYXN0X25hbWV9YCxcbiAgICAgICAgY29tcGFueTogY29tcGFueSxcbiAgICAgICAgZW1haWw6IGAke2ZpcnN0X25hbWUudG9Mb3dlckNhc2UoKX0uJHtsYXN0X25hbWUudG9Mb3dlckNhc2UoKX1AJHtjb21wYW55LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxzKy9nLCAnJyl9LmNvbWAsXG4gICAgICAgIHBob25lOiBgKDU1NSkgJHtzdHIoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogOTAwKSArIDEwMCl9LSR7c3RyKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDkwMDApICsgMTAwMCl9YCxcbiAgICAgICAgc3RhdHVzOiBzdGF0dXMubGFiZWwsXG4gICAgICAgIHN0YXR1c19jb2xvcjogc3RhdHVzLmNvbG9yLFxuICAgICAgICBjcmVhdGVkOiB0aGF0LnJhbmRvbV9kYXRlKClcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByb3dzOiByb3dzLFxuICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICBjdXJyZW50X3BhZ2U6IDEsXG4gICAgICAgIHRvdGFsX3BhZ2VzOiBNYXRoLmNlaWwoKHRoYXQuYXJncy50b3RhbCB8fCAxMDApIC8gY291bnQpLFxuICAgICAgICBmcm9tOiAxLFxuICAgICAgICB0bzogY291bnQsXG4gICAgICAgIHRvdGFsOiB0aGF0LmFyZ3MudG90YWwgfHwgMTAwLFxuICAgICAgICBwYWdlczogWzEsIDIsIDMsICcuLi4nLCBNYXRoLmNlaWwoKHRoYXQuYXJncy50b3RhbCB8fCAxMDApIC8gY291bnQpXVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcmFuZG9tIGRhdGUgZm9yIHNhbXBsZSBkYXRhXG4gICAqL1xuICByYW5kb21fZGF0ZSgpIHtcbiAgICBjb25zdCBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ107XG4gICAgY29uc3QgbW9udGggPSBtb250aHNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTIpXTtcbiAgICBjb25zdCBkYXkgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyOCkgKyAxO1xuICAgIHJldHVybiBgJHttb250aH0gJHtzdHIoZGF5KS5wYWRTdGFydCgyLCAnMCcpfSwgMjAyNGA7XG4gIH1cbn1cbiIsImNsYXNzIFNlYXJjaF9CYXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQmluZCBzZWFyY2ggZXZlbnRcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zZWFyY2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fc2VhcmNoKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgU2VhcmNoYWJsZV9TZWxlY3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZF92YWx1ZSA9IHRoaXMuYXJncy52YWx1ZSB8fCBudWxsO1xuICAgICAgICB0aGlzLmFsbF9vcHRpb25zID0gdGhpcy5hcmdzLm9wdGlvbnMgfHwgW107XG5cbiAgICAgICAgaWYgKHRoaXMuYWxsX29wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyh0aGlzLmFsbF9vcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlYXJjaCBmdW5jdGlvbmFsaXR5XG4gICAgICAgIGNvbnN0ICRzZWFyY2ggPSB0aGlzLiRpZCgnc2VhcmNoJyk7XG4gICAgICAgICRzZWFyY2gub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyX29wdGlvbnMoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBQcmV2ZW50IGRyb3Bkb3duIGNsb3NlIHdoZW4gY2xpY2tpbmcgc2VhcmNoIGlucHV0XG4gICAgICAgICRzZWFyY2gub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBzZWxlY3RlZCB0ZXh0IGlmIGluaXRpYWwgdmFsdWUgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRfdmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkX29wdGlvbiA9IHRoaXMuYWxsX29wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09IHRoaXMuc2VsZWN0ZWRfdmFsdWUpO1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkX29wdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdzZWxlY3RlZF90ZXh0JykudGV4dChzZWxlY3RlZF9vcHRpb24ubGFiZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVuZGVyX29wdGlvbnMob3B0aW9ucykge1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kaWQoJ29wdGlvbnMnKTtcbiAgICAgICAgJGNvbnRhaW5lci5lbXB0eSgpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgJGNvbnRhaW5lci5hcHBlbmQoJCgnPGRpdj4nKS5hZGRDbGFzcygncHgtMyBweS0yIHRleHQtbXV0ZWQnKS50ZXh0KCdObyBvcHRpb25zIGZvdW5kJykpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKG9wdGlvbiA9PiB7XG4gICAgICAgICAgICBjb25zdCAkaXRlbSA9ICQoJzxhPicpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJylcbiAgICAgICAgICAgICAgICAuYXR0cignaHJlZicsICcjJylcbiAgICAgICAgICAgICAgICAudGV4dChvcHRpb24ubGFiZWwpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2RhdGEtdmFsdWUnLCBvcHRpb24udmFsdWUpO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9uLnZhbHVlID09IHRoaXMuc2VsZWN0ZWRfdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAkaXRlbS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICRpdGVtLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0X29wdGlvbihvcHRpb24pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRjb250YWluZXIuYXBwZW5kKCRpdGVtKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZmlsdGVyX29wdGlvbnMocXVlcnkpIHtcbiAgICAgICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLmFsbF9vcHRpb25zLmZpbHRlcihvcHQgPT5cbiAgICAgICAgICAgIG9wdC5sYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHF1ZXJ5LnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnMoZmlsdGVyZWQpO1xuICAgIH1cblxuICAgIHNlbGVjdF9vcHRpb24ob3B0aW9uKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWUgPSBvcHRpb24udmFsdWU7XG4gICAgICAgIHRoaXMuJGlkKCdzZWxlY3RlZF90ZXh0JykudGV4dChvcHRpb24ubGFiZWwpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBhY3RpdmUgc3RhdGVcbiAgICAgICAgdGhpcy4kaWQoJ29wdGlvbnMnKS5maW5kKCcuZHJvcGRvd24taXRlbScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgdGhpcy4kaWQoJ29wdGlvbnMnKS5maW5kKGBbZGF0YS12YWx1ZT1cIiR7b3B0aW9uLnZhbHVlfVwiXWApLmFkZENsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICAvLyBDbG9zZSBkcm9wZG93blxuICAgICAgICBjb25zdCBkcm9wZG93biA9IGJvb3RzdHJhcC5Ecm9wZG93bi5nZXRJbnN0YW5jZSh0aGlzLiRpZCgnYnV0dG9uJylbMF0pO1xuICAgICAgICBpZiAoZHJvcGRvd24pIHtcbiAgICAgICAgICAgIGRyb3Bkb3duLmhpZGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENsZWFyIHNlYXJjaFxuICAgICAgICB0aGlzLiRpZCgnc2VhcmNoJykudmFsKCcnKTtcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyh0aGlzLmFsbF9vcHRpb25zKTtcblxuICAgICAgICAvLyBUcmlnZ2VyIGNhbGxiYWNrXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKG9wdGlvbi52YWx1ZSwgb3B0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRfdmFsdWU7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5hbGxfb3B0aW9ucy5maW5kKG9wdCA9PiBvcHQudmFsdWUgPT0gdmFsdWUpO1xuICAgICAgICBpZiAob3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpLnRleHQob3B0aW9uLmxhYmVsKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnLmRyb3Bkb3duLWl0ZW0nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoYFtkYXRhLXZhbHVlPVwiJHt2YWx1ZX1cIl1gKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRfb3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuYWxsX29wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLnJlbmRlcl9vcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogU2VsZWN0X0Ryb3Bkb3duIC0gQm9vdHN0cmFwIDUgRHJvcGRvd24gU2VsZWN0aW9uIENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IERyb3Bkb3duIG1lbnUgZm9yIHNlbGVjdGluZyBvbmUgb3B0aW9uIGZyb20gYSBsaXN0XG4gKiBEZXNpZ246IEJvb3RzdHJhcCAuZm9ybS1zZWxlY3Qgc3R5bGluZyB3aXRoIGRyb3Bkb3duIGFycm93XG4gKiBDb250ZW50OiBDb250YWlucyA8b3B0aW9uPiBlbGVtZW50c1xuICovXG5jbGFzcyBTZWxlY3RfRHJvcGRvd24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHZhbHVlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuJC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBjdXN0b20gY2xhc3NlcyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3ModGhpcy5hcmdzLmNsYXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkaXNhYmxlZCBzdGF0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCByZXF1aXJlZCBhdHRyaWJ1dGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBTaWRlYmFyX05hdiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBdXRvLXdyYXAgY2hpbGRyZW4gaW4gbmF2IHN0cnVjdHVyZSBpZiBuZWVkZWRcbiAgICAgICAgY29uc3QgJG5hdl9pdGVtcyA9IHRoaXMuJGlkKCduYXZfaXRlbXMnKTtcbiAgICAgICAgJG5hdl9pdGVtcy5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+JykuYWRkQ2xhc3MoJ25hdi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCduYXYtbGluaycpO1xuICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCBhY3RpdmUgc3RhdGUgYmFzZWQgb24gY3VycmVudCBVUkxcbiAgICAgICAgY29uc3QgY3VycmVudF9wYXRoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xuICAgICAgICAkbmF2X2l0ZW1zLmZpbmQoJ2EubmF2LWxpbmsnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRsaW5rLmF0dHIoJ2hyZWYnKSA9PT0gY3VycmVudF9wYXRoKSB7XG4gICAgICAgICAgICAgICAgJGxpbmsuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBTb3J0YWJsZV9Db2x1bW5fSGVhZGVyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENsaWNrIHRvIHRvZ2dsZSBzb3J0XG4gICAgICAgIHRoaXMuJC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZV9zb3J0KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCBpbml0aWFsIHNvcnQgc3RhdGVcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zb3J0KSB7XG4gICAgICAgICAgICB0aGlzLnNldF9zb3J0KHRoaXMuYXJncy5zb3J0KTsgLy8gJ2FzYycgb3IgJ2Rlc2MnXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0b2dnbGVfc29ydCgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuJC5hdHRyKCdkYXRhLXNvcnQnKSB8fCAnbm9uZSc7XG4gICAgICAgIGNvbnN0IG5leHQgPSBjdXJyZW50ID09PSAnbm9uZScgPyAnYXNjJyA6IGN1cnJlbnQgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgIHRoaXMuc2V0X3NvcnQobmV4dCk7XG5cbiAgICAgICAgLy8gQ2FsbCBjYWxsYmFjayBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3NvcnQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9zb3J0KHRoaXMuYXJncy5jb2x1bW4sIG5leHQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X3NvcnQoZGlyZWN0aW9uKSB7XG4gICAgICAgIHRoaXMuJC5hdHRyKCdkYXRhLXNvcnQnLCBkaXJlY3Rpb24pO1xuICAgICAgICBjb25zdCAkaWNvbiA9IHRoaXMuJGlkKCdzb3J0X2ljb24nKTtcblxuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnYXNjJykge1xuICAgICAgICAgICAgJGljb24uaHRtbCgnPGkgY2xhc3M9XCJ0ZXh0LXByaW1hcnlcIj7ihpE8L2k+Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnZGVzYycpIHtcbiAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1wcmltYXJ5XCI+4oaTPC9pPicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGljb24uaHRtbCgnPGkgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+4oeFPC9pPicpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgU3Bpbm5lciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBcHBseSBzaXplIChzbSlcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zaXplID09PSAnc20nKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ3NwaW5uZXItYm9yZGVyLXNtJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBseSBjb2xvclxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbG9yKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoYHRleHQtJHt0aGlzLmFyZ3MuY29sb3J9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBTdGF0X0NhcmQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIFN0YXR1c19CYWRnZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBcHBseSBjb2xvciBiYXNlZCBvbiBjb250ZW50IG9yIGFyZ3NcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gdGhpcy5hcmdzLnN0YXR1cyB8fCB0aGlzLiQudGV4dCgpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgIC8vIERlZmF1bHQgY29sb3IgbWFwcGluZ3NcbiAgICAgICAgY29uc3QgY29sb3JfbWFwID0ge1xuICAgICAgICAgICAgJ2FjdGl2ZSc6ICdiZy1zdWNjZXNzJyxcbiAgICAgICAgICAgICdwZW5kaW5nJzogJ2JnLXdhcm5pbmcnLFxuICAgICAgICAgICAgJ2NvbXBsZXRlZCc6ICdiZy1wcmltYXJ5JyxcbiAgICAgICAgICAgICdjYW5jZWxsZWQnOiAnYmctZGFuZ2VyJyxcbiAgICAgICAgICAgICdkcmFmdCc6ICdiZy1zZWNvbmRhcnknLFxuICAgICAgICAgICAgJ2FyY2hpdmVkJzogJ2JnLWRhcmsnXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYmdfY2xhc3MgPSB0aGlzLmFyZ3MuYmdfY2xhc3MgfHwgY29sb3JfbWFwW3N0YXR1c10gfHwgJ2JnLXNlY29uZGFyeSc7XG4gICAgICAgIHRoaXMuJC5hZGRDbGFzcyhiZ19jbGFzcyk7XG4gICAgfVxufVxuIiwiY2xhc3MgVGFiX0NvbnRlbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRW5zdXJlIGNoaWxkcmVuIGhhdmUgdGFiLXBhbmUgY2xhc3NcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ3RhYi1wYW5lIGZhZGUnKTtcblxuICAgICAgICAgICAgLy8gU2V0IGZpcnN0IHBhbmUgYXMgYWN0aXZlIGlmIG5vbmUgYWN0aXZlXG4gICAgICAgICAgICBpZiAoJGNoaWxkLnBhcmVudCgpLmZpbmQoJy50YWItcGFuZS5hY3RpdmUnKS5sZW5ndGggPT09IDAgJiYgJGNoaWxkLmluZGV4KCkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ3Nob3cgYWN0aXZlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFRhYmxlX1BhZ2luYXRpb24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gR2VuZXJhdGUgcGFnaW5hdGlvbiBpZiBwYWdlcyBwcm92aWRlZCB2aWEgYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmN1cnJlbnRfcGFnZSAmJiB0aGlzLmFyZ3MudG90YWxfcGFnZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVfcGFnaW5hdGlvbih0aGlzLmFyZ3MuY3VycmVudF9wYWdlLCB0aGlzLmFyZ3MudG90YWxfcGFnZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfcGFnaW5hdGlvbihjdXJyZW50LCB0b3RhbCkge1xuICAgICAgICBjb25zdCAkcGFnaW5hdGlvbiA9IHRoaXMuJGlkKCdwYWdpbmF0aW9uJyk7XG4gICAgICAgICRwYWdpbmF0aW9uLmVtcHR5KCk7XG5cbiAgICAgICAgLy8gUHJldmlvdXMgYnV0dG9uXG4gICAgICAgIGNvbnN0ICRwcmV2ID0gJCgnPGxpPicpLmFkZENsYXNzKCdwYWdlLWl0ZW0nICsgKGN1cnJlbnQgPT09IDEgPyAnIGRpc2FibGVkJyA6ICcnKSk7XG4gICAgICAgICRwcmV2LmFwcGVuZCgkKCc8YT4nKS5hZGRDbGFzcygncGFnZS1saW5rJykuYXR0cignaHJlZicsICcjJykudGV4dCgnUHJldmlvdXMnKSk7XG4gICAgICAgICRwYWdpbmF0aW9uLmFwcGVuZCgkcHJldik7XG5cbiAgICAgICAgLy8gUGFnZSBudW1iZXJzIChzaG93IDUgcGFnZXMgbWF4KVxuICAgICAgICBsZXQgc3RhcnQgPSBNYXRoLm1heCgxLCBjdXJyZW50IC0gMik7XG4gICAgICAgIGxldCBlbmQgPSBNYXRoLm1pbih0b3RhbCwgY3VycmVudCArIDIpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8PSBlbmQ7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFkZENsYXNzKCdwYWdlLWl0ZW0nICsgKGkgPT09IGN1cnJlbnQgPyAnIGFjdGl2ZScgOiAnJykpO1xuICAgICAgICAgICAgJGxpLmFwcGVuZCgkKCc8YT4nKS5hZGRDbGFzcygncGFnZS1saW5rJykuYXR0cignaHJlZicsICcjJykudGV4dChpKSk7XG4gICAgICAgICAgICAkcGFnaW5hdGlvbi5hcHBlbmQoJGxpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5leHQgYnV0dG9uXG4gICAgICAgIGNvbnN0ICRuZXh0ID0gJCgnPGxpPicpLmFkZENsYXNzKCdwYWdlLWl0ZW0nICsgKGN1cnJlbnQgPT09IHRvdGFsID8gJyBkaXNhYmxlZCcgOiAnJykpO1xuICAgICAgICAkbmV4dC5hcHBlbmQoJCgnPGE+JykuYWRkQ2xhc3MoJ3BhZ2UtbGluaycpLmF0dHIoJ2hyZWYnLCAnIycpLnRleHQoJ05leHQnKSk7XG4gICAgICAgICRwYWdpbmF0aW9uLmFwcGVuZCgkbmV4dCk7XG4gICAgfVxufVxuIiwiY2xhc3MgVGFibGUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgdmFyaWFudCBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy52YXJpYW50KSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoYHRhYmxlLSR7dGhpcy5hcmdzLnZhcmlhbnR9YCk7IC8vIHN0cmlwZWQsIGJvcmRlcmVkLCBib3JkZXJsZXNzXG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBseSBzaXplXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2l6ZSA9PT0gJ3NtJykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd0YWJsZS1zbScpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgVGFicyBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGNoaWxkcmVuIGluIG5hdi1pdGVtIHN0cnVjdHVyZVxuICAgICAgICB0aGlzLiQuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFkZENsYXNzKCduYXYtaXRlbScpO1xuICAgICAgICAgICAgICAgICRjaGlsZC5hZGRDbGFzcygnbmF2LWxpbmsnKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQud3JhcCgkbGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgZmlyc3QgdGFiIGFzIGFjdGl2ZSBpZiBub25lIGFjdGl2ZVxuICAgICAgICBpZiAodGhpcy4kLmZpbmQoJy5uYXYtbGluay5hY3RpdmUnKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuJC5maW5kKCcubmF2LWxpbmsnKS5maXJzdCgpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFRhZ19Hcm91cCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yIG5lZWRlZFxuICAgIH1cbn1cbiIsImNsYXNzIFRhZyBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBcHBseSBjb2xvciBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb2xvcikge1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKCdiZy1zZWNvbmRhcnknKS5hZGRDbGFzcyhgYmctJHt0aGlzLmFyZ3MuY29sb3J9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBUZXh0X0Rpc3BsYXkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBHZW5lcmljIHRleHQgZGlzcGxheSAtIGluaGVyaXRzIEJvb3RzdHJhcCB0eXBvZ3JhcGh5XG59XG4iLCIvKipcbiAqIFRleHRhcmVhIC0gQm9vdHN0cmFwIDUgTXVsdGktbGluZSBUZXh0IElucHV0IENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IE11bHRpLWxpbmUgdGV4dCBpbnB1dCBmb3IgbG9uZ2VyIGNvbnRlbnQgbGlrZSBkZXNjcmlwdGlvbnMsIGNvbW1lbnRzLCBub3Rlc1xuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY29udHJvbCBzdHlsaW5nIChzYW1lIGFzIElucHV0KVxuICovXG5jbGFzcyBUZXh0YXJlYSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBTZXQgcm93cyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJvd3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdyb3dzJywgdGhpcy5hcmdzLnJvd3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHBsYWNlaG9sZGVyIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdwbGFjZWhvbGRlcicsIHRoaXMuYXJncy5wbGFjZWhvbGRlcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdmFsdWUgaWYgcHJvdmlkZWQgKG92ZXJyaWRlcyBjb250ZW50KCkpXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuJC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBjdXN0b20gY2xhc3NlcyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3ModGhpcy5hcmdzLmNsYXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkaXNhYmxlZCBzdGF0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCByZXF1aXJlZCBhdHRyaWJ1dGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBUaHJlZV9Db2x1bW5fTGF5b3V0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFdyYXAgZWFjaCBkaXJlY3QgY2hpbGQgaW4gcmVzcG9uc2l2ZSBjb2x1bW4gY2xhc3Nlc1xuICAgICAgICB0aGlzLiQuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgJGVsZW1lbnQuYWRkQ2xhc3MoJ2NvbC0xMiBjb2wtbWQtNiBjb2wteGwtNCBtYi00Jyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFRpbWVfUGlja2VyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgICRpbnB1dC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm1pbikge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ21pbicsIHRoaXMuYXJncy5taW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5tYXgpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdtYXgnLCB0aGlzLmFyZ3MubWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc3RlcCkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ3N0ZXAnLCB0aGlzLmFyZ3Muc3RlcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVhZG9ubHkpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZWFkb25seScsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICB9XG5cbiAgICBzZXRfdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKHZhbHVlKTtcbiAgICB9XG5cbiAgICBmb2N1cygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykuZm9jdXMoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBUaW1lbGluZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgQm9vdHN0cmFwIGZsZXhib3ggLSBubyBKYXZhU2NyaXB0IG5lZWRlZFxufVxuIiwiY2xhc3MgVGltZXN0YW1wX0Rpc3BsYXkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBzdHlsaW5nIC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsImNsYXNzIFRvb2x0aXAgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHRvb2x0aXAgdGV4dCBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy50ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy10aXRsZScsIHRoaXMuYXJncy50ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBwbGFjZW1lbnRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5wbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdkYXRhLWJzLXBsYWNlbWVudCcsIHRoaXMuYXJncy5wbGFjZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBCb290c3RyYXAgdG9vbHRpcFxuICAgICAgICBuZXcgYm9vdHN0cmFwLlRvb2x0aXAodGhpcy4kWzBdKTtcbiAgICB9XG59XG4iLCJjbGFzcyBUb3BfTmF2IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFdyYXAgY2hpbGRyZW4gaW4gbmF2IHN0cnVjdHVyZVxuICAgICAgICBjb25zdCAkbmF2ID0gdGhpcy4kaWQoJ25hdl9pdGVtcycpO1xuICAgICAgICAkbmF2LmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKS5hZGRDbGFzcygnbmF2LWl0ZW0nKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ25hdi1saW5rJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLndyYXAoJGxpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgVHJlbmRfSW5kaWNhdG9yIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSB0aGlzLiQudGV4dCgpLnRyaW0oKTtcbiAgICAgICAgY29uc3QgaXNfcG9zaXRpdmUgPSB0ZXh0LnN0YXJ0c1dpdGgoJysnKTtcbiAgICAgICAgY29uc3QgaXNfbmVnYXRpdmUgPSB0ZXh0LnN0YXJ0c1dpdGgoJy0nKTtcblxuICAgICAgICBpZiAoaXNfcG9zaXRpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygndGV4dC1zdWNjZXNzIGZ3LWJvbGQnKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc19uZWdhdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd0ZXh0LWRhbmdlciBmdy1ib2xkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ3RleHQtbXV0ZWQgZnctYm9sZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdkLWJsb2NrIG10LTEnKTtcbiAgICB9XG59XG4iLCJjbGFzcyBUd29fQ29sdW1uX0xheW91dCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGVhY2ggZGlyZWN0IGNoaWxkIGluIHJlc3BvbnNpdmUgY29sdW1uIGNsYXNzZXNcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICRlbGVtZW50LmFkZENsYXNzKCdjb2wtMTIgY29sLWxnLTYgbWItNCcpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBVc2VyX0F2YXRhcl9Ecm9wZG93biBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBFbnN1cmUgcHJvcGVyIGRyb3Bkb3duIGl0ZW0gc3RydWN0dXJlXG4gICAgICAgIGNvbnN0ICRtZW51ID0gdGhpcy4kaWQoJ21lbnUnKTtcbiAgICAgICAgJG1lbnUuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpO1xuICAgICAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpID09PSAnSFInKSB7XG4gICAgICAgICAgICAgICAgICAgICRsaS5hcHBlbmQoJCgnPGhyPicpLmFkZENsYXNzKCdkcm9wZG93bi1kaXZpZGVyJykpO1xuICAgICAgICAgICAgICAgICAgICAkY2hpbGQucmVwbGFjZVdpdGgoJGxpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWl0ZW0nKTtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLndyYXAoJGxpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qKlxuICogTW9kYWxfQWJzdHJhY3QgLSBCYXNlIGNsYXNzIGZvciBtb2RhbCBvcmNoZXN0cmF0aW9uIGNsYXNzZXNcbiAqXG4gKiAqKlBoaWxvc29waHkqKjpcbiAqIE1vZGFsIGNsYXNzZXMgYXJlIG9yY2hlc3RyYXRpb24gbGF5ZXJzIHRoYXQgbWFuYWdlIHRoZSBsaWZlY3ljbGUgb2Ygc2hvd2luZ1xuICogYSBtb2RhbCwgY29sbGVjdGluZyB1c2VyIGlucHV0LCBhbmQgcmV0dXJuaW5nIHJlc3VsdHMuIFRoZXkgZG8gTk9UIGNvbnRhaW5cbiAqIGZvcm0gdmFsaWRhdGlvbiBvciBidXNpbmVzcyBsb2dpYyAtIHRoYXQgYmVsb25ncyBpbiBqcWh0bWwgY29tcG9uZW50cyBhbmRcbiAqIGNvbnRyb2xsZXIgZW5kcG9pbnRzLlxuICpcbiAqICoqUHVycG9zZSoqOlxuICogLSBQcm92aWRlcyBhIGNvbW1vbiBiYXNlIGNsYXNzIGZvciB0eXBlIGlkZW50aWZpY2F0aW9uXG4gKiAtIEVuZm9yY2VzIGZpbGUgbmFtaW5nIGNvbnZlbnRpb25zIChtb2RhbCBjbGFzc2VzIGVuZCB3aXRoIF9Nb2RhbClcbiAqIC0gRG9jdW1lbnRzIHRoZSBtb2RhbCBjbGFzcyBwYXR0ZXJuXG4gKiAtIEVuYWJsZXMgZnJhbWV3b3JrLWxldmVsIGZlYXR1cmVzIChmdXR1cmU6IGRpc2NvdmVyeSwgdmFsaWRhdGlvbilcbiAqXG4gKiAqKlJlc3BvbnNpYmlsaXRpZXMgb2YgTW9kYWwgQ2xhc3NlcyoqOlxuICogLSBJbnZva2UgTW9kYWwuZm9ybSgpIC8gTW9kYWwuc2hvdygpIC8gTW9kYWwuY29uZmlybSgpIHdpdGggYXBwcm9wcmlhdGUgY29uZmlndXJhdGlvblxuICogLSBIYW5kbGUgbW9kYWwgbGlmZWN5Y2xlIChzaG93LCBzdWJtaXQsIGNhbmNlbCwgZXJyb3JzKVxuICogLSBSZXR1cm4gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggZGF0YSBvciBmYWxzZVxuICogLSBFbmNhcHN1bGF0ZSBtb2RhbC1zcGVjaWZpYyBVSSBsb2dpY1xuICpcbiAqICoqQ29udHJhY3QqKjpcbiAqIEFsbCBtb2RhbCBjbGFzc2VzIGV4dGVuZGluZyBNb2RhbF9BYnN0cmFjdCBtdXN0IGltcGxlbWVudDpcbiAqIC0gYHN0YXRpYyBhc3luYyBzaG93KHBhcmFtcylgOiBQcmltYXJ5IGVudHJ5IHBvaW50LCByZXR1cm5zIFByb21pc2VcbiAqXG4gKiAqKlJldHVybiBWYWx1ZXMqKjpcbiAqIC0gU3VjY2VzczogUmVzb2x2ZSB3aXRoIGRhdGEgb2JqZWN0IChlLmcuLCBjcmVhdGVkIHVzZXIgcmVjb3JkKVxuICogLSBDYW5jZWwvQ2xvc2U6IFJlc29sdmUgd2l0aCBmYWxzZVxuICogLSBFcnJvcjogU2hvdyBlcnJvciBpbiBtb2RhbCwga2VlcCBvcGVuLCBkb24ndCByZXNvbHZlIHVudGlsIHVzZXIgYWN0c1xuICpcbiAqICoqSW50ZWdyYXRpb24qKjpcbiAqIE1vZGFsIGNsYXNzZXMgdXNlIE1vZGFsLmpzIHN0YXRpYyBBUEkgKE1vZGFsLmZvcm0oKSwgTW9kYWwuc2hvdygpLCBldGMuKVxuICogYXMgYnVpbGRpbmcgYmxvY2tzLiBGb3JtIHZhbGlkYXRpb24gaGFuZGxlZCBieSBSc3hfRm9ybSBhbmQgRm9ybV9VdGlscy5cbiAqIFBhZ2UgSlMgb3JjaGVzdHJhdGVzIG1vZGFsIGZsb3cgYnV0IGRvZXNuJ3QgY29udGFpbiBtb2RhbCBVSSBsb2dpYy5cbiAqXG4gKiAqKlBhdHRlcm4gRXhhbXBsZXMqKjpcbiAqXG4gKiBTaW1wbGUgZm9ybSBtb2RhbDpcbiAqIGBgYFxuICogY2xhc3MgQWRkX1VzZXJfTW9kYWwgZXh0ZW5kcyBNb2RhbF9BYnN0cmFjdCB7XG4gKiAgICAgc3RhdGljIGFzeW5jIHNob3coKSB7XG4gKiAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLmZvcm0oe1xuICogICAgICAgICAgICAgdGl0bGU6ICdBZGQgVXNlcicsXG4gKiAgICAgICAgICAgICBjb21wb25lbnQ6ICdBZGRfVXNlcl9Nb2RhbF9Gb3JtJyxcbiAqICAgICAgICAgICAgIG9uX3N1Ym1pdDogYXN5bmMgKGZvcm0pID0+IHtcbiAqICAgICAgICAgICAgICAgICB0cnkge1xuICogICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmb3JtLnZhbHMoKTtcbiAqICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgQ29udHJvbGxlci5hZGRfdXNlcih2YWx1ZXMpO1xuICogICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OyAvLyBDbG9zZSBtb2RhbCwgcmV0dXJuIGRhdGFcbiAqICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICogICAgICAgICAgICAgICAgICAgICBhd2FpdCBmb3JtLnJlbmRlcl9lcnJvcihlcnJvcik7XG4gKiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gS2VlcCBtb2RhbCBvcGVuXG4gKiAgICAgICAgICAgICAgICAgfVxuICogICAgICAgICAgICAgfSxcbiAqICAgICAgICAgfSk7XG4gKiAgICAgICAgIHJldHVybiByZXN1bHQgfHwgZmFsc2U7XG4gKiAgICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQ3VzdG9tIGNvbnRlbnQgbW9kYWw6XG4gKiBgYGBcbiAqIGNsYXNzIENvbmZpcm1fRGVsZXRlX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICogICAgIHN0YXRpYyBhc3luYyBzaG93KHtpdGVtX25hbWV9KSB7XG4gKiAgICAgICAgIHJldHVybiBhd2FpdCBNb2RhbC5jb25maXJtKFxuICogICAgICAgICAgICAgJ0NvbmZpcm0gRGVsZXRlJyxcbiAqICAgICAgICAgICAgIGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlICR7aXRlbV9uYW1lfT9gXG4gKiAgICAgICAgICk7XG4gKiAgICAgfVxuICogfVxuICogYGBgXG4gKlxuICogTW9kYWwgd2l0aCBiYWNrZW5kIGNhbGw6XG4gKiBgYGBcbiAqIGNsYXNzIFNlbmRfSW52aXRlX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICogICAgIHN0YXRpYyBhc3luYyBzaG93KHVzZXJfaWQpIHtcbiAqICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgQ29udHJvbGxlci5zZW5kX2ludml0ZSh7dXNlcl9pZH0pO1xuICogICAgICAgICBpZiAocmVzdWx0Lmludml0ZV91cmwpIHtcbiAqICAgICAgICAgICAgIGF3YWl0IE1vZGFsLmFsZXJ0KCdJbnZpdGUgU2VudCcsIHJlc3VsdC5pbnZpdGVfdXJsKTtcbiAqICAgICAgICAgfVxuICogICAgICAgICByZXR1cm4gcmVzdWx0O1xuICogICAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICoqVXNhZ2UgUGF0dGVybioqOlxuICogYGBgXG4gKiAvLyBQYWdlIEpTIG9yY2hlc3RyYXRlcyBmbG93LCBtb2RhbHMgaGFuZGxlIFVJXG4gKiBjb25zdCB1c2VyID0gYXdhaXQgQWRkX1VzZXJfTW9kYWwuc2hvdygpO1xuICogaWYgKHVzZXIpIHtcbiAqICAgICAkKCcuVXNlcnNfRGF0YUdyaWQnKS5jb21wb25lbnQoKS5yZWxvYWQoKTtcbiAqICAgICBhd2FpdCBTZW5kX1VzZXJfSW52aXRlX01vZGFsLnNob3codXNlci5pZCk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAqKkJlc3QgUHJhY3RpY2VzKio6XG4gKiAtIEtlZXAgbW9kYWwgY2xhc3NlcyBmb2N1c2VkOiBvbmUgbW9kYWwgPSBvbmUgY2xhc3NcbiAqIC0gUGFnZSBKUyBvcmNoZXN0cmF0ZXMgc2VxdWVuY2UsIG1vZGFsIGNsYXNzZXMgaGFuZGxlIGluZGl2aWR1YWwgbW9kYWxzXG4gKiAtIE1vZGFsIGNsYXNzZXMgZG9uJ3QgY2FsbCBlYWNoIG90aGVyIGRpcmVjdGx5XG4gKiAtIE1vZGFsIGNsYXNzZXMgZG9uJ3QgdXBkYXRlIFVJIChncmlkcywgbGlzdHMpIC0gcGFnZSBKUyBkb2VzIHRoYXRcbiAqIC0gVXNlIGRlc2NyaXB0aXZlIG5hbWVzIGVuZGluZyBpbiBfTW9kYWwgKEFkZF9Vc2VyX01vZGFsLCBTZW5kX0ludml0ZV9Nb2RhbClcbiAqIC0gUGxhY2UgZmVhdHVyZS1zcGVjaWZpYyBtb2RhbHMgaW4gZmVhdHVyZSBkaXJlY3RvcnlcbiAqIC0gUGxhY2UgcmV1c2FibGUgbW9kYWxzIGluIHRoZW1lL2NvbXBvbmVudHMvbW9kYWwvXG4gKlxuICogKipXaGVuIHRvIFVzZSBNb2RhbCBDbGFzc2VzKio6XG4gKiAtIE11bHRpLXN0ZXAgZm9ybXNcbiAqIC0gRm9ybXMgd2l0aCBjb21wbGV4IHZhbGlkYXRpb25cbiAqIC0gTW9kYWxzIGNhbGxlZCBmcm9tIG11bHRpcGxlIHBsYWNlc1xuICogLSBNb2RhbHMgd2l0aCBiYWNrZW5kIGludGVyYWN0aW9uc1xuICpcbiAqICoqV2hlbiBOT1QgdG8gVXNlIE1vZGFsIENsYXNzZXMqKjpcbiAqIC0gU2ltcGxlIGFsZXJ0czogYGF3YWl0IE1vZGFsLmFsZXJ0KCdTYXZlZCEnKWBcbiAqIC0gU2ltcGxlIGNvbmZpcm1hdGlvbnM6IGBpZiAoYXdhaXQgTW9kYWwuY29uZmlybSgnRGVsZXRlPycpKSB7Li4ufWBcbiAqIC0gT25lLW9mZiBwcm9tcHRzOiBgY29uc3QgbmFtZSA9IGF3YWl0IE1vZGFsLnByb21wdCgnRW50ZXIgbmFtZTonKWBcbiAqL1xuY2xhc3MgTW9kYWxfQWJzdHJhY3Qge1xuICAgIC8vIFRoaXMgY2xhc3MgcHJvdmlkZXMgc3RydWN0dXJlIGFuZCBkb2N1bWVudGF0aW9uIGZvciBtb2RhbCBwYXR0ZXJucy5cbiAgICAvLyBDb25jcmV0ZSBtb2RhbCBjbGFzc2VzIGV4dGVuZCB0aGlzIGFuZCBpbXBsZW1lbnQgc3RhdGljIHNob3coKSBtZXRob2QuXG59XG4iLCIvKipcbiAqIFJzeF9Nb2RhbCBDb21wb25lbnRcbiAqXG4gKiBJbnN0YW5jZSBvZiBhIG1vZGFsIGRpYWxvZy4gSGFuZGxlcyBsaWZlY3ljbGUsIHNpemluZywgYW5kIHVzZXIgaW50ZXJhY3Rpb24uXG4gKiBUeXBpY2FsbHkgY3JlYXRlZCBhbmQgbWFuYWdlZCBieSB0aGUgTW9kYWwgc3RhdGljIEFQSSBjbGFzcy5cbiAqL1xuY2xhc3MgUnN4X01vZGFsIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEudGl0bGUgPSAnJztcbiAgICAgICAgdGhpcy5kYXRhLmJvZHlfY29udGVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuZGF0YS5idXR0b25zID0gW107XG4gICAgICAgIHRoaXMuZGF0YS5jbG9zYWJsZSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5tYXhfd2lkdGggPSA4MDA7XG4gICAgICAgIHRoaXMuZGF0YS5jbG9zZV9vbl9zdWJtaXQgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEuaXNfdmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRhdGEucmVzdWx0X3Byb21pc2UgPSBudWxsO1xuICAgICAgICB0aGlzLmRhdGEucmVzb2x2ZV9mbiA9IG51bGw7XG5cbiAgICAgICAgLy8gU3RvcmUgcmVmZXJlbmNlIHRvIGJvb3RzdHJhcCBtb2RhbCBpbnN0YW5jZVxuICAgICAgICB0aGlzLl9ic19tb2RhbCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3Jlc2l6ZV9oYW5kbGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IHVwIGNsb3NlIGJ1dHRvbiBoYW5kbGVyXG4gICAgICAgIHRoaXMuJGlkKCdjbG9zZV9idG4nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5jbG9zYWJsZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuY2xvc2UoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgdXAgYmFja2Ryb3AgY2xpY2sgaGFuZGxlclxuICAgICAgICB0aGlzLiRpZCgnYmFja2Ryb3AnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5jbG9zYWJsZSAmJiBlLnRhcmdldCA9PT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHRoYXQuY2xvc2UoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgdXAgRVNDIGtleSBoYW5kbGVyXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdrZXlkb3duLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJyAmJiB0aGF0LmRhdGEuY2xvc2FibGUgJiYgdGhhdC5kYXRhLmlzX3Zpc2libGUpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIHJlc2l6ZSBoYW5kbGVyXG4gICAgICAgIHRoaXMuX3Jlc2l6ZV9oYW5kbGVyID0gZGVib3VuY2UoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5pc192aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5fYXBwbHlfc2l6aW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDEwMCk7XG5cbiAgICAgICAgJCh3aW5kb3cpLm9uKCdyZXNpemUucnN4X21vZGFsXycgKyB0aGlzLl9jaWQsIHRoaXMuX3Jlc2l6ZV9oYW5kbGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25maWd1cmUgYW5kIHNob3cgdGhlIG1vZGFsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBNb2RhbCBvcHRpb25zICh0aXRsZSwgYm9keSwgYnV0dG9ucywgZXRjLilcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW50ZXJuYWxfb3B0aW9ucyAtIEludGVybmFsIG9wdGlvbnMgKHNraXBfYmFja2Ryb3AsIGFuaW1hdGUpXG4gICAgICovXG4gICAgYXN5bmMgc2hvdyhvcHRpb25zLCBpbnRlcm5hbF9vcHRpb25zID0ge30pIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHNraXBfYmFja2Ryb3AgPSBpbnRlcm5hbF9vcHRpb25zLnNraXBfYmFja2Ryb3AgfHwgZmFsc2U7XG4gICAgICAgIGNvbnN0IHNob3VsZF9hbmltYXRlID0gaW50ZXJuYWxfb3B0aW9ucy5hbmltYXRlIHx8IGZhbHNlO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCdbUnN4X01vZGFsXSBzaG93KCkgY2FsbGVkIHdpdGggb3B0aW9uczonLCBvcHRpb25zKTtcblxuICAgICAgICAvLyBTdG9yZSBvcHRpb25zXG4gICAgICAgIHRoaXMuZGF0YS50aXRsZSA9IG9wdGlvbnMudGl0bGUgfHwgJyc7XG4gICAgICAgIHRoaXMuZGF0YS5jbG9zYWJsZSA9IG9wdGlvbnMuY2xvc2FibGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvc2FibGUgOiB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEubWF4X3dpZHRoID0gb3B0aW9ucy5tYXhfd2lkdGggfHwgODAwO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2Vfb25fc3VibWl0ID0gb3B0aW9ucy5jbG9zZV9vbl9zdWJtaXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvc2Vfb25fc3VibWl0IDogdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLmJ1dHRvbnMgPSBvcHRpb25zLmJ1dHRvbnMgfHwgW107XG4gICAgICAgIHRoaXMuZGF0YS5za2lwX2JhY2tkcm9wID0gc2tpcF9iYWNrZHJvcDtcbiAgICAgICAgdGhpcy5kYXRhLmljb24gPSBvcHRpb25zLmljb24gfHwgbnVsbDtcblxuICAgICAgICBjb25zb2xlLmxvZygnW1JzeF9Nb2RhbF0gU2V0dGluZyB0aXRsZSB0bzonLCB0aGlzLmRhdGEudGl0bGUpO1xuICAgICAgICBjb25zb2xlLmxvZygnW1JzeF9Nb2RhbF0gVGl0bGUgZWxlbWVudDonLCB0aGlzLiRpZCgndGl0bGUnKSk7XG5cbiAgICAgICAgLy8gU2V0IHRpdGxlXG4gICAgICAgIHRoaXMuJGlkKCd0aXRsZScpLnRleHQodGhpcy5kYXRhLnRpdGxlKTtcblxuICAgICAgICAvLyBTaG93L2hpZGUgY2xvc2UgYnV0dG9uIGJhc2VkIG9uIGNsb3NhYmxlXG4gICAgICAgIGlmICh0aGlzLmRhdGEuY2xvc2FibGUpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdjbG9zZV9idG4nKS5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykuaGlkZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGJvZHkgY29udGVudCAod2l0aCBvcHRpb25hbCBpY29uKVxuICAgICAgICB0aGlzLl9zZXRfYm9keV9jb250ZW50KG9wdGlvbnMuYm9keSwgdGhpcy5kYXRhLmljb24pO1xuXG4gICAgICAgIC8vIFNldCBidXR0b25zXG4gICAgICAgIHRoaXMuX3NldF9idXR0b25zKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHByb21pc2UgdGhhdCB3aWxsIHJlc29sdmUgd2hlbiBtb2RhbCBjbG9zZXNcbiAgICAgICAgY29uc3QgcmVzdWx0X3Byb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhhdC5kYXRhLnJlc29sdmVfZm4gPSByZXNvbHZlO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTaG93IG1vZGFsIGFuZCBiYWNrZHJvcFxuICAgICAgICB0aGlzLmRhdGEuaXNfdmlzaWJsZSA9IHRydWU7XG5cbiAgICAgICAgLy8gQXBwZW5kIHRvIGJvZHkgc28gaXQncyBvbiB0b3AgKGRvbid0IGFwcGVuZCBiYWNrZHJvcCBpZiB1c2luZyBzaGFyZWQpXG4gICAgICAgIGlmICghc2tpcF9iYWNrZHJvcCkge1xuICAgICAgICAgICAgJCgnYm9keScpLmFwcGVuZCh0aGlzLiRpZCgnYmFja2Ryb3AnKSk7XG4gICAgICAgIH1cbiAgICAgICAgJCgnYm9keScpLmFwcGVuZCh0aGlzLiQpO1xuXG4gICAgICAgIC8vIEFwcGx5IHNpemluZyBiZWZvcmUgc2hvd2luZ1xuICAgICAgICB0aGlzLl9hcHBseV9zaXppbmcoKTtcblxuICAgICAgICAvLyBGYWRlIGluIG1vZGFsIChhbmQgYmFja2Ryb3AgaWYgbm90IHVzaW5nIHNoYXJlZClcbiAgICAgICAgYXdhaXQgdGhpcy5fZmFkZV9pbihzaG91bGRfYW5pbWF0ZSk7XG5cbiAgICAgICAgLy8gQXV0by1mb2N1cyBmaXJzdCBpbnB1dCBlbGVtZW50XG4gICAgICAgIHRoaXMuX2ZvY3VzX2ZpcnN0X2lucHV0KCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdF9wcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBib2R5IGNvbnRlbnQgd2l0aCBvcHRpb25hbCBpY29uXG4gICAgICovXG4gICAgX3NldF9ib2R5X2NvbnRlbnQoYm9keSwgaWNvbikge1xuICAgICAgICBjb25zdCAkYm9keSA9IHRoaXMuJGlkKCdib2R5Jyk7XG4gICAgICAgICRib2R5LmVtcHR5KCk7XG5cbiAgICAgICAgLy8gSWYgaWNvbiBwcm92aWRlZCwgYWRkIGl0XG4gICAgICAgIGlmIChpY29uKSB7XG4gICAgICAgICAgICBjb25zdCAkaWNvbiA9ICQoYDxpIGNsYXNzPVwiYmkgYmktJHtpY29ufSBtb2RhbC1pY29uXCI+PC9pPmApO1xuICAgICAgICAgICAgJGJvZHkuYXBwZW5kKCRpY29uKTtcbiAgICAgICAgICAgICRib2R5LmFkZENsYXNzKCdoYXMtaWNvbicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGJvZHkucmVtb3ZlQ2xhc3MoJ2hhcy1pY29uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgb3IgY3JlYXRlIGJvZHkgY29udGVudCB3cmFwcGVyXG4gICAgICAgIGxldCAkY29udGVudCA9IHRoaXMuJGlkKCdib2R5X2NvbnRlbnQnKTtcbiAgICAgICAgaWYgKCEkY29udGVudC5leGlzdHMoKSkge1xuICAgICAgICAgICAgJGNvbnRlbnQgPSAkKCc8ZGl2IGNsYXNzPVwibW9kYWwtYm9keS1jb250ZW50XCI+PC9kaXY+Jyk7XG4gICAgICAgICAgICAkYm9keS5hcHBlbmQoJGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gVGV4dCBjb250ZW50IC0gZXNjYXBlIGFuZCBjb252ZXJ0IG5ld2xpbmVzXG4gICAgICAgICAgICBjb25zdCBlc2NhcGVkID0gJCgnPGRpdj4nKS50ZXh0KGJvZHkpLmh0bWwoKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcbiAgICAgICAgICAgICRjb250ZW50Lmh0bWwoZXNjYXBlZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoYm9keSBpbnN0YW5jZW9mIGpRdWVyeSkge1xuICAgICAgICAgICAgLy8galF1ZXJ5IGVsZW1lbnRcbiAgICAgICAgICAgICRjb250ZW50LmFwcGVuZChib2R5KTtcbiAgICAgICAgfSBlbHNlIGlmIChib2R5ICYmIHR5cGVvZiBib2R5ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gQXNzdW1lIGl0J3MgYSBqcWh0bWwgY29tcG9uZW50IGluc3RhbmNlXG4gICAgICAgICAgICAkY29udGVudC5hcHBlbmQoYm9keS4kKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBidXR0b25zIGluIGZvb3RlclxuICAgICAqL1xuICAgIF9zZXRfYnV0dG9ucygpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIGNvbnN0ICRmb290ZXIgPSB0aGlzLiRpZCgnZm9vdGVyJyk7XG4gICAgICAgICRmb290ZXIuZW1wdHkoKTtcblxuICAgICAgICBpZiAodGhpcy5kYXRhLmJ1dHRvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkZm9vdGVyLmhpZGUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgICRmb290ZXIuc2hvdygpO1xuXG4gICAgICAgIGZvciAobGV0IGJ1dHRvbl9kZWYgb2YgdGhpcy5kYXRhLmJ1dHRvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0ICRidXR0b24gPSAkKCc8YnV0dG9uPicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3R5cGUnLCAnYnV0dG9uJylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2J0bicpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKGJ1dHRvbl9kZWYuY2xhc3MgfHwgJ2J0bi1zZWNvbmRhcnknKVxuICAgICAgICAgICAgICAgIC50ZXh0KGJ1dHRvbl9kZWYubGFiZWwgfHwgJ0J1dHRvbicpO1xuXG4gICAgICAgICAgICAkYnV0dG9uLm9uKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gYnV0dG9uX2RlZi52YWx1ZTtcbiAgICAgICAgICAgICAgICBsZXQgaGFkX2NhbGxiYWNrID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBidXR0b24gaGFzIGEgY2FsbGJhY2ssIGNhbGwgaXQgYW5kIHVzZSByZXR1cm4gdmFsdWUgYXMgcmVzdWx0XG4gICAgICAgICAgICAgICAgaWYgKGJ1dHRvbl9kZWYuY2FsbGJhY2sgJiYgdHlwZW9mIGJ1dHRvbl9kZWYuY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFkX2NhbGxiYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgYnV0dG9uX2RlZi5jYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybmVkIGZhbHNlLCBrZWVwIG1vZGFsIG9wZW4gKGJ1dCBub3QgaWYganVzdCBidXR0b24gdmFsdWUgaXMgZmFsc2UpXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UgJiYgaGFkX2NhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBDbG9zZSBtb2RhbCB3aXRoIHJlc3VsdFxuICAgICAgICAgICAgICAgIHRoYXQuY2xvc2UocmVzdWx0KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkZm9vdGVyLmFwcGVuZCgkYnV0dG9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSBhbmQgYXBwbHkgcmVzcG9uc2l2ZSBzaXppbmdcbiAgICAgKi9cbiAgICBfYXBwbHlfc2l6aW5nKCkge1xuICAgICAgICBjb25zdCB2aWV3cG9ydF93aWR0aCA9ICQod2luZG93KS53aWR0aCgpO1xuICAgICAgICBjb25zdCB2aWV3cG9ydF9oZWlnaHQgPSAkKHdpbmRvdykuaGVpZ2h0KCk7XG4gICAgICAgIGNvbnN0IGlzX21vYmlsZSA9IHZpZXdwb3J0X3dpZHRoIDwgNzY4O1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSBtYXggd2lkdGggYmFzZWQgb24gdmlld3BvcnRcbiAgICAgICAgbGV0IG1heF93aWR0aCA9IHRoaXMuZGF0YS5tYXhfd2lkdGg7XG4gICAgICAgIGNvbnN0IHZpZXdwb3J0X2xpbWl0ID0gaXNfbW9iaWxlID8gdmlld3BvcnRfd2lkdGggKiAwLjkgOiB2aWV3cG9ydF93aWR0aCAqIDAuODtcblxuICAgICAgICBtYXhfd2lkdGggPSBNYXRoLm1pbihtYXhfd2lkdGgsIHZpZXdwb3J0X2xpbWl0KTtcblxuICAgICAgICAvLyBUcnkgdG8gY29uc3RyYWluIHRvIDYwJSB3aWR0aCBmb3IgYmV0dGVyIHByb3BvcnRpb25zIG9uIGRlc2t0b3BcbiAgICAgICAgaWYgKCFpc19tb2JpbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZWZlcnJlZF93aWR0aCA9IHZpZXdwb3J0X3dpZHRoICogMC42O1xuICAgICAgICAgICAgaWYgKHByZWZlcnJlZF93aWR0aCA8IG1heF93aWR0aCkge1xuICAgICAgICAgICAgICAgIG1heF93aWR0aCA9IHByZWZlcnJlZF93aWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFwcGx5IHdpZHRoXG4gICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC13aWR0aCcsIG1heF93aWR0aCArICdweCcpO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGNvbnRlbnQgZXhjZWVkcyA4MCUgaGVpZ2h0XG4gICAgICAgIGNvbnN0IGNvbnRlbnRfaGVpZ2h0ID0gdGhpcy4kaWQoJ2RpYWxvZycpLm91dGVySGVpZ2h0KCk7XG4gICAgICAgIGNvbnN0IG1heF9oZWlnaHQgPSB2aWV3cG9ydF9oZWlnaHQgKiAwLjg7XG5cbiAgICAgICAgaWYgKGNvbnRlbnRfaGVpZ2h0ID4gbWF4X2hlaWdodCkge1xuICAgICAgICAgICAgLy8gRW5hYmxlIHNjcm9sbGluZ1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWF4LWhlaWdodCcsIG1heF9oZWlnaHQgKyAncHgnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdib2R5JykuY3NzKHtcbiAgICAgICAgICAgICAgICAnb3ZlcmZsb3cteSc6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICAnbWF4LWhlaWdodCc6IG1heF9oZWlnaHQgLSAxNTAgKyAncHgnLCAvLyBBY2NvdW50IGZvciBoZWFkZXIvZm9vdGVyXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlc2V0IHNjcm9sbGluZ1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWF4LWhlaWdodCcsICcnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdib2R5JykuY3NzKHtcbiAgICAgICAgICAgICAgICAnb3ZlcmZsb3cteSc6ICcnLFxuICAgICAgICAgICAgICAgICdtYXgtaGVpZ2h0JzogJycsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1vYmlsZSBlZGdlIHNwYWNpbmdcbiAgICAgICAgaWYgKGlzX21vYmlsZSkge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWFyZ2luJywgJzUlJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCdtYXJnaW4nLCAnMCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbmltYXRpb24gKGluc3RhbnQgb3Igd2l0aCBmbHktaW4pXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhbmltYXRlIC0gV2hldGhlciB0byBhbmltYXRlIHRoZSBtb2RhbCBlbnRyYW5jZVxuICAgICAqL1xuICAgIGFzeW5jIF9mYWRlX2luKGFuaW1hdGUgPSBmYWxzZSkge1xuICAgICAgICBpZiAoYW5pbWF0ZSkge1xuICAgICAgICAgICAgLy8gSW5pdGlhbCBzdGF0ZTogbW9kYWwgcG9zaXRpb25lZCBhYm92ZSBmaW5hbCBwb3NpdGlvblxuICAgICAgICAgICAgdGhpcy4kLmNzcygnZGlzcGxheScsICdmbGV4JykuY3NzKCdvcGFjaXR5JywgJzAnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3RyYW5zZm9ybSc6ICd0cmFuc2xhdGUoMCwgLTUwcHgpJyxcbiAgICAgICAgICAgICAgICAnb3BhY2l0eSc6ICcwJ1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYmFja2Ryb3AnKS5jc3MoJ2Rpc3BsYXknLCAnYmxvY2snKS5hZGRDbGFzcygnc2hvdycpO1xuXG4gICAgICAgICAgICAvLyBGb3JjZSByZWZsb3dcbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpWzBdLm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgLy8gVHJpZ2dlciBhbmltYXRpb25cbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpLmFkZENsYXNzKCdzaG93JykuY3NzKHtcbiAgICAgICAgICAgICAgICAndHJhbnNmb3JtJzogJ3RyYW5zbGF0ZSgwLCAwKScsXG4gICAgICAgICAgICAgICAgJ29wYWNpdHknOiAnMSdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy4kLmNzcygnb3BhY2l0eScsICcxJyk7XG5cbiAgICAgICAgICAgIC8vIFdhaXQgZm9yIGFuaW1hdGlvbiB0byBjb21wbGV0ZVxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDE1MCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRGlzYWJsZSB0cmFuc2l0aW9ucyB0ZW1wb3JhcmlseSBmb3IgaW5zdGFudCBkaXNwbGF5XG4gICAgICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCd0cmFuc2l0aW9uJywgJ25vbmUnKTtcblxuICAgICAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgYmFja2Ryb3AgaW5zdGFudGx5XG4gICAgICAgICAgICB0aGlzLiQuY3NzKCdkaXNwbGF5JywgJ2ZsZXgnKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ21vZGFsJykuYWRkQ2xhc3MoJ3Nob3cnKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcblxuICAgICAgICAgICAgLy8gRm9yY2UgcmVmbG93IHRvIGFwcGx5IHRoZSBuby10cmFuc2l0aW9uIHN0YXRlXG4gICAgICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJylbMF0ub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICAvLyBSZS1lbmFibGUgdHJhbnNpdGlvbnMgZm9yIGZ1dHVyZSBhbmltYXRpb25zXG4gICAgICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCd0cmFuc2l0aW9uJywgJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvY3VzIHRoZSBmaXJzdCBpbnB1dCBlbGVtZW50IGluIHRoZSBtb2RhbFxuICAgICAqL1xuICAgIF9mb2N1c19maXJzdF9pbnB1dCgpIHtcbiAgICAgICAgLy8gRmluZCBmaXJzdCBpbnB1dC90ZXh0YXJlYS9zZWxlY3QgaW4gbW9kYWwgYm9keVxuICAgICAgICBjb25zdCAkZmlyc3RfaW5wdXQgPSB0aGlzLiRpZCgnYm9keScpLmZpbmQoJ2lucHV0Om5vdChbdHlwZT1cImhpZGRlblwiXSksIHRleHRhcmVhLCBzZWxlY3QnKS5maXJzdCgpO1xuICAgICAgICBpZiAoJGZpcnN0X2lucHV0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICRmaXJzdF9pbnB1dC5mb2N1cygpO1xuICAgICAgICAgICAgICAgIC8vIFNlbGVjdCB0ZXh0IGlmIGl0J3MgYW4gaW5wdXQgd2l0aCBleGlzdGluZyB2YWx1ZVxuICAgICAgICAgICAgICAgIGlmICgkZmlyc3RfaW5wdXQuaXMoJ2lucHV0W3R5cGU9XCJ0ZXh0XCJdLCBpbnB1dFt0eXBlPVwiZW1haWxcIl0nKSAmJiAkZmlyc3RfaW5wdXQudmFsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgJGZpcnN0X2lucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIG1vZGFsIGluc3RhbnRseVxuICAgICAqL1xuICAgIGFzeW5jIGNsb3NlKHJlc3VsdCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBNYXJrIGFzIG5vdCB2aXNpYmxlXG4gICAgICAgIHRoaXMuZGF0YS5pc192aXNpYmxlID0gZmFsc2U7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICAkKGRvY3VtZW50KS5vZmYoJ2tleWRvd24ucnN4X21vZGFsXycgKyB0aGlzLl9jaWQpO1xuICAgICAgICAkKHdpbmRvdykub2ZmKCdyZXNpemUucnN4X21vZGFsXycgKyB0aGlzLl9jaWQpO1xuXG4gICAgICAgIC8vIEhpZGUgaW5zdGFudGx5IChubyBmYWRlIG91dClcbiAgICAgICAgdGhpcy4kLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykuaGlkZSgpO1xuXG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTVxuICAgICAgICB0aGlzLiQucmVtb3ZlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLnJlbW92ZSgpO1xuXG4gICAgICAgIC8vIFJlc29sdmUgcHJvbWlzZVxuICAgICAgICBpZiAodGhpcy5kYXRhLnJlc29sdmVfZm4pIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5yZXNvbHZlX2ZuKHJlc3VsdCk7XG4gICAgICAgICAgICB0aGlzLmRhdGEucmVzb2x2ZV9mbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSB2YWxpZGF0aW9uIGVycm9ycyB0byBmb3JtIGZpZWxkcyBpbiBtb2RhbCBib2R5XG4gICAgICovXG4gICAgYXBwbHlfZXJyb3JzKGVycm9ycykge1xuICAgICAgICAvLyBVc2UgRm9ybV9VdGlscyB0byBhcHBseSBlcnJvcnMgdG8gZWxlbWVudHMgd2l0aGluIG1vZGFsIGJvZHlcbiAgICAgICAgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyh0aGlzLiRpZCgnYm9keScpLCBlcnJvcnMpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogTW9kYWwgU3RhdGljIEFQSVxuICpcbiAqIFByaW1hcnkgaW50ZXJmYWNlIGZvciBkaXNwbGF5aW5nIG1vZGFscyB0aHJvdWdob3V0IHRoZSBhcHBsaWNhdGlvbi5cbiAqIFByb3ZpZGVzIHNpbXBsZSBtZXRob2RzIGZvciBjb21tb24gZGlhbG9ncyBhbmQgZmxleGlibGUgb3B0aW9ucyBmb3IgY3VzdG9tIG1vZGFscy5cbiAqXG4gKiBVc2FnZTpcbiAqICAgYXdhaXQgTW9kYWwuYWxlcnQoXCJGaWxlIHNhdmVkXCIpXG4gKiAgIGlmIChhd2FpdCBNb2RhbC5jb25maXJtKFwiRGVsZXRlP1wiKSkgeyAuLi4gfVxuICogICBsZXQgbmFtZSA9IGF3YWl0IE1vZGFsLnByb21wdChcIkVudGVyIG5hbWU6XCIpXG4gKiAgIGxldCByZXN1bHQgPSBhd2FpdCBNb2RhbC5zaG93KHsgdGl0bGUsIGJvZHksIGJ1dHRvbnMgfSlcbiAqL1xuY2xhc3MgTW9kYWwge1xuICAgIC8vIEludGVybmFsIHN0YXRlXG4gICAgc3RhdGljIF9xdWV1ZSA9IFtdO1xuICAgIHN0YXRpYyBfY3VycmVudCA9IG51bGw7XG4gICAgc3RhdGljIF9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHN0YXRpYyBfYmFja2Ryb3AgPSBudWxsO1xuICAgIHN0YXRpYyBfb3JpZ2luYWxfYm9keV9vdmVyZmxvdyA9IG51bGw7XG4gICAgc3RhdGljIF9vcmlnaW5hbF9ib2R5X3BhZGRpbmcgPSBudWxsO1xuICAgIHN0YXRpYyBfdW5sb2NrX3RpbWVvdXQgPSBudWxsO1xuICAgIHN0YXRpYyBfbGFzdF9jbG9zZV90aW1lc3RhbXAgPSAwO1xuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSBnbG9iYWwgaGFuZGxlcnMgKGNhbGxlZCBhdXRvbWF0aWNhbGx5IG9uIGZpcnN0IG1vZGFsKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9pbml0KCkge1xuICAgICAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8vIENyZWF0ZSBzaGFyZWQgYmFja2Ryb3AgZWxlbWVudFxuICAgICAgICB0aGlzLl9iYWNrZHJvcCA9ICQoJzxkaXYgY2xhc3M9XCJtb2RhbC1iYWNrZHJvcCBmYWRlXCI+PC9kaXY+Jyk7XG4gICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy5fYmFja2Ryb3ApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSBzY3JvbGxiYXIgd2lkdGhcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIF9nZXRfc2Nyb2xsYmFyX3dpZHRoKCkge1xuICAgICAgICAvLyBDcmVhdGUgdGVtcG9yYXJ5IGVsZW1lbnQgdG8gbWVhc3VyZSBzY3JvbGxiYXIgd2lkdGhcbiAgICAgICAgY29uc3QgJG91dGVyID0gJCgnPGRpdj4nKS5jc3Moe1xuICAgICAgICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsXG4gICAgICAgICAgICBvdmVyZmxvdzogJ3Njcm9sbCcsXG4gICAgICAgICAgICB3aWR0aDogJzEwMHB4JyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgdG9wOiAnLTk5OTlweCcsXG4gICAgICAgIH0pO1xuICAgICAgICAkKCdib2R5JykuYXBwZW5kKCRvdXRlcik7XG5cbiAgICAgICAgY29uc3Qgd2lkdGhfd2l0aF9zY3JvbGxiYXIgPSAkb3V0ZXJbMF0ub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgY29uc3QgJGlubmVyID0gJCgnPGRpdj4nKS5jc3MoJ3dpZHRoJywgJzEwMCUnKTtcbiAgICAgICAgJG91dGVyLmFwcGVuZCgkaW5uZXIpO1xuXG4gICAgICAgIGNvbnN0IHdpZHRoX3dpdGhvdXRfc2Nyb2xsYmFyID0gJGlubmVyWzBdLm9mZnNldFdpZHRoO1xuXG4gICAgICAgICRvdXRlci5yZW1vdmUoKTtcblxuICAgICAgICByZXR1cm4gd2lkdGhfd2l0aF9zY3JvbGxiYXIgLSB3aWR0aF93aXRob3V0X3Njcm9sbGJhcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2NrIGJvZHkgc2Nyb2xsIGFuZCBjb21wZW5zYXRlIGZvciBzY3JvbGxiYXIgd2lkdGhcbiAgICAgKiBPbmx5IGxvY2tzIGlmIHdlIGhhdmVuJ3QgYWxyZWFkeSBzYXZlZCB0aGUgb3JpZ2luYWwgc3RhdGUgKGZpcnN0IG1vZGFsIGluIGNoYWluKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9sb2NrX2JvZHlfc2Nyb2xsKCkge1xuICAgICAgICAvLyBDYW5jZWwgYW55IHBlbmRpbmcgdW5sb2NrIHRpbWVvdXRcbiAgICAgICAgaWYgKHRoaXMuX3VubG9ja190aW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdW5sb2NrX3RpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5fdW5sb2NrX3RpbWVvdXQgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT25seSBsb2NrIHNjcm9sbCBpZiB3ZSBoYXZlbid0IGFscmVhZHkgc2F2ZWQgc3RhdGUgKGZpcnN0IG1vZGFsKVxuICAgICAgICAvLyBUaGlzIGlzIHRoZSB0cnVlIGluZGljYXRvciAtIG5vdCBiYWNrZHJvcCB2aXNpYmlsaXR5IHdoaWNoIGNhbiBiZSB0cmFuc2l0aW9uYWxcbiAgICAgICAgaWYgKHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0ICRib2R5ID0gJCgnYm9keScpO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSBvcmlnaW5hbCB2YWx1ZXNcbiAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgPSAkYm9keS5jc3MoJ292ZXJmbG93Jyk7XG4gICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcgPSAkYm9keS5jc3MoJ3BhZGRpbmctcmlnaHQnKTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYm9keSBjdXJyZW50bHkgaGFzIHZlcnRpY2FsIHNjcm9sbFxuICAgICAgICAgICAgY29uc3QgaGFzX3Njcm9sbGJhciA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0ID4gd2luZG93LmlubmVySGVpZ2h0O1xuXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSdzIGEgc2Nyb2xsYmFyLCBhZGQgcGFkZGluZyB0byBjb21wZW5zYXRlIGZvciBpdHMgcmVtb3ZhbFxuICAgICAgICAgICAgaWYgKGhhc19zY3JvbGxiYXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JvbGxiYXJfd2lkdGggPSB0aGlzLl9nZXRfc2Nyb2xsYmFyX3dpZHRoKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudF9wYWRkaW5nID0gaW50KHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZykgfHwgMDtcbiAgICAgICAgICAgICAgICAkYm9keS5jc3MoJ3BhZGRpbmctcmlnaHQnLCBjdXJyZW50X3BhZGRpbmcgKyBzY3JvbGxiYXJfd2lkdGggKyAncHgnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTG9jayBzY3JvbGxcbiAgICAgICAgICAgICRib2R5LmNzcygnb3ZlcmZsb3cnLCAnaGlkZGVuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVbmxvY2sgYm9keSBzY3JvbGwgYW5kIHJlc3RvcmUgb3JpZ2luYWwgc3RhdGVcbiAgICAgKiBVc2VzIGRlbGF5ZWQgY2hlY2sgdG8gZW5zdXJlIG5vIG90aGVyIG1vZGFscyBhcmUgb3BlbmluZ1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF91bmxvY2tfYm9keV9zY3JvbGwoKSB7XG4gICAgICAgIC8vIENsZWFyIGFueSBleGlzdGluZyB0aW1lb3V0XG4gICAgICAgIGlmICh0aGlzLl91bmxvY2tfdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3VubG9ja190aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1pbmltYWwgZGVsYXkgYmVmb3JlIHVubG9ja2luZ1xuICAgICAgICB0aGlzLl91bmxvY2tfdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgLy8gRG91YmxlLWNoZWNrIG5vIG1vZGFsIGlzIGN1cnJlbnRseSBvcGVuIGFuZCBxdWV1ZSBpcyBlbXB0eVxuICAgICAgICAgICAgaWYgKCF0aGlzLl9jdXJyZW50ICYmIHRoaXMuX3F1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRib2R5ID0gJCgnYm9keScpO1xuXG4gICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBvcmlnaW5hbCB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3JpZ2luYWxfYm9keV9vdmVyZmxvdyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAkYm9keS5jc3MoJ292ZXJmbG93JywgdGhpcy5fb3JpZ2luYWxfYm9keV9vdmVyZmxvdyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgdGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX3VubG9ja190aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgfSwgNTApOyAvLyBNaW5pbWFsIHNhZmV0eSBidWZmZXJcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IHRoZSBzaGFyZWQgYmFja2Ryb3AgKGluc3RhbnQgLSBubyBhbmltYXRpb24pXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX3Nob3dfYmFja2Ryb3AoKSB7XG4gICAgICAgIGlmICghdGhpcy5fYmFja2Ryb3AuaGFzQ2xhc3MoJ3Nob3cnKSkge1xuICAgICAgICAgICAgLy8gTG9jayBib2R5IHNjcm9sbCBiZWZvcmUgc2hvd2luZyBiYWNrZHJvcFxuICAgICAgICAgICAgdGhpcy5fbG9ja19ib2R5X3Njcm9sbCgpO1xuXG4gICAgICAgICAgICB0aGlzLl9iYWNrZHJvcC5jc3MoJ2Rpc3BsYXknLCAnYmxvY2snKS5hZGRDbGFzcygnc2hvdycpO1xuICAgICAgICAgICAgLy8gTm8gZGVsYXkgLSByZXR1cm4gaW1tZWRpYXRlbHlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhpZGUgdGhlIHNoYXJlZCBiYWNrZHJvcCAoaW5zdGFudCAtIG5vIGFuaW1hdGlvbilcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfaGlkZV9iYWNrZHJvcCgpIHtcbiAgICAgICAgdGhpcy5fYmFja2Ryb3AucmVtb3ZlQ2xhc3MoJ3Nob3cnKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuXG4gICAgICAgIC8vIFVubG9jayBib2R5IHNjcm9sbCBhZnRlciBiYWNrZHJvcCBpcyBoaWRkZW5cbiAgICAgICAgdGhpcy5fdW5sb2NrX2JvZHlfc2Nyb2xsKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IFJzeF9Nb2RhbCBpbnN0YW5jZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9jcmVhdGVfbW9kYWwoKSB7XG4gICAgICAgIC8vIENyZWF0ZSBtb2RhbCBjb21wb25lbnQgdXNpbmcgalF1ZXJ5IHBsdWdpblxuICAgICAgICBjb25zdCAkbW9kYWxfZWxlbWVudCA9ICQoJzxkaXY+Jyk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGNvbXBvbmVudCBpbnN0YW5jZSBkaXJlY3RseSAocmV0dXJucyB0aGUgY29tcG9uZW50KVxuICAgICAgICBjb25zdCBtb2RhbF9pbnN0YW5jZSA9ICRtb2RhbF9lbGVtZW50LmNvbXBvbmVudCgnUnN4X01vZGFsJywge30pO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIGNvbXBvbmVudCB0byBiZSBmdWxseSByZWFkeSAoRE9NIGVsZW1lbnRzIHF1ZXJ5YWJsZSlcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIG1vZGFsX2luc3RhbmNlLm9uKCdyZWFkeScsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnW01vZGFsXSBDb21wb25lbnQgcmVhZHksIGVsZW1lbnRzOicsIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IG1vZGFsX2luc3RhbmNlLiRpZCgndGl0bGUnKS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIGJvZHk6IG1vZGFsX2luc3RhbmNlLiRpZCgnYm9keScpLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgZm9vdGVyOiBtb2RhbF9pbnN0YW5jZS4kaWQoJ2Zvb3RlcicpLmxlbmd0aCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG1vZGFsX2luc3RhbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBtb2RhbCBhbmQgbWFuYWdlIHF1ZXVlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX3Nob3dfbW9kYWwob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3F1ZXVlLnB1c2goeyBvcHRpb25zLCByZXNvbHZlIH0pO1xuXG4gICAgICAgICAgICAvLyBQcm9jZXNzIHF1ZXVlIGlmIG5vIG1vZGFsIGN1cnJlbnRseSBzaG93aW5nXG4gICAgICAgICAgICBpZiAoIXRoaXMuX2N1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzX3F1ZXVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2Nlc3MgdGhlIG1vZGFsIHF1ZXVlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX3Byb2Nlc3NfcXVldWUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xuICAgICAgICAgICAgLy8gSGlkZSBiYWNrZHJvcCB3aGVuIHF1ZXVlIGlzIGVtcHR5XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9oaWRlX2JhY2tkcm9wKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IG9wdGlvbnMsIHJlc29sdmUgfSA9IHRoaXMuX3F1ZXVlLnNoaWZ0KCk7XG5cbiAgICAgICAgLy8gRW5zdXJlIGluaXRpYWxpemVkXG4gICAgICAgIHRoaXMuX2luaXQoKTtcblxuICAgICAgICAvLyBTaG93IGJhY2tkcm9wIGlmIG5vdCBhbHJlYWR5IHZpc2libGUgKGluc3RhbnQgLSBubyBkZWxheSBiZXR3ZWVuIG1vZGFscylcbiAgICAgICAgY29uc3QgYmFja2Ryb3BfdmlzaWJsZSA9IHRoaXMuX2JhY2tkcm9wLmhhc0NsYXNzKCdzaG93Jyk7XG4gICAgICAgIGlmICghYmFja2Ryb3BfdmlzaWJsZSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19iYWNrZHJvcCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIGRlbGF5IGJldHdlZW4gc2VxdWVudGlhbCBtb2RhbHMgLSBpbW1lZGlhdGUgdHJhbnNpdGlvblxuXG4gICAgICAgIC8vIENyZWF0ZSBtb2RhbCBpbnN0YW5jZVxuICAgICAgICBjb25zdCBtb2RhbF9pbnN0YW5jZSA9IGF3YWl0IHRoaXMuX2NyZWF0ZV9tb2RhbCgpO1xuICAgICAgICB0aGlzLl9jdXJyZW50ID0gbW9kYWxfaW5zdGFuY2U7XG5cbiAgICAgICAgLy8gRGV0ZXJtaW5lIGlmIHdlIHNob3VsZCBhbmltYXRlIGJhc2VkIG9uOlxuICAgICAgICAvLyAxLiBEZXNrdG9wIHZpZXdwb3J0ICg+PSAxMDAwcHgpXG4gICAgICAgIC8vIDIuIE1vcmUgdGhhbiAxIHNlY29uZCBzaW5jZSBsYXN0IG1vZGFsIGNsb3NlZFxuICAgICAgICBjb25zdCB2aWV3cG9ydF93aWR0aCA9ICQod2luZG93KS53aWR0aCgpO1xuICAgICAgICBjb25zdCBpc19kZXNrdG9wID0gdmlld3BvcnRfd2lkdGggPj0gMTAwMDtcbiAgICAgICAgY29uc3QgdGltZV9zaW5jZV9sYXN0X2Nsb3NlID0gRGF0ZS5ub3coKSAtIHRoaXMuX2xhc3RfY2xvc2VfdGltZXN0YW1wO1xuICAgICAgICBjb25zdCBzaG91bGRfYW5pbWF0ZSA9IGlzX2Rlc2t0b3AgJiYgdGltZV9zaW5jZV9sYXN0X2Nsb3NlID4gMTAwMDtcblxuICAgICAgICAvLyBTaG93IG1vZGFsIGFuZCB3YWl0IGZvciByZXN1bHQgKG1vZGFsIHdvbid0IGNyZWF0ZSBpdHMgb3duIGJhY2tkcm9wKVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBtb2RhbF9pbnN0YW5jZS5zaG93KG9wdGlvbnMsIHsgc2tpcF9iYWNrZHJvcDogdHJ1ZSwgYW5pbWF0ZTogc2hvdWxkX2FuaW1hdGUgfSk7XG5cbiAgICAgICAgLy8gUmVjb3JkIGNsb3NlIHRpbWVzdGFtcCBCRUZPUkUgcmVzb2x2aW5nIChlbnN1cmVzIGl0J3Mgc2V0IGJlZm9yZSBuZXh0IG1vZGFsIGNhbiBzdGFydClcbiAgICAgICAgdGhpcy5fbGFzdF9jbG9zZV90aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIC8vIFJlc29sdmUgdGhlIHByb21pc2Ugd2l0aCB0aGUgcmVzdWx0XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcblxuICAgICAgICAvLyBDbGVhciBjdXJyZW50IGFuZCBwcm9jZXNzIG5leHRcbiAgICAgICAgdGhpcy5fY3VycmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3Byb2Nlc3NfcXVldWUoKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFN0YXRlIE1hbmFnZW1lbnQgTWV0aG9kc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhIG1vZGFsIGlzIGN1cnJlbnRseSBvcGVuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgc3RhdGljIGlzX29wZW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50ICE9PSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudGx5IG9wZW4gbW9kYWwgaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7UnN4X01vZGFsfG51bGx9XG4gICAgICovXG4gICAgc3RhdGljIGdldF9jdXJyZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JjZSBjbG9zZSB0aGUgY3VycmVudCBtb2RhbFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBjbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2N1cnJlbnQuY2xvc2UoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgdmFsaWRhdGlvbiBlcnJvcnMgdG8gdGhlIGN1cnJlbnQgbW9kYWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZXJyb3JzIC0gRXJyb3Igb2JqZWN0IHtmaWVsZDogbWVzc2FnZX1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXBwbHlfZXJyb3JzKGVycm9ycykge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudCkge1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudC5hcHBseV9lcnJvcnMoZXJyb3JzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gU2ltcGxlIERpYWxvZyBNZXRob2RzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gYWxlcnQgZGlhbG9nXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSB0aXRsZV9vcl9ib2R5IC0gTWVzc2FnZSAoaWYgb25seSAxIGFyZykgb3IgVGl0bGUgKGlmIDIgYXJncykuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSBib2R5IC0gTWVzc2FnZSBib2R5IChpZiAyIGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBidXR0b25fbGFiZWwgLSBCdXR0b24gdGV4dCAoZGVmYXVsdDogXCJPS1wiKVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBhbGVydCh0aXRsZV9vcl9ib2R5LCBib2R5ID0gbnVsbCwgYnV0dG9uX2xhYmVsID0gJ09LJykge1xuICAgICAgICBsZXQgdGl0bGUgPSAnTm90aWNlJztcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aXRsZV9vcl9ib2R5O1xuXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRpdGxlX29yX2JvZHk7XG4gICAgICAgICAgICBtZXNzYWdlID0gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogbWVzc2FnZSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBidXR0b25fbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgY29uZmlybWF0aW9uIGRpYWxvZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gdGl0bGVfb3JfYm9keSAtIE1lc3NhZ2UgKGlmIDEtMiBhcmdzKSBvciBUaXRsZSAoaWYgMy00IGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gYm9keSAtIE1lc3NhZ2UgYm9keSAob3B0aW9uYWwpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb25maXJtX2xhYmVsIC0gQ29uZmlybSBidXR0b24gdGV4dCAoZGVmYXVsdDogXCJDb25maXJtXCIpXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNhbmNlbF9sYWJlbCAtIENhbmNlbCBidXR0b24gdGV4dCAoZGVmYXVsdDogXCJDYW5jZWxcIilcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY29uZmlybSh0aXRsZV9vcl9ib2R5LCBib2R5ID0gbnVsbCwgY29uZmlybV9sYWJlbCA9ICdDb25maXJtJywgY2FuY2VsX2xhYmVsID0gJ0NhbmNlbCcpIHtcbiAgICAgICAgbGV0IHRpdGxlID0gJ0NvbmZpcm0nO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IHRpdGxlX29yX2JvZHk7XG5cbiAgICAgICAgaWYgKGJvZHkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGVfb3JfYm9keTtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGNhbmNlbF9sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1zZWNvbmRhcnknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogY29uZmlybV9sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXByaW1hcnknLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIHByb21wdCBkaWFsb2cgZm9yIHRleHQgaW5wdXRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IHRpdGxlX29yX2JvZHkgLSBNZXNzYWdlIChpZiAxLTMgYXJncykgb3IgVGl0bGUgKGlmIDQgYXJncykuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSBib2R5IC0gTWVzc2FnZSBib2R5IChvcHRpb25hbCkuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRfdmFsdWUgLSBEZWZhdWx0IGlucHV0IHZhbHVlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBtdWx0aWxpbmUgLSBTaG93IHRleHRhcmVhIGluc3RlYWQgb2YgaW5wdXRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXJyb3IgLSBPcHRpb25hbCBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgYXMgdmFsaWRhdGlvbiBmZWVkYmFja1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ3xmYWxzZT59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHByb21wdCh0aXRsZV9vcl9ib2R5LCBib2R5ID0gbnVsbCwgZGVmYXVsdF92YWx1ZSA9ICcnLCBtdWx0aWxpbmUgPSBmYWxzZSwgZXJyb3IgPSBudWxsKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdJbnB1dCc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICAvLyBIYW5kbGUgb3ZlcmxvYWRlZCBhcmd1bWVudHNcbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJyAmJiBib2R5ICE9PSAnJykge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgaW5wdXQgZWxlbWVudCB3aXRoIG1pbmltdW0gd2lkdGggY29uc3RyYWludHNcbiAgICAgICAgY29uc3QgJGlucHV0ID0gbXVsdGlsaW5lXG4gICAgICAgICAgICA/ICQoJzx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJvd3M9XCI0XCIgc3R5bGU9XCJtaW4td2lkdGg6IDMxNXB4O1wiPjwvdGV4dGFyZWE+JylcbiAgICAgICAgICAgIDogJCgnPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBzdHlsZT1cIm1pbi13aWR0aDogMjQ1cHg7XCI+Jyk7XG5cbiAgICAgICAgJGlucHV0LnZhbChkZWZhdWx0X3ZhbHVlKTtcblxuICAgICAgICAvLyBNYXJrIGFzIGludmFsaWQgaWYgdGhlcmUncyBhbiBlcnJvclxuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICRpbnB1dC5hZGRDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGJvZHkgd2l0aCBtZXNzYWdlIGFuZCBpbnB1dFxuICAgICAgICBsZXQgJGJvZHk7XG4gICAgICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgalF1ZXJ5KSB7XG4gICAgICAgICAgICAvLyBJZiBtZXNzYWdlIGlzIGEgalF1ZXJ5IGVsZW1lbnQsIHVzZSBpdCBhcyB0aGUgY29udGFpbmVyIGFuZCBhcHBlbmQgaW5wdXRcbiAgICAgICAgICAgICRib2R5ID0gbWVzc2FnZS5hcHBlbmQoJGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIElmIG1lc3NhZ2UgaXMgYSBzdHJpbmcsIGNyZWF0ZSB3cmFwcGVyIHdpdGggdGV4dCBhbmQgaW5wdXQgKDM2cHggc3BhY2luZylcbiAgICAgICAgICAgICRib2R5ID0gJCgnPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj4nKS5hcHBlbmQoJCgnPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDM2cHg7XCI+JykudGV4dChtZXNzYWdlKSkuYXBwZW5kKCRpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgZXJyb3IgbWVzc2FnZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlcnJvciA9ICQoJzxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIGQtYmxvY2tcIj48L2Rpdj4nKS50ZXh0KGVycm9yKTtcbiAgICAgICAgICAgICRib2R5LmFwcGVuZCgkZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiAkYm9keSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQ2FuY2VsJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1zZWNvbmRhcnknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ1N1Ym1pdCcsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBudWxsLCAvLyBXaWxsIGJlIHJlcGxhY2VkIGJ5IGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXByaW1hcnknLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRpbnB1dC52YWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA1MDAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZvY3VzIGFuZCBzZWxlY3QgaW5wdXQgYWZ0ZXIgbW9kYWwgc2hvd3NcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICRpbnB1dC5mb2N1cygpO1xuICAgICAgICAgICAgaWYgKCFtdWx0aWxpbmUpIHtcbiAgICAgICAgICAgICAgICAkaW5wdXQuc2VsZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbiBlcnJvciBkaWFsb2cgd2l0aCByZWQgYWxlcnQgc3R5bGluZ1xuICAgICAqXG4gICAgICogQ2FuIGFwcGVhciBvdmVyIG90aGVyIG1vZGFscyB0byBzaG93IGNyaXRpY2FsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMuXG4gICAgICogVXNlZCBwcmltYXJpbHkgZm9yIEFqYXggZXJyb3JzIHRoYXQgd2VyZW4ndCBjYXVnaHQgYnkgYXBwbGljYXRpb24gY29kZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfEVycm9yfE9iamVjdH0gZXJyb3IgLSBFcnJvciBtZXNzYWdlIHN0cmluZywgRXJyb3Igb2JqZWN0LCBvciBzdHJ1Y3R1cmVkIGVycm9yXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlIC0gTW9kYWwgdGl0bGUgKGRlZmF1bHQ6IFwiRXJyb3JcIilcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZXJyb3IoZXJyb3IsIHRpdGxlID0gJ0Vycm9yJykge1xuICAgICAgICBsZXQgbWVzc2FnZSA9ICcnO1xuXG4gICAgICAgIC8vIEhhbmRsZSBkaWZmZXJlbnQgZXJyb3IgdHlwZXNcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcjtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3IubWVzc2FnZSB8fCBlcnJvci50b1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yICYmIGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yICYmIGVycm9yLmVycm9yKSB7XG4gICAgICAgICAgICAvLyBGYXRhbCBlcnJvciB3aXRoIGRldGFpbHNcbiAgICAgICAgICAgIGNvbnN0IGRldGFpbHMgPSBlcnJvci5lcnJvcjtcbiAgICAgICAgICAgIGlmIChkZXRhaWxzLmZpbGUgJiYgZGV0YWlscy5saW5lKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBVbmNhdWdodCBGYXRhbCBFcnJvciBpbiAke2RldGFpbHMuZmlsZX06JHtkZXRhaWxzLmxpbmV9OlxcblxcbiR7ZGV0YWlscy5lcnJvcn1gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gZGV0YWlscy5lcnJvciB8fCAnQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGVycm9yIGJvZHkgd2l0aCByZWQgYWxlcnQgc3R5bGluZ1xuICAgICAgICBjb25zdCAkYm9keSA9ICQoJzxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXIgbWItMFwiIHJvbGU9XCJhbGVydFwiPicpLmFwcGVuZChcbiAgICAgICAgICAgICQoJzxwcmUgY2xhc3M9XCJtYi0wXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IHdvcmQtd3JhcDogYnJlYWstd29yZDsgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsgZm9udC1zaXplOiAwLjllbTtcIj4nKS50ZXh0KFxuICAgICAgICAgICAgICAgIG1lc3NhZ2VcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6ICRib2R5LFxuICAgICAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdDbG9zZScsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1kYW5nZXInLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgICAgICBtYXhfd2lkdGg6IDYwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBDdXN0b20gTW9kYWwgTWV0aG9kc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgY3VzdG9tIG1vZGFsIHdpdGggc3BlY2lmaWVkIGNvbnRlbnQgYW5kIGJ1dHRvbnNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzaG93KG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgICAgICAgICB0aXRsZTogJ01vZGFsJyxcbiAgICAgICAgICAgIGJvZHk6ICcnLFxuICAgICAgICAgICAgYnV0dG9uczogW10sXG4gICAgICAgICAgICBtYXhfd2lkdGg6IDgwMCxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGZpbmFsX29wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoZmluYWxfb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIG1vZGFsIHdpdGggYSBqcWh0bWwgZm9ybSBjb21wb25lbnRcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmNvbXBvbmVudCAtIENvbXBvbmVudCBjbGFzcyBuYW1lXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuY29tcG9uZW50X2FyZ3MgLSBBcmd1bWVudHMgdG8gcGFzcyB0byBjb21wb25lbnRcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRpb25zLm9uX3N1Ym1pdCAtIENhbGxiYWNrIGZ1bmN0aW9uIGNhbGxlZCBvbiBzdWJtaXQuIFJlY2VpdmVzIGZvcm0gY29tcG9uZW50IGluc3RhbmNlLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJldHVybiBmYWxzZSB0byBrZWVwIG1vZGFsIG9wZW4sIG9yIHJldHVybiBkYXRhIHRvIGNsb3NlIGFuZCByZXNvbHZlLlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdHxmYWxzZT59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGZvcm0ob3B0aW9ucykge1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgICAgICAgIHRpdGxlOiAnRm9ybScsXG4gICAgICAgICAgICBjb21wb25lbnQ6IG51bGwsXG4gICAgICAgICAgICBjb21wb25lbnRfYXJnczoge30sXG4gICAgICAgICAgICBtYXhfd2lkdGg6IDgwMCxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgc3VibWl0X2xhYmVsOiAnU3VibWl0JyxcbiAgICAgICAgICAgIGNhbmNlbF9sYWJlbDogJ0NhbmNlbCcsXG4gICAgICAgICAgICBvbl9zdWJtaXQ6IG51bGwsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmluYWxfb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRzLCBvcHRpb25zKTtcblxuICAgICAgICBpZiAoIWZpbmFsX29wdGlvbnMuY29tcG9uZW50KSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdNb2RhbC5mb3JtKCkgcmVxdWlyZXMgYSBjb21wb25lbnQnKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBjb21wb25lbnQgaW5zdGFuY2VcbiAgICAgICAgbGV0ICRjb21wb25lbnRfY29udGFpbmVyID0gJCgnPGRpdj4nKTtcbiAgICAgICAgbGV0IGNvbXBvbmVudF9pbnN0YW5jZSA9ICRjb21wb25lbnRfY29udGFpbmVyLmNvbXBvbmVudChmaW5hbF9vcHRpb25zLmNvbXBvbmVudCwgZmluYWxfb3B0aW9ucy5jb21wb25lbnRfYXJncyk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgY29tcG9uZW50IHRvIGJlIHJlYWR5XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBjb21wb25lbnRfaW5zdGFuY2Uub24oJ3JlYWR5JywgKCkgPT4gcmVzb2x2ZSgpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRmluZCBhIGZvcm0gaW5zdGFuY2UgaWYgY29tcG9uZW50IGluc3RhbmNlIGRvZXNudCBoYXZlIC52YWxzKClcbiAgICAgICAgaWYgKCFjb21wb25lbnRfaW5zdGFuY2UudmFscykge1xuICAgICAgICAgICAgbGV0ICRmb3JtID0gY29tcG9uZW50X2luc3RhbmNlLiQuZmluZCgnLlJzeF9Gb3JtJyk7XG4gICAgICAgICAgICBpZiAoJGZvcm0uZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnRfaW5zdGFuY2UgPSAkZm9ybS5jb21wb25lbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBidXR0b25zXG4gICAgICAgIGNvbnN0IGJ1dHRvbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IGZpbmFsX29wdGlvbnMuY2FuY2VsX2xhYmVsLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1zZWNvbmRhcnknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogZmluYWxfb3B0aW9ucy5zdWJtaXRfbGFiZWwsXG4gICAgICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tcHJpbWFyeScsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiBvbl9zdWJtaXQgY2FsbGJhY2sgcHJvdmlkZWQsIHVzZSBpdFxuICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxfb3B0aW9ucy5vbl9zdWJtaXQgJiYgdHlwZW9mIGZpbmFsX29wdGlvbnMub25fc3VibWl0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaW5hbF9vcHRpb25zLm9uX3N1Ym1pdChjb21wb25lbnRfaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgY2FsbGJhY2sgcmV0dXJucyBudWxsL3VuZGVmaW5lZCwga2VlcCBtb2RhbCBvcGVuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIChpbmNsdWRpbmcgZmFsc2UpLCByZXR1cm4gdGhlIHJlc3VsdCB0byBjbG9zZSBtb2RhbFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIE5vIG9uX3N1Ym1pdCBjYWxsYmFjayAtIGdldCBmb3JtIGRhdGEgYW5kIGNsb3NlIG1vZGFsXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnRfaW5zdGFuY2Uuc3VibWl0ICYmIHR5cGVvZiBjb21wb25lbnRfaW5zdGFuY2Uuc3VibWl0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgY29tcG9uZW50X2luc3RhbmNlLnN1Ym1pdCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBvbmVudF9pbnN0YW5jZS52YWxzICYmIHR5cGVvZiBjb21wb25lbnRfaW5zdGFuY2UudmFscyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudF9pbnN0YW5jZS52YWxzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0Zvcm0gY29tcG9uZW50IGhhcyBubyBzdWJtaXQoKSBvciB2YWxzKCkgbWV0aG9kJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiBmaW5hbF9vcHRpb25zLnRpdGxlLFxuICAgICAgICAgICAgYm9keTogY29tcG9uZW50X2luc3RhbmNlLiQsXG4gICAgICAgICAgICBidXR0b25zOiBidXR0b25zLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiBmaW5hbF9vcHRpb25zLm1heF93aWR0aCxcbiAgICAgICAgICAgIGNsb3NhYmxlOiBmaW5hbF9vcHRpb25zLmNsb3NhYmxlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGFuIHVuY2xvc2FibGUgbW9kYWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGVfb3JfYm9keVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBib2R5XG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHVuY2xvc2FibGUodGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwpIHtcbiAgICAgICAgbGV0IHRpdGxlID0gJ1BsZWFzZSBXYWl0JztcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aXRsZV9vcl9ib2R5O1xuXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRpdGxlX29yX2JvZHk7XG4gICAgICAgICAgICBtZXNzYWdlID0gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvbid0IHdhaXQgZm9yIHRoaXMgcHJvbWlzZSAtIGl0IG5ldmVyIHJlc29sdmVzIHVudGlsIGNsb3NlZCBtYW51YWxseVxuICAgICAgICB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IG1lc3NhZ2UsXG4gICAgICAgICAgICBidXR0b25zOiBbXSwgLy8gTm8gYnV0dG9uc1xuICAgICAgICAgICAgY2xvc2FibGU6IGZhbHNlLCAvLyBDYW4ndCBjbG9zZVxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiBmYWxzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgbmV4dCBhbmltYXRpb24gZnJhbWUgZm9yIG1vZGFsIHRvIHJlbmRlclxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZShyZXNvbHZlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIG1vZGFsIHdpdGggY3VzdG9tIGpRdWVyeSBjb250ZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY3VzdG9tKG9wdGlvbnMpIHtcbiAgICAgICAgLy8gQWxpYXMgZm9yIHNob3coKSAtIHNhbWUgZnVuY3Rpb25hbGl0eVxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5zaG93KG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gSGVscGVyIE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbiBlcnJvciBhbGVydFxuICAgICAqIEBwYXJhbSB7Kn0gZXJyb3JzXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGVycm9yKGVycm9ycywgdGl0bGUgPSAnRXJyb3InKSB7XG4gICAgICAgIGxldCBtZXNzYWdlID0gJ0FuIGVycm9yIG9jY3VycmVkJztcblxuICAgICAgICAvLyBIYW5kbGUgdmFyaW91cyBlcnJvciBmb3JtYXRzXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3JzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9ycztcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvcnMgJiYgJ3Jlc3BvbnNlSlNPTicgaW4gZXJyb3JzICYmICdtZXNzYWdlJyBpbiBlcnJvcnMucmVzcG9uc2VKU09OKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JzLnJlc3BvbnNlSlNPTi5tZXNzYWdlO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9ycyAmJiAnbWVzc2FnZScgaW4gZXJyb3JzKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JzLm1lc3NhZ2U7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3JzICYmIHR5cGVvZiBlcnJvcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBUcnkgdG8gZm9ybWF0IGVycm9yIG9iamVjdFxuICAgICAgICAgICAgY29uc3QgZXJyb3JfbWVzc2FnZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGVycm9ycykge1xuICAgICAgICAgICAgICAgIGlmIChpc19hcnJheShlcnJvcnNba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZXMucHVzaChlcnJvcnNba2V5XVswXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZXMucHVzaChlcnJvcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVycm9yX21lc3NhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JfbWVzc2FnZXMuam9pbignXFxuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IG1lc3NhZ2UsXG4gICAgICAgICAgICBpY29uOiAnZXhjbGFtYXRpb24tY2lyY2xlJyxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnT0snLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tZGFuZ2VyJyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW9wZW4gY3VycmVudCBtb2RhbCB3aXRoIHZhbGlkYXRpb24gZXJyb3JzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGVycm9yc1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyByZW9wZW5fd2l0aF9lcnJvcnMoZXJyb3JzKSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICAvLyBNb2RhbCBpcyBzdGlsbCBvcGVuLCBqdXN0IGFwcGx5IGVycm9yc1xuICAgICAgICAgICAgdGhpcy5hcHBseV9lcnJvcnMoZXJyb3JzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignTm8gbW9kYWwgb3BlbiB0byBhcHBseSBlcnJvcnMgdG8nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEJyZWFkY3J1bWJfSXRlbSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gUmVhZCBocmVmIGZyb20gSFRNTCBhdHRyaWJ1dGUgaWYgcHJlc2VudFxuICAgICAgICBjb25zdCBocmVmID0gdGhpcy4kLmF0dHIoJ2hyZWYnKTtcbiAgICAgICAgaWYgKGhyZWYpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5ocmVmID0gaHJlZjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlYWQgYWN0aXZlIGZyb20gSFRNTCBhdHRyaWJ1dGUgaWYgcHJlc2VudFxuICAgICAgICBjb25zdCBhY3RpdmUgPSB0aGlzLiQuYXR0cignYWN0aXZlJyk7XG4gICAgICAgIGlmIChhY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLmFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2FyaWEtY3VycmVudCcsICdwYWdlJyk7XG4gICAgICAgICAgICB0aGlzLiQucmVtb3ZlQXR0cignYWN0aXZlJyk7IC8vIFJlbW92ZSB0aGUgYXR0cmlidXRlIGFmdGVyIHJlYWRpbmdcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENsaWVudF9MYWJlbF9MaW5rIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBudWxsO1xuXG4gICAgICAgIC8vIENvbnZlcnQgY2xpZW50X2lkIHRvIG51bWJlciBpZiBpdCdzIGEgbnVtZXJpYyBzdHJpbmdcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGllbnRfaWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5jbGllbnRfaWQgPSB2YWx1ZV91bmxlc3NfbnVtZXJpY19zdHJpbmdfdGhlbl9udW1lcmljX3ZhbHVlKHRoaXMuYXJncy5jbGllbnRfaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBjbGllbnQgZGF0YSBpZiB3ZSBoYXZlIGFuIElEXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBhd2FpdCBGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmdldF9jbGllbnQoe1xuICAgICAgICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuYXJncy5jbGllbnRfaWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgY2xpZW50OicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlbmRlcigpIHtcbiAgICAgICAgLy8gU2V0IGhyZWYgZHluYW1pY2FsbHkgYWZ0ZXIgZWFjaCByZW5kZXJcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGllbnRfaWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGhyZWYgPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlcicsICd2aWV3JywgdGhpcy5hcmdzLmNsaWVudF9pZCk7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignaHJlZicsIGhyZWYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2hyZWYnLCAnIycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IG9yIHNldCB0aGUgY2xpZW50X2lkXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtjbGllbnRfaWRdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIGNsaWVudF9pZCBhbmQgcmVsb2Fkc1xuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEN1cnJlbnQgY2xpZW50X2lkIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbChjbGllbnRfaWQpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXJncy5jbGllbnRfaWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXIgLSB1cGRhdGUgY2xpZW50X2lkIGFuZCByZWxvYWRcbiAgICAgICAgICAgIHRoaXMuYXJncy5jbGllbnRfaWQgPSB2YWx1ZV91bmxlc3NfbnVtZXJpY19zdHJpbmdfdGhlbl9udW1lcmljX3ZhbHVlKGNsaWVudF9pZCk7XG4gICAgICAgICAgICB0aGlzLmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gbnVsbDtcblxuICAgICAgICAgICAgLy8gUmVsb2FkIGNsaWVudCBkYXRhIGFuZCByZS1yZW5kZXIgKG9uX3JlbmRlciB3aWxsIHVwZGF0ZSBocmVmKVxuICAgICAgICAgICAgdGhpcy5vbl9sb2FkKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgQ2xpZW50X0xhYmVsIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBudWxsO1xuXG4gICAgICAgIC8vIENvbnZlcnQgY2xpZW50X2lkIHRvIG51bWJlciBpZiBpdCdzIGEgbnVtZXJpYyBzdHJpbmdcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGllbnRfaWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5jbGllbnRfaWQgPSB2YWx1ZV91bmxlc3NfbnVtZXJpY19zdHJpbmdfdGhlbl9udW1lcmljX3ZhbHVlKHRoaXMuYXJncy5jbGllbnRfaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBjbGllbnQgZGF0YSBpZiB3ZSBoYXZlIGFuIElEXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBhd2FpdCBGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmdldF9jbGllbnQoe1xuICAgICAgICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuYXJncy5jbGllbnRfaWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgY2xpZW50OicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgdGhlIGNsaWVudF9pZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbY2xpZW50X2lkXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBjbGllbnRfaWQgYW5kIHJlbG9hZHNcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBDdXJyZW50IGNsaWVudF9pZCB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwoY2xpZW50X2lkKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3MuY2xpZW50X2lkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gdXBkYXRlIGNsaWVudF9pZCBhbmQgcmVsb2FkXG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZShjbGllbnRfaWQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNsaWVudCA9IG51bGw7XG5cbiAgICAgICAgICAgIC8vIFJlbG9hZCBjbGllbnQgZGF0YSBhbmQgcmUtcmVuZGVyIChvbl9yZW5kZXIgd2lsbCB1cGRhdGUgaHJlZilcbiAgICAgICAgICAgIHRoaXMub25fbG9hZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8qKlxuICogRm9ybV9JbnB1dF9BYnN0cmFjdCAtIEJhc2UgY2xhc3MgZm9yIGFsbCBmb3JtIGlucHV0IHdpZGdldHNcbiAqXG4gKiBEZWZpbmVzIHRoZSBpbnRlcmZhY2UgdGhhdCBhbGwgZm9ybSB3aWRnZXRzIG11c3QgaW1wbGVtZW50LlxuICogVGhpcyBlbnN1cmVzIGNvbnNpc3RlbmN5IGFjcm9zcyBhbGwgaW5wdXQgdHlwZXMgKHRleHQsIHNlbGVjdCwgd3lzaXd5ZywgZXRjLilcbiAqXG4gKiBSRVFVSVJFRCBNRVRIT0RTIChtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzZXMpOlxuICogLSB2YWwoKSAtIEdldCBjdXJyZW50IHZhbHVlIChubyBhcmd1bWVudHMpXG4gKiAtIHZhbCh2YWx1ZSkgLSBTZXQgdmFsdWUgKG9uZSBhcmd1bWVudClcbiAqIC0gc2VlZCgpIC0gRmlsbHMgdGhlIHdpZGdldCB3aXRoIHJhbmRvbSB0ZXN0IGRhdGEgKG9wdGlvbmFsKVxuICpcbiAqIEFsbCB3aWRnZXRzIG11c3Q6XG4gKiAtIEhhdmUgLldpZGdldCBDU1MgY2xhc3NcbiAqIC0gSGF2ZSBkYXRhLW5hbWUgYXR0cmlidXRlIHNldCBieSBGb3JtX0ZpZWxkXG4gKi9cbmNsYXNzIEZvcm1fSW5wdXRfQWJzdHJhY3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGN1cnJlbnQgdmFsdWVcbiAgICAgKiBTdWJjbGFzc2VzIE1VU1QgaW1wbGVtZW50IHRoaXMgbWV0aG9kXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgdmFsdWUuIElmIG9taXR0ZWQsIHJldHVybnMgdGhlIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgY3VycmVudCB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gbXVzdCBpbXBsZW1lbnQgdmFsKCkgZ2V0dGVyYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHZhbCh2YWx1ZSkgc2V0dGVyYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWVkIC0gRmlsbCB3aXRoIHJhbmRvbSB0ZXN0IGRhdGEgKG9wdGlvbmFsKVxuICAgICAqIFN1YmNsYXNzZXMgTUFZIGltcGxlbWVudCB0aGlzIG1ldGhvZFxuICAgICAqL1xuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIC8vIE9wdGlvbmFsIC0gd2lkZ2V0cyBjYW4gb3ZlcnJpZGUgaWYgdGhleSBzdXBwb3J0IHNlZWRpbmdcbiAgICB9XG59XG4iLCJjbGFzcyBUZXh0X0lucHV0IGV4dGVuZHMgRm9ybV9JbnB1dF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGlucHV0IHZhbHVlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudCB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSB2YWx1ZSB8fCAnJztcbiAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh0aGlzLmRhdGEudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zZWVkZXIpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IEltcGxlbWVudCBSc3hfUmFuZG9tX1ZhbHVlcyBlbmRwb2ludFxuICAgICAgICAgICAgLy8gbGV0IHZhbHVlID0gYXdhaXQgUnN4X1JhbmRvbV9WYWx1ZXNbdGhpcy5hcmdzLnNlZWRlcl0oKTtcbiAgICAgICAgICAgIC8vIEZvciBub3csIGp1c3QgdXNlIHBsYWNlaG9sZGVyIHRleHRcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9ICdUZXN0ICcgKyAodGhpcy5hcmdzLnNlZWRlciB8fCAnVmFsdWUnKTtcbiAgICAgICAgICAgIHRoaXMudmFsKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENoZWNrYm94X0lucHV0IGV4dGVuZHMgRm9ybV9JbnB1dF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoZWNrZWRfdmFsdWUgPSB0aGlzLmFyZ3MuY2hlY2tlZF92YWx1ZSB8fCAnMSc7XG4gICAgICAgIHRoaXMudW5jaGVja2VkX3ZhbHVlID0gdGhpcy5hcmdzLnVuY2hlY2tlZF92YWx1ZSB8fCAnMCc7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENvbm5lY3QgbGFiZWwgY2xpY2tzIHRvIGNoZWNrYm94XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICBjb25zdCAkbGFiZWwgPSB0aGlzLiRpZCgnbGFiZWwnKTtcblxuICAgICAgICBpZiAoJGxhYmVsLmV4aXN0cygpKSB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dF9pZCA9ICRpbnB1dC5hdHRyKCdpZCcpO1xuICAgICAgICAgICAgJGxhYmVsLmF0dHIoJ2ZvcicsIGlucHV0X2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCB0aGUgY2hlY2tib3ggc3RhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xib29sZWFufSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIGNoZWNrZWQgc3RhdGVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY2hlY2tlZF92YWx1ZSBvciB1bmNoZWNrZWRfdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIGNvbnN0IGlzX2NoZWNrZWQgPSB0aGlzLiRpZCgnaW5wdXQnKS5wcm9wKCdjaGVja2VkJyk7XG4gICAgICAgICAgICByZXR1cm4gaXNfY2hlY2tlZCA/IHRoaXMuY2hlY2tlZF92YWx1ZSA6IHRoaXMudW5jaGVja2VkX3ZhbHVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gYWNjZXB0cyBib29sZWFuLCBjaGVja2VkX3ZhbHVlLCBvciB1bmNoZWNrZWRfdmFsdWVcbiAgICAgICAgICAgIGxldCBzaG91bGRfY2hlY2sgPSBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkX2NoZWNrID0gdmFsdWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSB0aGlzLmNoZWNrZWRfdmFsdWUgfHwgdmFsdWUgPT09ICcxJyB8fCB2YWx1ZSA9PT0gMSB8fCB2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHNob3VsZF9jaGVjayA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZGF0YS5jaGVja2VkID0gc2hvdWxkX2NoZWNrO1xuICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykucHJvcCgnY2hlY2tlZCcsIHNob3VsZF9jaGVjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICAvLyBSYW5kb21seSBjaGVjayBvciB1bmNoZWNrXG4gICAgICAgIHRoaXMudmFsKE1hdGgucmFuZG9tKCkgPiAwLjUpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogV3lzaXd5Z19JbnB1dCAtIFdZU0lXWUcgZWRpdG9yIHdpZGdldCB1c2luZyBRdWlsbFxuICpcbiAqIEltcGxlbWVudHMgdGhlIGZvcm0gd2lkZ2V0IGludGVyZmFjZTpcbiAqIC0gdmFsKCkgLSBHZXQvc2V0IEhUTUwgY29udGVudFxuICogLSBzZWVkKCkgLSBGaWxscyB3aXRoIHJhbmRvbSBjb250ZW50XG4gKi9cbmNsYXNzIFd5c2l3eWdfSW5wdXQgZXh0ZW5kcyBGb3JtX0lucHV0X0Fic3RyYWN0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHRoaXMucXVpbGwgPSBudWxsO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXYWl0IGZvciBRdWlsbCB0byBiZSBsb2FkZWQsIHRoZW4gaW5pdGlhbGl6ZVxuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgcXVpbGxfcmVhZHkoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB0aGF0Ll9pbml0aWFsaXplX3F1aWxsKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9pbml0aWFsaXplX3F1aWxsKCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIFF1aWxsIGVkaXRvclxuICAgICAgICB0aGlzLnF1aWxsID0gbmV3IFF1aWxsKHRoaXMuJGlkKCdlZGl0b3InKVswXSwge1xuICAgICAgICAgICAgdGhlbWU6ICdzbm93JyxcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ0VudGVyIHRleHQuLi4nLFxuICAgICAgICAgICAgbW9kdWxlczoge1xuICAgICAgICAgICAgICAgIHRvb2xiYXI6IFtcbiAgICAgICAgICAgICAgICAgICAgW3sgJ2hlYWRlcic6IFsxLCAyLCAzLCBmYWxzZV0gfV0sXG4gICAgICAgICAgICAgICAgICAgIFsnYm9sZCcsICdpdGFsaWMnLCAndW5kZXJsaW5lJywgJ3N0cmlrZSddLFxuICAgICAgICAgICAgICAgICAgICBbJ2Jsb2NrcXVvdGUnLCAnY29kZS1ibG9jayddLFxuICAgICAgICAgICAgICAgICAgICBbeyAnbGlzdCc6ICdvcmRlcmVkJ30sIHsgJ2xpc3QnOiAnYnVsbGV0JyB9XSxcbiAgICAgICAgICAgICAgICAgICAgW3sgJ2luZGVudCc6ICctMSd9LCB7ICdpbmRlbnQnOiAnKzEnIH1dLFxuICAgICAgICAgICAgICAgICAgICBbJ2xpbmsnLCAnaW1hZ2UnXSxcbiAgICAgICAgICAgICAgICAgICAgWydjbGVhbiddXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgaGlkZGVuIGlucHV0IG9uIHRleHQgY2hhbmdlXG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICB0aGlzLnF1aWxsLm9uKCd0ZXh0LWNoYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhhdC4kaWQoJ2hpZGRlbl9pbnB1dCcpLnZhbCh0aGF0LnF1aWxsLnJvb3QuaW5uZXJIVE1MKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IEhUTUwgY29udGVudFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIEhUTUwgY29udGVudFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBIVE1MIGNvbnRlbnQgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIGlmICghdGhpcy5xdWlsbCkgcmV0dXJuICcnO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucXVpbGwucm9vdC5pbm5lckhUTUw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIGlmICghdGhpcy5xdWlsbCkge1xuICAgICAgICAgICAgICAgIC8vIFF1aWxsIG5vdCByZWFkeSB5ZXQsIHdhaXQgYW5kIHRyeSBhZ2FpblxuICAgICAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhhdC52YWwodmFsdWUpLCAxMDApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWlsbC5yb290LmlubmVySFRNTCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdoaWRkZW5faW5wdXQnKS52YWwodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlZCAtIEZpbGwgd2l0aCByYW5kb20gY29udGVudCBmb3IgdGVzdGluZ1xuICAgICAqL1xuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5xdWlsbCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHNhbXBsZV9jb250ZW50ID0gYFxuICAgICAgICAgICAgPGgyPlNhbXBsZSBIZWFkaW5nPC9oMj5cbiAgICAgICAgICAgIDxwPlRoaXMgaXMgYSBzYW1wbGUgcGFyYWdyYXBoIHdpdGggPHN0cm9uZz5ib2xkIHRleHQ8L3N0cm9uZz4gYW5kIDxlbT5pdGFsaWMgdGV4dDwvZW0+LjwvcD5cbiAgICAgICAgICAgIDx1bD5cbiAgICAgICAgICAgICAgICA8bGk+Rmlyc3QgYnVsbGV0IHBvaW50PC9saT5cbiAgICAgICAgICAgICAgICA8bGk+U2Vjb25kIGJ1bGxldCBwb2ludDwvbGk+XG4gICAgICAgICAgICAgICAgPGxpPlRoaXJkIGJ1bGxldCBwb2ludDwvbGk+XG4gICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPHA+QW5vdGhlciBwYXJhZ3JhcGggd2l0aCA8YSBocmVmPVwiI1wiPmEgc2FtcGxlIGxpbms8L2E+LjwvcD5cbiAgICAgICAgYDtcblxuICAgICAgICB0aGlzLnZhbChzYW1wbGVfY29udGVudCk7XG4gICAgfVxufVxuIiwiY2xhc3MgU2VsZWN0X0lucHV0IGV4dGVuZHMgRm9ybV9JbnB1dF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSAnJztcblxuICAgICAgICAvLyBQYXJzZSBvcHRpb25zIGlmIHBhc3NlZCBhcyBKU09OIHN0cmluZ1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuYXJncy5vcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBEZWNvZGUgSFRNTCBlbnRpdGllcyBiZWZvcmUgcGFyc2luZyBKU09OXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIEpTT04gaXMgcGFzc2VkIHRocm91Z2ggQmxhZGUgeyEhICEhfSBzeW50YXhcbiAgICAgICAgICAgICAgICBjb25zdCBkZWNvZGVkID0gJCgnPHRleHRhcmVhPicpLmh0bWwodGhpcy5hcmdzLm9wdGlvbnMpLnRleHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub3B0aW9ucyA9IGpzb25fZGVjb2RlKGRlY29kZWQpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBwYXJzZSBvcHRpb25zIEpTT046JywgZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9wdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnZlcnQgb2JqZWN0IG9wdGlvbnMgdG8gYXJyYXkgZm9ybWF0XG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub3B0aW9ucyAmJiB0eXBlb2YgdGhpcy5hcmdzLm9wdGlvbnMgPT09ICdvYmplY3QnICYmICFpc19hcnJheSh0aGlzLmFyZ3Mub3B0aW9ucykpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vcHRpb25zID0gT2JqZWN0LmVudHJpZXModGhpcy5hcmdzLm9wdGlvbnMpLm1hcCgoW3ZhbHVlLCBsYWJlbF0pID0+ICh7dmFsdWUsIGxhYmVsfSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBsZXQgY29uZmlnID0ge1xuICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyxcbiAgICAgICAgICAgIGFsbG93RW1wdHlPcHRpb246IHRydWUsXG4gICAgICAgICAgICBjcmVhdGU6IGZhbHNlLFxuICAgICAgICAgICAgbWF4T3B0aW9uczogbnVsbCwgIC8vIFNob3cgYWxsIG9wdGlvbnMgKGRlZmF1bHQgaXMgNTApXG4gICAgICAgICAgICBwbHVnaW5zOiBbJ2Ryb3Bkb3duX2lucHV0J10sICAvLyBFbmFibGUgc2VhcmNoIGluIGRyb3Bkb3duXG4gICAgICAgICAgICBvbkluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIC8vIEtlZXAgQm9vdHN0cmFwIGZvcm0tc2VsZWN0IGNsYXNzXG4gICAgICAgICAgICAgICAgdGhpcy5jb250cm9sLmNsYXNzTGlzdC5hZGQoJ2Zvcm0tc2VsZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy50b21fc2VsZWN0ID0gbmV3IFRvbVNlbGVjdCh0aGlzLiRpZCgnaW5wdXQnKS5nZXQoMCksIGNvbmZpZyk7XG5cbiAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuZGF0YS52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LnNldFZhbHVlKHRoaXMuZGF0YS52YWx1ZSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIHNlbGVjdGVkIHZhbHVlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudCB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvbV9zZWxlY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlclxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICBpZiAodGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LnNldFZhbHVlKHRoaXMuZGF0YS52YWx1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKHRoaXMuZGF0YS52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLnNlZWRlcikge1xuICAgICAgICAgICAgLy8gVE9ETzogSW1wbGVtZW50IFJzeF9SYW5kb21fVmFsdWVzIGVuZHBvaW50XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSAnVGVzdCAnICsgKHRoaXMuYXJncy5zZWVkZXIgfHwgJ1ZhbHVlJyk7XG4gICAgICAgICAgICB0aGlzLnZhbCh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcmdzLm9wdGlvbnMgJiYgdGhpcy5hcmdzLm9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gU2VsZWN0IHJhbmRvbSBvcHRpb25cbiAgICAgICAgICAgIGxldCByYW5kb21faW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB0aGlzLmFyZ3Mub3B0aW9ucy5sZW5ndGgpO1xuICAgICAgICAgICAgbGV0IHJhbmRvbV9vcHQgPSB0aGlzLmFyZ3Mub3B0aW9uc1tyYW5kb21faW5kZXhdO1xuICAgICAgICAgICAgbGV0IHJhbmRvbV92YWx1ZSA9IHR5cGVvZiByYW5kb21fb3B0ID09PSAnb2JqZWN0JyA/IHJhbmRvbV9vcHQudmFsdWUgOiByYW5kb21fb3B0O1xuICAgICAgICAgICAgdGhpcy52YWwocmFuZG9tX3ZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX2Rlc3Ryb3koKSB7XG4gICAgICAgIC8vIENsZWFuIHVwIFRvbSBTZWxlY3QgaW5zdGFuY2VcbiAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEFqYXhfU2VsZWN0X0lucHV0IGV4dGVuZHMgU2VsZWN0X0lucHV0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgZW1wdHkgc2VsZWN0IHZhbHVlcyBhcnJheVxuICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFtdO1xuXG4gICAgICAgIC8vIFN0b3JlIGZvciB2YWx1ZSBzZXQgYmVmb3JlIGluaXRpYWxpemF0aW9uIGNvbXBsZXRlc1xuICAgICAgICB0aGlzLl9wZW5kaW5nX3ZhbHVlID0gbnVsbDtcblxuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBkbyBiYXNpYyBzZXR1cFxuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcbiAgICB9XG5cbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICAvLyBMb2FkIG9wdGlvbnMgZnJvbSBBamF4IGVuZHBvaW50IGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSFRUUCBlcnJvciEgc3RhdHVzOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IGRhdGE7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHNlbGVjdCBvcHRpb25zOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIC8vIElmIGEgdmFsdWUgd2FzIHNldCBiZWZvcmUgaW5pdGlhbGl6YXRpb24sIGFwcGx5IGl0IG5vd1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ192YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLl9wZW5kaW5nX3ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodGhpcy5fcGVuZGluZ192YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSB0aGlzLl9wZW5kaW5nX3ZhbHVlO1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZ192YWx1ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIHNlbGVjdGVkIHZhbHVlXG4gICAgICogSGFuZGxlcyBjYWxscyBiZWZvcmUgVG9tIFNlbGVjdCBpbml0aWFsaXphdGlvbiBjb21wbGV0ZXNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IHZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBpZiAodGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZWQgLSBnZXQgZnJvbSBUb20gU2VsZWN0XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9tX3NlbGVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9wZW5kaW5nX3ZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gTm90IHlldCBpbml0aWFsaXplZCAtIHJldHVybiBwZW5kaW5nIHZhbHVlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BlbmRpbmdfdmFsdWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YS52YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIFJldHVybiBkYXRhIHZhbHVlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlclxuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemVkIC0gc2V0IHZpYSBUb20gU2VsZWN0XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LnNldFZhbHVlKHRoaXMuZGF0YS52YWx1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIE5vdCB5ZXQgaW5pdGlhbGl6ZWQgLSBzdG9yZSBmb3IgbGF0ZXJcbiAgICAgICAgICAgICAgICB0aGlzLl9wZW5kaW5nX3ZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIEN1cnJlbmN5X0lucHV0XG4gKlxuICogRXh0ZW5kcyBUZXh0X0lucHV0IHRvIHByb3ZpZGUgYXV0b21hdGljIGN1cnJlbmN5IGZvcm1hdHRpbmcuXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIEFkZHMgdGhvdXNhbmRzIHNlcGFyYXRvcnMgKGNvbW1hcykgZXZlcnkgMyBkaWdpdHNcbiAqIC0gT3B0aW9uYWwgY3VycmVuY3kgc3ltYm9sIHByZWZpeCAoZGVmYXVsdDogaGlkZGVuKVxuICogLSBPcHRpb25hbCBkZWNpbWFsIHN1cHBvcnQgKGRlZmF1bHQ6IGRpc2FibGVkKVxuICogLSBTbWFydCBiYWNrc3BhY2Ugb3ZlciBmb3JtYXR0aW5nIGNoYXJhY3RlcnNcbiAqIC0gTm8gbWlkLXN0cmluZyBmb3JtYXR0aW5nICh3YWl0cyBmb3IgYmx1cilcbiAqXG4gKiBBcmd1bWVudHM6XG4gKiAtICRhbGxvd19kZWNpbWFscyAtIEFsbG93IDIgZGVjaW1hbCBwbGFjZXMgKGRlZmF1bHQ6IGZhbHNlKVxuICogLSAkc2hvd19zeW1ib2wgLSBTaG93IGN1cnJlbmN5IHN5bWJvbCAoZGVmYXVsdDogZmFsc2UpXG4gKiAtICRjdXJyZW5jeV9zeW1ib2wgLSBDdXJyZW5jeSBzeW1ib2wgdG8gdXNlIChkZWZhdWx0OiBcIiRcIilcbiAqXG4gKiBVc2FnZTpcbiAqICAgPEN1cnJlbmN5X0lucHV0IC8+XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAkc2hvd19zeW1ib2w9dHJ1ZSAvPlxuICogICA8Q3VycmVuY3lfSW5wdXQgJGFsbG93X2RlY2ltYWxzPXRydWUgLz5cbiAqICAgPEN1cnJlbmN5X0lucHV0ICRzaG93X3N5bWJvbD10cnVlICRhbGxvd19kZWNpbWFscz10cnVlICRjdXJyZW5jeV9zeW1ib2w9XCLigqxcIiAvPlxuICpcbiAqIEJlaGF2aW9yOlxuICogLSBUeXBlIFwiMTIzNDU2N1wiIC0+IGRpc3BsYXlzIFwiMSwyMzQsNTY3XCIsIHZhbCgpIHJldHVybnMgXCIxMjM0NTY3XCJcbiAqIC0gVHlwZSBcIjEyMzQ1NjcuODlcIiAod2l0aCBkZWNpbWFscykgLT4gZGlzcGxheXMgXCIxLDIzNCw1NjcuODlcIiwgdmFsKCkgcmV0dXJucyBcIjEyMzQ1NjcuODlcIlxuICogLSBXaXRoIHN5bWJvbDogZGlzcGxheXMgXCIkMSwyMzQsNTY3XCIsIHZhbCgpIHN0aWxsIHJldHVybnMgXCIxMjM0NTY3XCJcbiAqL1xuY2xhc3MgQ3VycmVuY3lfSW5wdXQgZXh0ZW5kcyBUZXh0X0lucHV0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHN1cGVyLm9uX2NyZWF0ZSgpO1xuXG4gICAgICAgIC8vIFNldCBkZWZhdWx0cyBmb3Igb3B0aW9uc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmFsbG93X2RlY2ltYWxzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5hbGxvd19kZWNpbWFscyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2hvd19zeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLnNob3dfc3ltYm9sID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbCA9ICckJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcm1hdCBjdXJyZW5jeSB3aXRoIGNvbW1hcyBhbmQgb3B0aW9uYWwgc3ltYm9sXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gTnVtZXJpYyB2YWx1ZSAobWF5IGluY2x1ZGUgZGVjaW1hbClcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBGb3JtYXR0ZWQgY3VycmVuY3kgc3RyaW5nXG4gICAgICovXG4gICAgX2Zvcm1hdF9jdXJyZW5jeSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGxpdCBpbnRvIGludGVnZXIgYW5kIGRlY2ltYWwgcGFydHNcbiAgICAgICAgbGV0IHBhcnRzID0gdmFsdWUuc3BsaXQoJy4nKTtcbiAgICAgICAgbGV0IGludGVnZXJfcGFydCA9IHBhcnRzWzBdO1xuICAgICAgICBsZXQgZGVjaW1hbF9wYXJ0ID0gcGFydHNbMV07XG5cbiAgICAgICAgLy8gQWRkIGNvbW1hcyB0byBpbnRlZ2VyIHBhcnRcbiAgICAgICAgaW50ZWdlcl9wYXJ0ID0gaW50ZWdlcl9wYXJ0LnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csICcsJyk7XG5cbiAgICAgICAgLy8gUmVjb25zdHJ1Y3Qgd2l0aCBkZWNpbWFsIGlmIGFsbG93ZWRcbiAgICAgICAgbGV0IGZvcm1hdHRlZCA9IGludGVnZXJfcGFydDtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5hbGxvd19kZWNpbWFscyAmJiBkZWNpbWFsX3BhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gTGltaXQgdG8gMiBkZWNpbWFsIHBsYWNlc1xuICAgICAgICAgICAgZGVjaW1hbF9wYXJ0ID0gZGVjaW1hbF9wYXJ0LnN1YnN0cigwLCAyKTtcbiAgICAgICAgICAgIGZvcm1hdHRlZCArPSAnLicgKyBkZWNpbWFsX3BhcnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VycmVuY3kgc3ltYm9sIGlmIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zaG93X3N5bWJvbCkge1xuICAgICAgICAgICAgZm9ybWF0dGVkID0gdGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbCArIGZvcm1hdHRlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXR0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdCBudW1lcmljIHZhbHVlIGZyb20gZm9ybWF0dGVkIHN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXR0ZWQgLSBGb3JtYXR0ZWQgY3VycmVuY3kgc3RyaW5nXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQ2xlYW4gbnVtZXJpYyB2YWx1ZSAoZGlnaXRzIGFuZCBkZWNpbWFsIG9ubHkpXG4gICAgICovXG4gICAgX2dldF9udW1lcmljX3ZhbHVlKGZvcm1hdHRlZCkge1xuICAgICAgICBpZiAoIWZvcm1hdHRlZCkge1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGN1cnJlbmN5IHN5bWJvbCBhbmQgY29tbWFzXG4gICAgICAgIGxldCBjbGVhbmVkID0gZm9ybWF0dGVkLnJlcGxhY2UoL1teMC05Ll0vZywgJycpO1xuXG4gICAgICAgIC8vIEVuc3VyZSBvbmx5IG9uZSBkZWNpbWFsIHBvaW50XG4gICAgICAgIGNvbnN0IGRlY2ltYWxfY291bnQgPSAoY2xlYW5lZC5tYXRjaCgvXFwuL2cpIHx8IFtdKS5sZW5ndGg7XG4gICAgICAgIGlmIChkZWNpbWFsX2NvdW50ID4gMSkge1xuICAgICAgICAgICAgLy8gS2VlcCBvbmx5IGZpcnN0IGRlY2ltYWwgcG9pbnRcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0X2RlY2ltYWwgPSBjbGVhbmVkLmluZGV4T2YoJy4nKTtcbiAgICAgICAgICAgIGNsZWFuZWQgPSBjbGVhbmVkLnN1YnN0cigwLCBmaXJzdF9kZWNpbWFsICsgMSkgKyBjbGVhbmVkLnN1YnN0cihmaXJzdF9kZWNpbWFsICsgMSkucmVwbGFjZSgvXFwuL2csICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjbGVhbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCB0aGUgY3VycmVuY3kgdmFsdWVcbiAgICAgKiBHZXR0ZXIgcmV0dXJucyBudW1lcmljIHN0cmluZyAobm8gY29tbWFzLCBubyBzeW1ib2wpXG4gICAgICogU2V0dGVyIGFjY2VwdHMgYW55dGhpbmcgYW5kIGZvcm1hdHMgd2l0aCBjb21tYXMvc3ltYm9sXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV1cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gcmV0dXJuIG51bWVyaWMgdmFsdWUgb25seVxuICAgICAgICAgICAgY29uc3QgcmF3ID0gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGZvcm1hdCBhbmQgZGlzcGxheVxuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENsZWFuIHRoZSBpbnB1dCB2YWx1ZVxuICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHN0cih2YWx1ZSkpO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X2N1cnJlbmN5KG51bWVyaWMpO1xuXG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSBmb3JtYXR0ZWQ7XG4gICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIC8vIEhhbmRsZSBrZXlkb3duIHRvIGludGVyY2VwdCBiYWNrc3BhY2UgYXQgZW5kIG9mIHN0cmluZ1xuICAgICAgICAkaW5wdXQub24oJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3ID0gJGlucHV0LnZhbCgpO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGhhbmRsZSBiYWNrc3BhY2Uga2V5XG4gICAgICAgICAgICBpZiAoZS5rZXkgIT09ICdCYWNrc3BhY2UnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBpbnB1dF9lbGVtZW50ID0gJGlucHV0WzBdO1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX3BvcyA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfZW5kID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25FbmQ7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZV9sZW5ndGggPSByYXcubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGhhbmRsZSBpZiBjdXJzb3IgaXMgYXQgdGhlIGVuZCBhbmQgbm8gc2VsZWN0aW9uXG4gICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA9PT0gdmFsdWVfbGVuZ3RoICYmIGN1cnNvcl9wb3MgPT09IGN1cnNvcl9lbmQpIHtcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjaGFyYWN0ZXIgYmVmb3JlIGN1cnNvciBpcyBub24tbnVtZXJpY1xuICAgICAgICAgICAgICAgIGlmIChjdXJzb3JfcG9zID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyX2JlZm9yZSA9IHJhdy5jaGFyQXQoY3Vyc29yX3BvcyAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIS9bMC05XS8udGVzdChjaGFyX2JlZm9yZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoYXJhY3RlciBiZWZvcmUgY3Vyc29yIGlzIG5vdCBhIGRpZ2l0XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWxldGUgdGhlIGxhc3QgZGlnaXQgaW5zdGVhZFxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChudW1lcmljLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgbGFzdCBjaGFyYWN0ZXIgZnJvbSBudW1lcmljIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X251bWVyaWMgPSBudW1lcmljLnN1YnN0cigwLCBudW1lcmljLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShuZXdfbnVtZXJpYyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGxhY2UgY3Vyc29yIGF0IGVuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdfbGVuZ3RoID0gJGlucHV0LnZhbCgpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZShuZXdfbGVuZ3RoLCBuZXdfbGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGlucHV0IGV2ZW50IGZvciBsaXZlIGZvcm1hdHRpbmdcbiAgICAgICAgJGlucHV0Lm9uKCdpbnB1dCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0X2VsZW1lbnQgPSAkaW5wdXRbMF07XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlX2xlbmd0aCA9IHJhdy5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgYXBwbHkgbGl2ZSBmb3JtYXR0aW5nIGlmIGN1cnNvciBpcyBhdCB0aGUgZW5kXG4gICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA9PT0gdmFsdWVfbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBudW1lcmljIHZhbHVlXG4gICAgICAgICAgICAgICAgbGV0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuXG4gICAgICAgICAgICAgICAgLy8gTGltaXQgZGVjaW1hbCBwbGFjZXMgdG8gMiBpZiBkZWNpbWFscyBhbGxvd2VkXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5hbGxvd19kZWNpbWFscykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0cyA9IG51bWVyaWMuc3BsaXQoJy4nKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRzWzFdICYmIHBhcnRzWzFdLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bWVyaWMgPSBwYXJ0c1swXSArICcuJyArIHBhcnRzWzFdLnN1YnN0cigwLCAyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEZvcm1hdCB0aGUgbnVtZXJpYyB2YWx1ZVxuICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShudW1lcmljKTtcbiAgICAgICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEN1cnNvciBpcyBub3QgYXQgZW5kIC0gdXNlciBpcyBlZGl0aW5nIGluIHRoZSBtaWRkbGVcbiAgICAgICAgICAgICAgICAvLyBEb24ndCBmb3JtYXQsIGp1c3QgY2xlYW4gaW52YWxpZCBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG5cbiAgICAgICAgICAgICAgICAvLyBPbmx5IHVwZGF0ZSBpZiB3ZSByZW1vdmVkIGludmFsaWQgY2hhcmFjdGVyc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYykgIT09IHJhdykge1xuICAgICAgICAgICAgICAgICAgICAvLyBQcmVzZXJ2ZSBqdXN0IHRoZSBudW1lcmljIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3ltYm9sX29mZnNldCA9IHRoaXMuYXJncy5zaG93X3N5bWJvbCA/IHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wubGVuZ3RoIDogMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZCA9ICh0aGlzLmFyZ3Muc2hvd19zeW1ib2wgPyB0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sIDogJycpICsgbnVtZXJpYztcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xlYW5lZCAhPT0gcmF3KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkaW5wdXQudmFsKGNsZWFuZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBjdXJzb3IgcG9zaXRpb24gKGFwcHJveGltYXRlbHkpXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdfY3Vyc29yID0gTWF0aC5taW4oY3Vyc29yX3BvcywgY2xlYW5lZC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZShuZXdfY3Vyc29yLCBuZXdfY3Vyc29yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGJsdXIgdG8gcmVmb3JtYXQgd2hlbiBkb25lIGVkaXRpbmdcbiAgICAgICAgJGlucHV0Lm9uKCdibHVyJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3ID0gJGlucHV0LnZhbCgpO1xuXG4gICAgICAgICAgICBpZiAoIXJhdykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVmb3JtYXQgdGhlIGVudGlyZSB2YWx1ZSBvbiBibHVyXG4gICAgICAgICAgICBjb25zdCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShudW1lcmljKTtcbiAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGZvY3VzIHRvIHNlbGVjdCBhbGwgZm9yIGVhc3kgcmVwbGFjZW1lbnRcbiAgICAgICAgJGlucHV0Lm9uKCdmb2N1cycsICgpID0+IHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICRpbnB1dFswXS5zZWxlY3QoKTtcbiAgICAgICAgICAgIH0sIDApO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIGZvcm1hdHRpbmcgaWYgdGhlcmUncyBhIHZhbHVlXG4gICAgICAgIGNvbnN0IGluaXRpYWxfdmFsdWUgPSAkaW5wdXQudmFsKCk7XG4gICAgICAgIGlmIChpbml0aWFsX3ZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnZhbChpbml0aWFsX3ZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8qKlxuICogUGhvbmVfVGV4dF9JbnB1dFxuICpcbiAqIEV4dGVuZHMgVGV4dF9JbnB1dCB0byBwcm92aWRlIGF1dG9tYXRpYyBwaG9uZSBudW1iZXIgZm9ybWF0dGluZy5cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gVVMgTW9kZSAoZGVmYXVsdCk6IEZvcm1hdHMgYXMgKFhYWCkgWFhYLVhYWFggb24gZXZlcnkga2V5c3Ryb2tlXG4gKiAtIEludGVybmF0aW9uYWwgTW9kZTogVHJpZ2dlcmVkIGJ5IHN0YXJ0aW5nIHdpdGggJysnLCBkaXNhYmxlcyBmb3JtYXR0aW5nXG4gKiAtIHZhbCgpIGdldHRlciByZXR1cm5zIGZvcm1hdHRlZCBzdHJpbmcgYXMgZGlzcGxheWVkXG4gKiAtIHZhbCgpIHNldHRlciBhY2NlcHRzIGFueSBmb3JtYXQgYW5kIGRpc3BsYXlzIGFwcHJvcHJpYXRlbHlcbiAqXG4gKiBVc2FnZTpcbiAqICAgPFBob25lX1RleHRfSW5wdXQgJHBsYWNlaG9sZGVyPVwiUGhvbmUgbnVtYmVyXCIgLz5cbiAqXG4gKiBCZWhhdmlvcjpcbiAqIC0gVHlwZSBcIjU1NTEyMzQ1NjdcIiAtPiBkaXNwbGF5cyBcIig1NTUpIDEyMy00NTY3XCIsIHZhbCgpIHJldHVybnMgXCIoNTU1KSAxMjMtNDU2N1wiXG4gKiAtIFR5cGUgXCIrNDQgMjAgNzEyMyA0NTY3XCIgLT4gZGlzcGxheXMgYXMgdHlwZWQsIHZhbCgpIHJldHVybnMgXCIrNDQgMjAgNzEyMyA0NTY3XCJcbiAqIC0gTGVhZGluZyBcIjFcIiBpcyBzdHJpcHBlZDogXCIxNTU1MTIzNDU2N1wiIC0+IFwiKDU1NSkgMTIzLTQ1NjdcIlxuICovXG5jbGFzcyBQaG9uZV9UZXh0X0lucHV0IGV4dGVuZHMgVGV4dF9JbnB1dCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcbiAgICAgICAgdGhpcy5faXNfaW50ZXJuYXRpb25hbCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGlucHV0IGlzIGluIGludGVybmF0aW9uYWwgbW9kZSAoc3RhcnRzIHdpdGggKylcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBfY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAmJiBzdHIodmFsdWUpLmNoYXJBdCgwKSA9PT0gJysnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcm1hdCBVUyBwaG9uZSBudW1iZXIgYXMgKFhYWCkgWFhYLVhYWFhcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZGlnaXRzIC0gQ2xlYW4gbnVtZXJpYyBzdHJpbmcgKHNob3VsZCBiZSAxMCBkaWdpdHMgb3IgbGVzcyBhZnRlciBwcm9jZXNzaW5nKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEZvcm1hdHRlZCBwaG9uZSBudW1iZXJcbiAgICAgKi9cbiAgICBfZm9ybWF0X3VzX3Bob25lKGRpZ2l0cykge1xuICAgICAgICAvLyBGb3JtYXQgYmFzZWQgb24gbGVuZ3RoIChhc3N1bWVzIGRpZ2l0cyBhcmUgYWxyZWFkeSBjbGVhbmVkIGFuZCBsaW1pdGVkIHRvIDEwKVxuICAgICAgICBpZiAoZGlnaXRzLmxlbmd0aCA+PSA2KSB7XG4gICAgICAgICAgICAvLyAoWFhYKSBYWFgtWFhYWFxuICAgICAgICAgICAgcmV0dXJuICcoJyArIGRpZ2l0cy5zdWJzdHIoMCwgMykgKyAnKSAnICsgZGlnaXRzLnN1YnN0cigzLCAzKSArICctJyArIGRpZ2l0cy5zdWJzdHIoNik7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICAvLyAoWFhYKSBYWFhcbiAgICAgICAgICAgIHJldHVybiAnKCcgKyBkaWdpdHMuc3Vic3RyKDAsIDMpICsgJykgJyArIGRpZ2l0cy5zdWJzdHIoMyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIChYWFxuICAgICAgICAgICAgcmV0dXJuICcoJyArIGRpZ2l0cztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkaWdpdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBwaG9uZSBudW1iZXJcbiAgICAgKiBHZXR0ZXIgcmV0dXJucyBmb3JtYXR0ZWQgdmFsdWUgYXMgZGlzcGxheWVkICh3aXRoIHBhcmVucywgZGFzaGVzLCBldGMpXG4gICAgICogU2V0dGVyIGFjY2VwdHMgYW55dGhpbmcgYW5kIGZvcm1hdHMgYXBwcm9wcmlhdGVseVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHJldHVybiB0aGUgZm9ybWF0dGVkIHZhbHVlIGFzIGRpc3BsYXllZFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpIHx8ICcnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gZm9ybWF0IGFuZCBkaXNwbGF5XG4gICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc3RyX3ZhbHVlID0gc3RyKHZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX2NoZWNrX2ludGVybmF0aW9uYWxfbW9kZShzdHJfdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gSW50ZXJuYXRpb25hbCBtb2RlIC0gbm8gZm9ybWF0dGluZ1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHN0cl92YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKHN0cl92YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBVUyBtb2RlIC0gY2xlYW4gZGlnaXRzIGFuZCBmb3JtYXRcbiAgICAgICAgICAgICAgICBjb25zdCBkaWdpdHMgPSBzdHJfdmFsdWUucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICAgICAgICAgIC8vIERldGVybWluZSB3aGljaCBkaWdpdHMgdG8gZm9ybWF0XG4gICAgICAgICAgICAgICAgbGV0IGRpZ2l0c190b19mb3JtYXQ7XG4gICAgICAgICAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPT09IDExICYmIGRpZ2l0cy5jaGFyQXQoMCkgPT09ICcxJyAmJiAvWzItOV0vLnRlc3QoZGlnaXRzLmNoYXJBdCgxKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXAgVVMgY291bnRyeSBjb2RlXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRha2UgZmlyc3QgMTBcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cy5zdWJzdHIoMCwgMTApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVzZSBhcy1pc1xuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF91c19waG9uZShkaWdpdHNfdG9fZm9ybWF0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSBmb3JtYXR0ZWQ7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICBsZXQgX2xhc3RfY3Vyc29yX3Bvc2l0aW9uID0gbnVsbDtcblxuICAgICAgICAvLyBIYW5kbGUga2V5ZG93biB0byBpbnRlcmNlcHQgYmFja3NwYWNlIGF0IGVuZCBvZiBzdHJpbmdcbiAgICAgICAgJGlucHV0Lm9uKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgLy8gU2tpcCBpZiBpbnRlcm5hdGlvbmFsIG1vZGVcbiAgICAgICAgICAgIGlmICh0aGlzLl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUocmF3KSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgYmFja3NwYWNlIGtleVxuICAgICAgICAgICAgaWYgKGUua2V5ICE9PSAnQmFja3NwYWNlJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaW5wdXRfZWxlbWVudCA9ICRpbnB1dFswXTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9wb3MgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX2VuZCA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uRW5kO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVfbGVuZ3RoID0gcmF3Lmxlbmd0aDtcblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgaWYgY3Vyc29yIGlzIGF0IHRoZSBlbmQgYW5kIG5vIHNlbGVjdGlvblxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCAmJiBjdXJzb3JfcG9zID09PSBjdXJzb3JfZW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm9uLW51bWVyaWNcbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcl9iZWZvcmUgPSByYXcuY2hhckF0KGN1cnNvcl9wb3MgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEvWzAtOV0vLnRlc3QoY2hhcl9iZWZvcmUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGFyYWN0ZXIgYmVmb3JlIGN1cnNvciBpcyBub3QgYSBkaWdpdFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBsYXN0IGRpZ2l0IGluc3RlYWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gcmF3LnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlnaXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdfZGlnaXRzID0gZGlnaXRzLnN1YnN0cigwLCBkaWdpdHMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X3VzX3Bob25lKG5ld19kaWdpdHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIGN1cnNvciBhdCBlbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2xlbmd0aCA9ICRpbnB1dC52YWwoKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3X2xlbmd0aCwgbmV3X2xlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBpbnB1dCBldmVudCBmb3IgbGl2ZSBmb3JtYXR0aW5nXG4gICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUocmF3KSkge1xuICAgICAgICAgICAgICAgIC8vIEludGVybmF0aW9uYWwgbW9kZSAtIGFsbG93IGFueXRoaW5nXG4gICAgICAgICAgICAgICAgdGhpcy5faXNfaW50ZXJuYXRpb25hbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgLy8gTm8gZm9ybWF0dGluZywgbm8gcmVzdHJpY3Rpb25zXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBVUyBtb2RlXG4gICAgICAgICAgICB0aGlzLl9pc19pbnRlcm5hdGlvbmFsID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGNvbnN0IGlucHV0X2VsZW1lbnQgPSAkaW5wdXRbMF07XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlX2xlbmd0aCA9IHJhdy5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgYXBwbHkgbGl2ZSBmb3JtYXR0aW5nIGlmIGN1cnNvciBpcyBhdCB0aGUgZW5kXG4gICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA9PT0gdmFsdWVfbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFueSBub24tZGlnaXQsIG5vbi1mb3JtYXR0aW5nIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkID0gcmF3LnJlcGxhY2UoL1teMC05XFxzXFwtKCldL2csICcnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaWdpdHMgPSBjbGVhbmVkLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hpY2ggZGlnaXRzIHRvIGZvcm1hdFxuICAgICAgICAgICAgICAgIGxldCBkaWdpdHNfdG9fZm9ybWF0O1xuXG4gICAgICAgICAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPT09IDExICYmIGRpZ2l0cy5jaGFyQXQoMCkgPT09ICcxJyAmJiAvWzItOV0vLnRlc3QoZGlnaXRzLmNoYXJBdCgxKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRXhhY3RseSAxMSBkaWdpdHMgc3RhcnRpbmcgd2l0aCBcIjFcIiBmb2xsb3dlZCBieSB2YWxpZCBhcmVhIGNvZGUgZGlnaXQgKDItOSlcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIFVTIGNvdW50cnkgY29kZSAtIHN0cmlwIHRoZSBsZWFkaW5nIDFcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cy5zdWJzdHIoMSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaWdpdHMubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTW9yZSB0aGFuIDEwIGRpZ2l0cyAtIGp1c3QgdGFrZSB0aGUgZmlyc3QgMTAgYW5kIGlnbm9yZSB0aGUgcmVzdFxuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigwLCAxMCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTAgb3IgZmV3ZXIgZGlnaXRzIC0gdXNlIGFzLWlzXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gRm9ybWF0IHRoZSBkaWdpdHNcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfdXNfcGhvbmUoZGlnaXRzX3RvX2Zvcm1hdCk7XG4gICAgICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBDdXJzb3IgaXMgbm90IGF0IGVuZCAtIHVzZXIgaXMgZWRpdGluZyBpbiB0aGUgbWlkZGxlXG4gICAgICAgICAgICAgICAgLy8gRG9uJ3QgZm9ybWF0LCBqdXN0IGNsZWFuIGludmFsaWQgY2hhcmFjdGVyc1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuZWQgPSByYXcucmVwbGFjZSgvW14wLTlcXHNcXC0oKV0vZywgJycpO1xuICAgICAgICAgICAgICAgIGlmIChjbGVhbmVkICE9PSByYXcpIHtcbiAgICAgICAgICAgICAgICAgICAgJGlucHV0LnZhbChjbGVhbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBjdXJzb3IgcG9zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgaW5wdXRfZWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZShjdXJzb3JfcG9zLCBjdXJzb3JfcG9zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBibHVyIHRvIHJlZm9ybWF0IHdoZW4gZG9uZSBlZGl0aW5nXG4gICAgICAgICRpbnB1dC5vbignYmx1cicsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgLy8gU2tpcCBpZiBpbnRlcm5hdGlvbmFsIG1vZGUgb3IgZW1wdHlcbiAgICAgICAgICAgIGlmICh0aGlzLl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUocmF3KSB8fCAhcmF3KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWZvcm1hdCB0aGUgZW50aXJlIHZhbHVlIG9uIGJsdXJcbiAgICAgICAgICAgIGNvbnN0IGRpZ2l0cyA9IHJhdy5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hpY2ggZGlnaXRzIHRvIGZvcm1hdFxuICAgICAgICAgICAgbGV0IGRpZ2l0c190b19mb3JtYXQ7XG5cbiAgICAgICAgICAgIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiBkaWdpdHMuY2hhckF0KDApID09PSAnMScgJiYgL1syLTldLy50ZXN0KGRpZ2l0cy5jaGFyQXQoMSkpKSB7XG4gICAgICAgICAgICAgICAgLy8gRXhhY3RseSAxMSBkaWdpdHMgc3RhcnRpbmcgd2l0aCBcIjFcIiBmb2xsb3dlZCBieSB2YWxpZCBhcmVhIGNvZGUgZGlnaXQgKDItOSlcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgVVMgY291bnRyeSBjb2RlIC0gc3RyaXAgdGhlIGxlYWRpbmcgMVxuICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkaWdpdHMubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgICAgICAvLyBNb3JlIHRoYW4gMTAgZGlnaXRzIC0ganVzdCB0YWtlIHRoZSBmaXJzdCAxMFxuICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDAsIDEwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gMTAgb3IgZmV3ZXIgZGlnaXRzIC0gdXNlIGFzLWlzXG4gICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X3VzX3Bob25lKGRpZ2l0c190b19mb3JtYXQpO1xuICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIGZvcm1hdHRpbmcgaWYgdGhlcmUncyBhIHZhbHVlXG4gICAgICAgIGNvbnN0IGluaXRpYWxfdmFsdWUgPSAkaW5wdXQudmFsKCk7XG4gICAgICAgIGlmIChpbml0aWFsX3ZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnZhbChpbml0aWFsX3ZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFN0YXRlX1NlbGVjdF9JbnB1dCBleHRlbmRzIEFqYXhfU2VsZWN0X0lucHV0IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIGNvdW50cnkgY29kZSBmcm9tIGFyZ3Mgb3IgZGVmYXVsdCB0byBVU1xuICAgICAgICBpZiAoIXRoaXMuZGF0YS5jb3VudHJ5X2NvZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgPSB0aGlzLmFyZ3MuY291bnRyeV9jb2RlIHx8ICdVUyc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb2FkIHN0YXRlcyB2aWEgQWpheCBlbmRwb2ludCBpZiBjb3VudHJ5IGNvZGUgaXMgc2V0XG4gICAgICAgIGlmICh0aGlzLmRhdGEuY291bnRyeV9jb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IGF3YWl0IFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLnN0YXRlcyh7IGNvdW50cnk6IHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgfSk7XG5cbiAgICAgICAgICAgIC8vIElmIG5vIHN0YXRlcyByZXR1cm5lZCwgYWRkIE4vQSBvcHRpb25cbiAgICAgICAgICAgIGlmICghdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgfHwgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbeyB2YWx1ZTogJ04vQScsIGxhYmVsOiAnTi9BJyB9XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIFNldCBkZWZhdWx0IHBsYWNlaG9sZGVyIGlmIG5vdCBwcm92aWRlZFxuICAgICAgICBpZiAoIXRoaXMuYXJncy5wbGFjZWhvbGRlcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLnBsYWNlaG9sZGVyID0gJ1NlbGVjdCBTdGF0ZS4uLic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbml0aWFsaXplIGNvdW50cnkgY29kZSBpbiBkYXRhXG4gICAgICAgIHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgPSB0aGlzLmFyZ3MuY291bnRyeV9jb2RlIHx8ICcnO1xuXG4gICAgICAgIC8vIENhY2hlIGZvciBzZWxlY3RlZCBzdGF0ZSBwZXIgY291bnRyeSBjb2RlXG4gICAgICAgIHRoaXMuX3N0YXRlX2NhY2hlID0ge307XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gaW5pdGlhbGl6ZSBBamF4X1NlbGVjdF9JbnB1dFxuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gaW5pdGlhbGl6ZSBUb20gU2VsZWN0XG4gICAgICAgIHN1cGVyLm9uX3JlYWR5KCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBOL0EgY2FzZSAobm8gc3RhdGVzIGZvciBjb3VudHJ5KVxuICAgICAgICBjb25zdCBpc19uYSA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlc1swXS52YWx1ZSA9PT0gJ04vQSc7XG5cbiAgICAgICAgLy8gRGlzYWJsZSBpZiBubyBjb3VudHJ5IGNvZGUgb3IgTi9BIGNhc2VcbiAgICAgICAgaWYgKCghdGhpcy5kYXRhLmNvdW50cnlfY29kZSB8fCBpc19uYSkgJiYgdGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZGlzYWJsZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHZhbHVlIHRvIE4vQSBpZiB0aGF0J3MgdGhlIG9ubHkgb3B0aW9uXG4gICAgICAgIGlmIChpc19uYSkge1xuICAgICAgICAgICAgdGhpcy52YWwoJ04vQScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGNvdW50cnkgY29kZSBhbmQgcmVsb2FkIHN0YXRlIGxpc3RcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY291bnRyeV9jb2RlIC0gSVNPIGNvdW50cnkgY29kZSAoZS5nLiwgJ1VTJywgJ0NBJylcbiAgICAgKi9cbiAgICBhc3luYyBzZXRfY291bnRyeV9jb2RlKGNvdW50cnlfY29kZSkge1xuICAgICAgICAvLyBDYWNoZSB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdGhlIGN1cnJlbnQgY291bnRyeSBiZWZvcmUgc3dpdGNoaW5nXG4gICAgICAgIGNvbnN0IGN1cnJlbnRfY291bnRyeSA9IHRoaXMuZGF0YS5jb3VudHJ5X2NvZGU7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRfdmFsdWUgPSB0aGlzLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudF9jb3VudHJ5ICYmIGN1cnJlbnRfdmFsdWUgJiYgY3VycmVudF92YWx1ZSAhPT0gJ04vQScpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlX2NhY2hlW2N1cnJlbnRfY291bnRyeV0gPSBjdXJyZW50X3ZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIGNvdW50cnkgY29kZVxuICAgICAgICB0aGlzLmRhdGEuY291bnRyeV9jb2RlID0gY291bnRyeV9jb2RlO1xuXG4gICAgICAgIC8vIERpc2FibGUgdGhlIHNlbGVjdG9yIHdoaWxlIGxvYWRpbmdcbiAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRpc2FibGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIExvYWQgbmV3IHN0YXRlIGxpc3RcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gYXdhaXQgUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIuc3RhdGVzKHsgY291bnRyeTogY291bnRyeV9jb2RlIH0pO1xuXG4gICAgICAgICAgICAvLyBSYWNlIGNvbmRpdGlvbiBjaGVjazogdmVyaWZ5IGNvdW50cnkgaGFzbid0IGNoYW5nZWQgZHVyaW5nIHRoZSByZXF1ZXN0XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhLmNvdW50cnlfY29kZSAhPT0gY291bnRyeV9jb2RlKSB7XG4gICAgICAgICAgICAgICAgLy8gQ291bnRyeSBjaGFuZ2VkIHdoaWxlIHJlcXVlc3Qgd2FzIGluIGZsaWdodCAtIGlnbm9yZSB0aGlzIHJlc3BvbnNlXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBzdGF0ZXMgcmV0dXJuZWQsIGFkZCBOL0Egb3B0aW9uXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzIHx8IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW3sgdmFsdWU6ICdOL0EnLCBsYWJlbDogJ04vQScgfV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlLXJlbmRlciB0aGUgd2lkZ2V0IHdpdGggbmV3IHN0YXRlc1xuICAgICAgICAgICAgdGhpcy5yZWRyYXcoKTtcblxuICAgICAgICAgICAgLy8gUmUtaW5pdGlhbGl6ZSBUb20gU2VsZWN0IGFmdGVyIHJlZHJhd1xuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlLXJ1biBvbl9yZWFkeSB0byBzZXQgdXAgVG9tIFNlbGVjdCBhZ2FpblxuICAgICAgICAgICAgdGhpcy5vbl9yZWFkeSgpO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIE4vQSBjYXNlXG4gICAgICAgICAgICBjb25zdCBpc19uYSA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlc1swXS52YWx1ZSA9PT0gJ04vQSc7XG5cbiAgICAgICAgICAgIGlmIChpc19uYSkge1xuICAgICAgICAgICAgICAgIC8vIFNldCB0byBOL0EgYW5kIGtlZXAgZGlzYWJsZWRcbiAgICAgICAgICAgICAgICB0aGlzLnZhbCgnTi9BJyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZGlzYWJsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHJlc3RvcmUgY2FjaGVkIHZhbHVlIGZvciB0aGlzIGNvdW50cnlcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZWRfdmFsdWUgPSB0aGlzLl9zdGF0ZV9jYWNoZVtjb3VudHJ5X2NvZGVdO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlZF92YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZV9leGlzdHMgPSB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5zb21lKChvcHQpID0+ICh0eXBlb2Ygb3B0ID09PSAnb2JqZWN0JyA/IG9wdC52YWx1ZSA6IG9wdCkgPT09IGNhY2hlZF92YWx1ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlX2V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWwoY2FjaGVkX3ZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsKCcnKTsgLy8gQ2xlYXIgaWYgY2FjaGVkIHZhbHVlIG5vdCBpbiBuZXcgbGlzdFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWwoJycpOyAvLyBObyBjYWNoZWQgdmFsdWUgLSBsZWF2ZSBlbXB0eVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEVuYWJsZSB0aGUgd2lkZ2V0IG5vdyB0aGF0IHdlIGhhdmUgYSBjb3VudHJ5IHdpdGggc3RhdGVzXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZW5hYmxlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgc3RhdGVzIGZvciBjb3VudHJ5OicsIGNvdW50cnlfY29kZSwgZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbXTtcblxuICAgICAgICAgICAgLy8gUmUtZW5hYmxlIGV2ZW4gb24gZXJyb3JcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZW5hYmxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSB2YWwoKSB0byB1cGRhdGUgY2FjaGUgd2hlbiB1c2VyIG1hbnVhbGx5IHNlbGVjdHMgYSBzdGF0ZVxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gdXNlIHBhcmVudCBpbXBsZW1lbnRhdGlvblxuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZhbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gdXBkYXRlIGNhY2hlIGFuZCBjYWxsIHBhcmVudFxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgJiYgdmFsdWUgJiYgdmFsdWUgIT09ICdOL0EnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGVfY2FjaGVbdGhpcy5kYXRhLmNvdW50cnlfY29kZV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBlci52YWwodmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgQ291bnRyeV9TZWxlY3RfSW5wdXQgZXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBjb3VudHJpZXMgdmlhIEFqYXggZW5kcG9pbnQgaWYgZGF0YSBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBhd2FpdCBSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci5jb3VudHJpZXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFVzZSBwYXJlbnQgb25fbG9hZCBmb3IgY3VzdG9tIGRhdGEgZW5kcG9pbnRzXG4gICAgICAgICAgICBhd2FpdCBzdXBlci5vbl9sb2FkKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW9yZGVyIHNlbGVjdF92YWx1ZXMgdG8gcHV0IGRlZmF1bHQgY291bnRyeSBmaXJzdCBpbiB0aGUgbGlzdFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRlZmF1bHRfY291bnRyeSAmJiB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyAmJiBpc19hcnJheSh0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcykpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRfY291bnRyeV9jb2RlID0gdGhpcy5hcmdzLmRlZmF1bHRfY291bnRyeTtcblxuICAgICAgICAgICAgLy8gRmluZCB0aGUgZGVmYXVsdCBjb3VudHJ5IGluIHRoZSBhcnJheVxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdF9jb3VudHJ5X2luZGV4ID0gdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMuZmluZEluZGV4KFxuICAgICAgICAgICAgICAgIG9wdCA9PiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcgPyBvcHQudmFsdWUgOiBvcHQpID09PSBkZWZhdWx0X2NvdW50cnlfY29kZVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKGRlZmF1bHRfY291bnRyeV9pbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgaXQgZnJvbSBpdHMgY3VycmVudCBwb3NpdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IFtkZWZhdWx0X2NvdW50cnldID0gdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMuc3BsaWNlKGRlZmF1bHRfY291bnRyeV9pbmRleCwgMSk7XG5cbiAgICAgICAgICAgICAgICAvLyBBZGQgaXQgdG8gdGhlIGJlZ2lubmluZ1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLnVuc2hpZnQoZGVmYXVsdF9jb3VudHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gU2V0IGRlZmF1bHQgcGxhY2Vob2xkZXIgaWYgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgPSAnU2VsZWN0IENvdW50cnkuLi4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gaW5pdGlhbGl6ZSBBamF4X1NlbGVjdF9JbnB1dFxuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcblxuICAgICAgICAvLyBIYW5kbGUgZGVmYXVsdCBjb3VudHJ5IHZhbHVlXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGVmYXVsdF9jb3VudHJ5ICYmICF0aGlzLmRhdGEudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHRoaXMuYXJncy5kZWZhdWx0X2NvdW50cnk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gaW5pdGlhbGl6ZSBUb20gU2VsZWN0XG4gICAgICAgIHN1cGVyLm9uX3JlYWR5KCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIHN0YXRlIHNlbGVjdG9yIHdpdGggaW5pdGlhbC9kZWZhdWx0IGNvdW50cnlcbiAgICAgICAgdGhpcy5fdXBkYXRlX3N0YXRlX3NlbGVjdG9yKCk7XG5cbiAgICAgICAgLy8gTGlzdGVuIGZvciBjb3VudHJ5IGNoYW5nZXMgYW5kIHVwZGF0ZSBzdGF0ZSBzZWxlY3RvclxuICAgICAgICBpZiAodGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3Qub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVfc3RhdGVfc2VsZWN0b3IoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmluZCBTdGF0ZV9TZWxlY3RfSW5wdXQgc2libGluZyBhbmQgdXBkYXRlIGl0cyBjb3VudHJ5IGNvZGVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF91cGRhdGVfc3RhdGVfc2VsZWN0b3IoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRfY291bnRyeSA9IHRoaXMudmFsKCk7XG5cbiAgICAgICAgLy8gRmluZCBTdGF0ZV9TZWxlY3RfSW5wdXQgY29tcG9uZW50IHVzaW5nIGNsb3Nlc3Rfc2libGluZ1xuICAgICAgICBjb25zdCBzdGF0ZV9jb21wb25lbnQgPSB0aGlzLiQuY2xvc2VzdF9zaWJsaW5nKCcuU3RhdGVfU2VsZWN0X0lucHV0JykuY29tcG9uZW50KCk7XG5cbiAgICAgICAgaWYgKHN0YXRlX2NvbXBvbmVudCAmJiB0eXBlb2Ygc3RhdGVfY29tcG9uZW50LnNldF9jb3VudHJ5X2NvZGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlX2NvbXBvbmVudC5zZXRfY291bnRyeV9jb2RlKGN1cnJlbnRfY291bnRyeSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFByb2ZpbGVfUGhvdG9fSW5wdXRcbiAqXG4gKiBQcm9maWxlIHBob3RvIHVwbG9hZCB3aWRnZXQgd2l0aCB0aHVtYm5haWwgZGlzcGxheSBhbmQgdXBsb2FkIGhhbmRsaW5nLlxuICogU2VlIHByb2ZpbGVfcGhvdG9faW5wdXQuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBIYW5kbGUgZmlsZSBzZWxlY3Rpb24gYW5kIHVwbG9hZFxuICogLSBVcGRhdGUgdGh1bWJuYWlsIG9uIHN1Y2Nlc3NmdWwgdXBsb2FkXG4gKiAtIE1hbmFnZSBsb2FkaW5nIHN0YXRlIHdpdGggc3Bpbm5lclxuICogLSBQcm92aWRlIHZhbCgpIGdldHRlci9zZXR0ZXIgZm9yIGF0dGFjaG1lbnQga2V5XG4gKiAtIEhhbmRsZSByZW1vdmUgYnV0dG9uIGZ1bmN0aW9uYWxpdHlcbiAqL1xuY2xhc3MgUHJvZmlsZV9QaG90b19JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBkYXRhXG4gICAgICAgIHRoaXMuZGF0YS5hdHRhY2htZW50X2tleSA9ICcnO1xuICAgICAgICB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCA9ICcnO1xuICAgIH1cblxuICAgIG9uX3JlbmRlcigpIHtcbiAgICAgICAgLy8gSGFuZGxlIHVwbG9hZCBidXR0b24gY2xpY2sgLSB0cmlnZ2VyIGhpZGRlbiBmaWxlIGlucHV0XG4gICAgICAgIHRoaXMuJGlkKCd1cGxvYWRfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS5jbGljaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgZmlsZSBzZWxlY3Rpb25cbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS5vbignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmlsZSA9IHRoaXMuJGlkKCdmaWxlX2lucHV0JylbMF0uZmlsZXNbMF07XG4gICAgICAgICAgICBpZiAoIWZpbGUpIHJldHVybjtcblxuICAgICAgICAgICAgdGhpcy51cGxvYWRfcGhvdG8oZmlsZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSByZW1vdmUgYnV0dG9uXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2hvd19yZW1vdmUpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdyZW1vdmVfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlX3Bob3RvKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCB0aGUgYXR0YWNobWVudCBrZXlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2tleV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgYXR0YWNobWVudCBrZXkgYW5kIHVwZGF0ZXMgdGh1bWJuYWlsXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgYXR0YWNobWVudCBrZXkgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKGtleSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gcmV0dXJuIGF0dGFjaG1lbnQga2V5XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5IHx8ICcnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gc2V0IGF0dGFjaG1lbnQga2V5IGFuZCB1cGRhdGUgdGh1bWJuYWlsXG4gICAgICAgICAgICB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkgPSBrZXkgfHwgJyc7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkpIHtcbiAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSB0aHVtYm5haWwgVVJMIGZyb20gYXR0YWNobWVudCBrZXlcbiAgICAgICAgICAgICAgICBjb25zdCB3aWR0aCA9IHRoaXMuYXJncy53aWR0aCB8fCA5NjtcbiAgICAgICAgICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmFyZ3MuaGVpZ2h0IHx8IDk2O1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS50aHVtYm5haWxfdXJsID0gYC9fdGh1bWJuYWlsLyR7dGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5fS9jb3Zlci8ke3dpZHRofS8ke2hlaWdodH1gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBObyBrZXkgLSBjbGVhciB0aHVtYm5haWxcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCA9ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnUmVyZW5kZXInKTtcbiAgICAgICAgICAgIC8vIFJlLXJlbmRlciB0byBzd2l0Y2ggYmV0d2VlbiBpY29uIGFuZCBpbWFnZVxuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwbG9hZF9waG90byhmaWxlKSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgc2l6ZVxuICAgICAgICBjb25zdCBtYXhfc2l6ZSA9ICh0aGlzLmFyZ3MubWF4X3NpemUgfHwgMikgKiAxMDI0ICogMTAyNDsgLy8gQ29udmVydCBNQiB0byBieXRlc1xuICAgICAgICBpZiAoZmlsZS5zaXplID4gbWF4X3NpemUpIHtcbiAgICAgICAgICAgIGFsZXJ0KGBGaWxlIHNpemUgbXVzdCBiZSBsZXNzIHRoYW4gJHt0aGlzLmFyZ3MubWF4X3NpemUgfHwgMn1NQmApO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS52YWwoJycpOyAvLyBDbGVhciBzZWxlY3Rpb25cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNob3cgc3Bpbm5lciwgZGltIGltYWdlXG4gICAgICAgIHRoaXMuJGlkKCdzcGlubmVyJykucmVtb3ZlQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLiRpZCgncGhvdG8nKS5jc3MoJ29wYWNpdHknLCAnMC4zJyk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIEZvcm1EYXRhIGZvciBmaWxlIHVwbG9hZFxuICAgICAgICBjb25zdCBmb3JtX2RhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgZm9ybV9kYXRhLmFwcGVuZCgnZmlsZScsIGZpbGUpO1xuICAgICAgICBmb3JtX2RhdGEuYXBwZW5kKCdzaXRlX2lkJywgJzEnKTsgLy8gVE9ETzogR2V0IGZyb20gc2Vzc2lvbi9jb25maWdcbiAgICAgICAgLy8gRG8gTk9UIHNldCBmaWxlYWJsZV90eXBlL2ZpbGVhYmxlX2NhdGVnb3J5IC0gZmlsZSB1cGxvYWRzIHVuYXR0YWNoZWRcbiAgICAgICAgLy8gVGhlIHBhcmVudCBmb3JtIHdpbGwgYXNzaWduIGl0IHZpYSBhdHRhY2hfdG8oKSBvbiBzYXZlXG5cbiAgICAgICAgLy8gVXBsb2FkIGZpbGUgdmlhIEFKQVhcbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogJy9fdXBsb2FkJyxcbiAgICAgICAgICAgIHR5cGU6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IGZvcm1fZGF0YSxcbiAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdQcm9maWxlIHBob3RvIHVwbG9hZCBzdWNjZXNzZnVsOicsIHJlc3BvbnNlKTtcblxuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBhdHRhY2htZW50IGtleSAodGhpcyB3aWxsIGFsc28gdXBkYXRlIHRodW1ibmFpbClcbiAgICAgICAgICAgICAgICB0aGlzLnZhbChyZXNwb25zZS5hdHRhY2htZW50LmtleSk7XG5cbiAgICAgICAgICAgICAgICAvLyBIaWRlIHNwaW5uZXIsIHJlc3RvcmUgb3BhY2l0eVxuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdzcGlubmVyJykuYWRkQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdwaG90bycpLmNzcygnb3BhY2l0eScsICcxJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBDbGVhciBmaWxlIGlucHV0IGZvciBmdXR1cmUgdXBsb2Fkc1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykudmFsKCcnKTtcblxuICAgICAgICAgICAgICAgIC8vIFRyaWdnZXIgY2hhbmdlIGV2ZW50IGZvciBmb3JtIHRyYWNraW5nXG4gICAgICAgICAgICAgICAgdGhpcy4kLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiAoeGhyLCBzdGF0dXMsIGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignUHJvZmlsZSBwaG90byB1cGxvYWQgZmFpbGVkOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSZXNwb25zZTonLCB4aHIucmVzcG9uc2VKU09OKTtcblxuICAgICAgICAgICAgICAgIC8vIEhpZGUgc3Bpbm5lciwgcmVzdG9yZSBvcGFjaXR5XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ3NwaW5uZXInKS5hZGRDbGFzcygnZC1ub25lJyk7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ3Bob3RvJykuY3NzKCdvcGFjaXR5JywgJzEnKTtcblxuICAgICAgICAgICAgICAgIC8vIENsZWFyIGZpbGUgaW5wdXRcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpLnZhbCgnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBTaG93IGVycm9yIHRvIHVzZXJcbiAgICAgICAgICAgICAgICBhbGVydCgnVXBsb2FkIGZhaWxlZDogJyArICh4aHIucmVzcG9uc2VKU09OPy5lcnJvciB8fCBlcnJvcikpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdXBkYXRlX3Bob3RvKCkge1xuICAgICAgICAvLyA8JSBpZiAodGhpcy5hcmdzLnNob3dfcmVtb3ZlICYmIHRoaXMuZGF0YS5hdHRhY2htZW50X2tleSkgeyAlPlxuICAgIH1cblxuICAgIHJlbW92ZV9waG90bygpIHtcbiAgICAgICAgLy8gQ2xlYXIgYXR0YWNobWVudCBrZXkgKHNldHMgdG8gcGxhY2Vob2xkZXIpXG4gICAgICAgIHRoaXMudmFsKCcnKTtcblxuICAgICAgICAvLyBUcmlnZ2VyIGNoYW5nZSBldmVudCBmb3IgZm9ybSB0cmFja2luZ1xuICAgICAgICB0aGlzLiQudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgLy8gRm9yIHRlc3RpbmcgLSBzZXQgYSBwbGFjZWhvbGRlciBrZXlcbiAgICAgICAgLy8gSW4gcHJvZHVjdGlvbiwgdGhpcyB3b3VsZCB1c2UgYWN0dWFsIHRlc3QgZGF0YVxuICAgICAgICB0aGlzLnZhbCgnJyk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBSc3hfVGFic1xuICpcbiAqIFRhYiBjb250YWluZXIgY29tcG9uZW50IHdpdGggZm9ybS1hd2FyZSBlcnJvciBoYW5kbGluZyBpbnRlZ3JhdGlvbi5cbiAqIFNlZSByc3hfdGFicy5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIEJ1aWxkcyB0YWIgbmF2aWdhdGlvbiBkeW5hbWljYWxseSBmcm9tIHJlZ2lzdGVyZWQgUnN4X1RhYiBjaGlsZHJlblxuICogLSBNYW5hZ2VzIHRhYiBhY3RpdmF0aW9uIGFuZCBzd2l0Y2hpbmcgYmVoYXZpb3JcbiAqIC0gUGVyc2lzdHMgYWN0aXZlIHRhYiB0byBVUkwgaGFzaCBmb3IgYm9va21hcmtpbmdcbiAqIC0gSW50ZWdyYXRlcyB3aXRoIGZvcm0gdmFsaWRhdGlvbiB0byBzaG93IGVycm9yIGJhZGdlcyBvbiB0YWJzXG4gKiAtIEF1dG8tc3dpdGNoZXMgdG8gZmlyc3QgdGFiIHdpdGggZXJyb3JzIG9uIHZhbGlkYXRpb24gZmFpbHVyZVxuICogLSBQcm92aWRlcyBBUEkgZm9yIHBhcmVudCBmb3JtcyB0byByZXBvcnQgdmFsaWRhdGlvbiBlcnJvcnNcbiAqL1xuY2xhc3MgUnN4X1RhYnMgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHRoaXMudGFicyA9IFtdOyAvLyBSZWdpc3RlcmVkIFJzeF9UYWIgY29tcG9uZW50c1xuICAgICAgICB0aGlzLmFjdGl2ZV90YWJfaWQgPSBudWxsO1xuICAgICAgICB0aGlzLmZvcm0gPSBudWxsO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBGaW5kIHBhcmVudCBmb3JtIGlmIGl0IGV4aXN0c1xuICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLmNsb3Nlc3QoJy5Sc3hfRm9ybScpO1xuXG4gICAgICAgIC8vIEJ1aWxkIHRhYiBuYXZpZ2F0aW9uIGZyb20gcmVnaXN0ZXJlZCB0YWJzXG4gICAgICAgIHRoaXMuX2J1aWxkX25hdigpO1xuXG4gICAgICAgIC8vIFJlc3RvcmUgYWN0aXZlIHRhYiBmcm9tIFVSTCBoYXNoIG9yIGFjdGl2YXRlIGZpcnN0IHRhYlxuICAgICAgICBjb25zdCBoYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2g7XG4gICAgICAgIGlmIChoYXNoKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJfaWQgPSBoYXNoLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVfdGFiKHRhYl9pZCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50YWJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVfdGFiKHRoaXMudGFic1swXS5hcmdzLmlkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBlcnNpc3QgYWN0aXZlIHRhYiB0byBVUkwgaGFzaFxuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgdGhpcy4kaWQoJ25hdicpLm9uKCdjbGljaycsICdhW2RhdGEtYnMtdG9nZ2xlPVwidGFiXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHRhYl9pZCA9ICQoZS5jdXJyZW50VGFyZ2V0KS5kYXRhKCd0YWItaWQnKTtcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gJyMnICsgdGFiX2lkO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZWdpc3Rlcl90YWIodGFiX2NvbXBvbmVudCkge1xuICAgICAgICB0aGlzLnRhYnMucHVzaCh0YWJfY29tcG9uZW50KTtcbiAgICB9XG5cbiAgICBfYnVpbGRfbmF2KCkge1xuICAgICAgICBjb25zdCAkbmF2ID0gdGhpcy4kaWQoJ25hdicpO1xuICAgICAgICAkbmF2LmVtcHR5KCk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnRhYnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHRhYiA9IHRoaXMudGFic1tpXTtcbiAgICAgICAgICAgIGNvbnN0IGlzX2FjdGl2ZSA9IGkgPT09IDAgPyAnYWN0aXZlJyA6ICcnO1xuXG4gICAgICAgICAgICBjb25zdCAkbGkgPSAkKGBcbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJuYXYtaXRlbVwiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJuYXYtbGluayAke2lzX2FjdGl2ZX1cIlxuICAgICAgICAgICAgICAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXG4gICAgICAgICAgICAgICAgICAgICAgIGhyZWY9XCIjJHt0YWIuYXJncy5pZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICBkYXRhLXRhYi1pZD1cIiR7dGFiLmFyZ3MuaWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1zZWxlY3RlZD1cIiR7aSA9PT0gMCA/ICd0cnVlJyA6ICdmYWxzZSd9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgcm9sZT1cInRhYlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgJHt0YWIuYXJncy5pY29uID8gYDxpIGNsYXNzPVwiJHt0YWIuYXJncy5pY29ufVwiPjwvaT4gYCA6ICcnfVxuICAgICAgICAgICAgICAgICAgICAgICAgJHt0YWIuYXJncy5sYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyIG1zLTJcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCIgZGF0YS1lcnJvci1iYWRnZT1cIiR7dGFiLmFyZ3MuaWR9XCI+MDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICBgKTtcblxuICAgICAgICAgICAgJG5hdi5hcHBlbmQoJGxpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFjdGl2YXRlX3RhYih0YWJfaWQpIHtcbiAgICAgICAgLy8gRmluZCB0aGUgdGFiXG4gICAgICAgIGNvbnN0IHRhYiA9IHRoaXMudGFicy5maW5kKCh0KSA9PiB0LmFyZ3MuaWQgPT09IHRhYl9pZCk7XG4gICAgICAgIGlmICghdGFiKSByZXR1cm47XG5cbiAgICAgICAgLy8gUmVtb3ZlIGFjdGl2ZSBzaG93IGZyb20gYWxsIHRhYiBwYW5lc1xuICAgICAgICBmb3IgKGxldCB0IG9mIHRoaXMudGFicykge1xuICAgICAgICAgICAgdC4kLnJlbW92ZUNsYXNzKCdhY3RpdmUgc2hvdycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGFjdGl2ZSBzaG93IHRvIHRoZSBzZWxlY3RlZCB0YWIgcGFuZVxuICAgICAgICB0YWIuJC5hZGRDbGFzcygnYWN0aXZlIHNob3cnKTtcblxuICAgICAgICAvLyBVcGRhdGUgQm9vdHN0cmFwIHRhYiBuYXZpZ2F0aW9uXG4gICAgICAgIHRoaXMuJGlkKCduYXYnKS5maW5kKCdhW2RhdGEtYnMtdG9nZ2xlPVwidGFiXCJdJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCAnZmFsc2UnKTtcbiAgICAgICAgdGhpcy4kaWQoJ25hdicpXG4gICAgICAgICAgICAuZmluZCgnYVtkYXRhLXRhYi1pZD1cIicgKyB0YWJfaWQgKyAnXCJdJylcbiAgICAgICAgICAgIC5hZGRDbGFzcygnYWN0aXZlJylcbiAgICAgICAgICAgIC5hdHRyKCdhcmlhLXNlbGVjdGVkJywgJ3RydWUnKTtcblxuICAgICAgICB0aGlzLmFjdGl2ZV90YWJfaWQgPSB0YWJfaWQ7XG4gICAgfVxuXG4gICAgaGFuZGxlX3ZhbGlkYXRpb25fZXJyb3JzKGVycm9ycykge1xuICAgICAgICAvLyBDb3VudCBlcnJvcnMgcGVyIHRhYlxuICAgICAgICBjb25zdCB0YWJfZXJyb3JzID0ge307XG5cbiAgICAgICAgZm9yIChsZXQgdGFiIG9mIHRoaXMudGFicykge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JfY291bnQgPSB0YWIuY291bnRfZXJyb3JzKGVycm9ycyk7XG4gICAgICAgICAgICB0YWJfZXJyb3JzW3RhYi5hcmdzLmlkXSA9IGVycm9yX2NvdW50O1xuXG4gICAgICAgICAgICAvLyBVcGRhdGUgYmFkZ2VcbiAgICAgICAgICAgIGNvbnN0ICRiYWRnZSA9IHRoaXMuJGlkKCduYXYnKS5maW5kKGBbZGF0YS1lcnJvci1iYWRnZT1cIiR7dGFiLmFyZ3MuaWR9XCJdYCk7XG4gICAgICAgICAgICBpZiAoZXJyb3JfY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgJGJhZGdlLnRleHQoZXJyb3JfY291bnQpLnNob3coKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgJGJhZGdlLmhpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmQgZmlyc3QgdGFiIHdpdGggZXJyb3JzXG4gICAgICAgIGNvbnN0IGZpcnN0X2Vycm9yZWRfdGFiID0gdGhpcy50YWJzLmZpbmQoKHQpID0+IHRhYl9lcnJvcnNbdC5hcmdzLmlkXSA+IDApO1xuXG4gICAgICAgIC8vIFN3aXRjaCB0byBmaXJzdCBlcnJvcmVkIHRhYiBpZiBub3QgY3VycmVudGx5IG9uIGFuIGVycm9yZWQgdGFiXG4gICAgICAgIGlmIChmaXJzdF9lcnJvcmVkX3RhYiAmJiB0YWJfZXJyb3JzW3RoaXMuYWN0aXZlX3RhYl9pZF0gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVfdGFiKGZpcnN0X2Vycm9yZWRfdGFiLmFyZ3MuaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXJfZXJyb3JfYmFkZ2VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnbmF2JykuZmluZCgnW2RhdGEtZXJyb3ItYmFkZ2VdJykuaGlkZSgpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X1RhYlxuICpcbiAqIEluZGl2aWR1YWwgdGFiIHBhbmUgY29tcG9uZW50IHRoYXQgd29ya3Mgd2l0aCBSc3hfVGFicyBmb3IgZm9ybSB2YWxpZGF0aW9uLlxuICogU2VlIHJzeF90YWIuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBBdXRvLXJlZ2lzdGVycyB3aXRoIHBhcmVudCBSc3hfVGFicyBjb21wb25lbnQgb24gY3JlYXRpb25cbiAqIC0gU2V0cyB0YWIgcGFuZSBJRCBhdHRyaWJ1dGUgZnJvbSAkaWQgYXJndW1lbnRcbiAqIC0gRGlzY292ZXJzIGFuZCB0cmFja3MgY2hpbGQgRm9ybV9GaWVsZCBjb21wb25lbnRzXG4gKiAtIENvdW50cyB2YWxpZGF0aW9uIGVycm9ycyB3aXRoaW4gdGhpcyB0YWIncyBmaWVsZHNcbiAqIC0gUHJvdmlkZXMgZXJyb3IgY291bnQgdG8gcGFyZW50IGZvciBiYWRnZSBkaXNwbGF5XG4gKi9cbmNsYXNzIFJzeF9UYWIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBTZXQgdGhlIHRhYiBJRCBkeW5hbWljYWxseSBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoYXQuYXJncy5pZCkge1xuICAgICAgICAgICAgdGhhdC4kLmF0dHIoJ2lkJywgdGhhdC5hcmdzLmlkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmQgcGFyZW50IFJzeF9UYWJzIGFuZCByZWdpc3RlclxuICAgICAgICB0aGF0LnRhYnNfY29udGFpbmVyID0gdGhhdC5jbG9zZXN0KCcuUnN4X1RhYnMnKTtcbiAgICAgICAgaWYgKHRoYXQudGFic19jb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoYXQudGFic19jb250YWluZXIucmVnaXN0ZXJfdGFiKHRoYXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RvcmUgcmVmZXJlbmNlIHRvIGFsbCBGb3JtX0ZpZWxkIGNvbXBvbmVudHMgd2l0aGluIHRoaXMgdGFiXG4gICAgICAgIHRoYXQuZmllbGRzID0gW107XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBGaW5kIGFsbCBGb3JtX0ZpZWxkIGNvbXBvbmVudHMgd2l0aGluIHRoaXMgdGFiXG4gICAgICAgIHRoYXQuJC5maW5kKCcuRm9ybV9GaWVsZCcpLmVhY2goKGluZGV4LCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZF9jb21wb25lbnQgPSAkKGVsZW1lbnQpLmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgaWYgKGZpZWxkX2NvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIHRoYXQuZmllbGRzLnB1c2goZmllbGRfY29tcG9uZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ291bnQgdmFsaWRhdGlvbiBlcnJvcnMgaW4gRm9ybV9GaWVsZCBjb21wb25lbnRzIHdpdGhpbiB0aGlzIHRhYlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBlcnJvcnMgLSBFcnJvciBvYmplY3QgZnJvbSBmb3JtIHZhbGlkYXRpb24ge2ZpZWxkX25hbWU6IGVycm9yX21lc3NhZ2V9XG4gICAgICogQHJldHVybnMge251bWJlcn0gQ291bnQgb2YgZXJyb3JzIGluIHRoaXMgdGFiXG4gICAgICovXG4gICAgY291bnRfZXJyb3JzKGVycm9ycykge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG4gICAgICAgIGxldCBjb3VudCA9IDA7XG5cbiAgICAgICAgZm9yIChsZXQgZmllbGQgb2YgdGhhdC5maWVsZHMpIHtcbiAgICAgICAgICAgIGlmIChlcnJvcnNbZmllbGQuYXJncy5uYW1lXSkge1xuICAgICAgICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBSc3hfRm9ybVxuICpcbiAqIEZvcm0gY29udGFpbmVyIHdpdGggdmFsaWRhdGlvbiwgc3VibWlzc2lvbiwgYW5kIHdpZGdldCB2YWx1ZSBtYW5hZ2VtZW50LlxuICogU2VlIHJzeF9mb3JtLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gUGFyc2VzIGFuZCBzdG9yZXMgaW5pdGlhbCBmb3JtIGRhdGEgZnJvbSAkZGF0YSBhdHRyaWJ1dGUgKEpTT04gb3Igb2JqZWN0KVxuICogLSBEaXNjb3ZlcnMgYW5kIG1hbmFnZXMgY2hpbGQgV2lkZ2V0IGNvbXBvbmVudHMgdmlhIHZhbHMoKSBnZXR0ZXIvc2V0dGVyXG4gKiAtIEhhbmRsZXMgZm9ybSBzdWJtaXNzaW9uIHZpYSBBamF4IHRvIGNvbnRyb2xsZXIvbWV0aG9kIGVuZHBvaW50c1xuICogLSBBcHBsaWVzIHZhbGlkYXRpb24gZXJyb3JzIHRvIGZpZWxkcyB1c2luZyBGb3JtX1V0aWxzXG4gKiAtIEludGVncmF0ZXMgd2l0aCBSc3hfVGFicyBmb3IgdGFiLWF3YXJlIGVycm9yIGhhbmRsaW5nXG4gKiAtIFByb3ZpZGVzIHNlZWQoKSBmdW5jdGlvbmFsaXR5IGZvciBkZWJ1Zy90ZXN0aW5nXG4gKiAtIE1hbmFnZXMgZm9ybSBzdGF0ZSAodmFsdWVzLCBlcnJvcnMpIHRocm91Z2hvdXQgbGlmZWN5Y2xlXG4gKi9cbmNsYXNzIFJzeF9Gb3JtIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLmRhdGEudmFsdWVzID0ge307IC8vIEN1cnJlbnQgZm9ybSB2YWx1ZXMge25hbWU6IHZhbHVlfVxuICAgICAgICB0aGlzLmRhdGEuZXJyb3JzID0ge307IC8vIFZhbGlkYXRpb24gZXJyb3JzIHtuYW1lOiBlcnJvcl9tZXNzYWdlfVxuICAgICAgICB0aGlzLnRhYnMgPSBudWxsOyAvLyBSZWZlcmVuY2UgdG8gUnN4X1RhYnMgY29tcG9uZW50IGlmIHByZXNlbnRcblxuICAgICAgICAvLyBQYXJzZSBpbml0aWFsIGRhdGEgZnJvbSAkZGF0YSBhdHRyaWJ1dGUgKGUuZy4sIGZyb20gJGRhdGE9JGNsaWVudClcbiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmFyZ3MuZGF0YTtcblxuICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIERlY29kZSBIVE1MIGVudGl0aWVzIGJlZm9yZSBwYXJzaW5nIEpTT05cbiAgICAgICAgICAgICAgICAvLyBUaGlzIGhhbmRsZXMgY2FzZXMgd2hlcmUgSlNPTiBpcyBwYXNzZWQgdGhyb3VnaCBCbGFkZSB7ISEgISF9IHN5bnRheFxuICAgICAgICAgICAgICAgIGNvbnN0IGRlY29kZWQgPSAkKCc8dGV4dGFyZWE+JykuaHRtbChkYXRhKS50ZXh0KCk7XG4gICAgICAgICAgICAgICAgZGF0YSA9IGpzb25fZGVjb2RlKGRlY29kZWQpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Zvcm06IEZhaWxlZCB0byBwYXJzZSBkYXRhIEpTT04gc3RyaW5nJywgZSk7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWVzID0gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBWYWxpZGF0ZSB0aGF0IGVycm9yIGNvbnRhaW5lciBleGlzdHNcbiAgICAgICAgaWYgKCF0aGlzLiRpZCgnZXJyb3InKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy4kLmh0bWwoKSk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ1JzeF9Gb3JtIHJlcXVpcmVzIGFuIGVycm9yIGNvbnRhaW5lciB3aXRoICRpZD1cImVycm9yXCIuICcgK1xuICAgICAgICAgICAgICAgICAgICAnQWRkIDxkaXYgJGlkPVwiZXJyb3JcIj48L2Rpdj4gdG8geW91ciBmb3JtIHRlbXBsYXRlIGZvciBkaXNwbGF5aW5nIHZhbGlkYXRpb24gYW5kIGVycm9yIG1lc3NhZ2VzLidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdXAgc2VlZCBidXR0b24gaGFuZGxlciBpZiBpbiBkZWJ1ZyBtb2RlXG4gICAgICAgIGlmICh3aW5kb3cucnN4YXBwLmRlYnVnICYmIHRoaXMuJGlkKCdzZWVkX2J0bicpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICB0aGF0LiRpZCgnc2VlZF9idG4nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5zZWVkKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmQgY2hpbGQgUnN4X1RhYnMgY29tcG9uZW50IGlmIHByZXNlbnQgZm9yIGVycm9yIGhhbmRsaW5nIGludGVncmF0aW9uXG4gICAgICAgIGNvbnN0IHRhYnNfZWwgPSB0aGlzLiQuZmluZCgnLlJzeF9UYWJzJykuZmlyc3QoKTtcbiAgICAgICAgaWYgKHRhYnNfZWwubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGF0LnRhYnMgPSB0YWJzX2VsLmNvbXBvbmVudCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXV0b21hdGljYWxseSB3aXJlIGFsbCBzdWJtaXQgYnV0dG9ucyB0byBjYWxsIGZvcm0gc3VibWl0KClcbiAgICAgICAgdGhpcy4kLmZpbmQoJ2J1dHRvblt0eXBlPVwic3VibWl0XCJdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKHRoaXMpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoYXQuc3VibWl0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTm90aWZ5IGFsbCBmaWVsZHMgdG8gbG9hZCB0aGVpciBpbml0aWFsIHZhbHVlc1xuICAgICAgICAvLyBUaGlzIGhhcHBlbnMgaW4gb25fcmVhZHkgdG8gZW5zdXJlIGFsbCBGb3JtX0ZpZWxkIGNoaWxkcmVuIGFyZSBpbml0aWFsaXplZFxuICAgICAgICB0aGlzLnZhbHModGhpcy5kYXRhLnZhbHVlcyk7XG5cbiAgICAgICAgLy8gSGlkZSBsb2FkaW5nIHNwaW5uZXIgYW5kIHNob3cgZm9ybSBjb250ZW50ICh3aXRob3V0IHJlLXJlbmRlcmluZylcbiAgICAgICAgdGhpcy4kaWQoJ2xvYWRlcicpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Zvcm1fY29udGVudCcpLnNob3coKTtcbiAgICB9XG5cbiAgICAvLyBHZXR0ZXIgb3Igc2V0dGVyIGZvciBhbGwgZm9ybSB2YWx1ZXMsIHNpbWlsYXIgdG8ganF1ZXJ5IHZhbFxuICAgIHZhbHModmFsdWVzKSB7XG4gICAgICAgIGlmICh2YWx1ZXMpIHtcbiAgICAgICAgICAgIC8vIFNldHRlclxuXG4gICAgICAgICAgICB0aGlzLiQuc2hhbGxvd0ZpbmQoJy5XaWRnZXQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgJHdpZGdldCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9ICR3aWRnZXQuY29tcG9uZW50KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAndmFsJyBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHdpZGdldF9uYW1lID0gJHdpZGdldC5kYXRhKCduYW1lJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aWRnZXRfbmFtZSBpbiB2YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudC52YWwodmFsdWVzW3dpZGdldF9uYW1lXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIGxldCBkYXRhID0ge307XG5cbiAgICAgICAgICAgIC8vIEdldCB3aWRnZXQgdmFsdWVzXG4gICAgICAgICAgICB0aGlzLiQuc2hhbGxvd0ZpbmQoJy5XaWRnZXQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgJHdpZGdldCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9ICR3aWRnZXQuY29tcG9uZW50KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAndmFsJyBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHdpZGdldF9uYW1lID0gJHdpZGdldC5kYXRhKCduYW1lJyk7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbd2lkZ2V0X25hbWVdID0gY29tcG9uZW50LnZhbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBBbHNvIGdldCByZWd1bGFyIGhpZGRlbiBpbnB1dHMgKG5vbi13aWRnZXQgaW5wdXRzKVxuICAgICAgICAgICAgdGhpcy4kLmZpbmQoJ2lucHV0W3R5cGU9XCJoaWRkZW5cIl1bbmFtZV0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBsZXQgJGlucHV0ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICBsZXQgbmFtZSA9ICRpbnB1dC5hdHRyKCduYW1lJyk7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVtuYW1lXSA9ICRpbnB1dC52YWwoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZXJyb3IobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLmVycm9yc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgYW4gZXJyb3IgaW4gdGhlIGZvcm0ncyBlcnJvciBjb250YWluZXJcbiAgICAgKlxuICAgICAqIEhhbmRsZXMgYm90aCBmaWVsZC1zcGVjaWZpYyB2YWxpZGF0aW9uIGVycm9ycyBhbmQgZ2VuZXJpYyBlcnJvcnMuXG4gICAgICogQ2FuIGJlIGNhbGxlZCBieSBleHRlcm5hbCBoYW5kbGVycyAoZS5nLiwgbW9kYWwgb25fc3VibWl0KSBvciBpbnRlcm5hbGx5XG4gICAgICogYnkgdGhlIGZvcm0ncyBvd24gc3VibWl0KCkgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtFcnJvcnxPYmplY3R9IGVycm9yIC0gRXJyb3Igb2JqZWN0IGZyb20gQWpheCBjYWxsXG4gICAgICovXG4gICAgYXN5bmMgcmVuZGVyX2Vycm9yKGVycm9yKSB7XG4gICAgICAgIC8vIEhhbmRsZSB2YWxpZGF0aW9uIGVycm9ycyAtIGFwcGx5IHRvIGZpZWxkc1xuICAgICAgICBpZiAoZXJyb3IudHlwZSA9PT0gJ2Zvcm1fZXJyb3InICYmIGVycm9yLmRldGFpbHMpIHtcbiAgICAgICAgICAgIGF3YWl0IEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnModGhpcy4kLCBlcnJvci5kZXRhaWxzKTtcblxuICAgICAgICAgICAgLy8gTm90aWZ5IHRhYnMgb2YgdmFsaWRhdGlvbiBlcnJvcnMgZm9yIGVycm9yIGJhZGdlcyBhbmQgYXV0by1zd2l0Y2hpbmdcbiAgICAgICAgICAgIGlmICh0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRhYnMuaGFuZGxlX3ZhbGlkYXRpb25fZXJyb3JzKGVycm9yLmRldGFpbHMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBGb3JtX1V0aWxzIGhhbmRsZXMgYWxsIHJlbmRlcmluZyAoaW5saW5lIGVycm9ycyArIHVubWF0Y2hlZCBlcnJvcnMgYWxlcnQpXG4gICAgICAgICAgICAvLyBEb24ndCBjYWxsIFJzeC5yZW5kZXJfZXJyb3IoKSB0byBhdm9pZCBkdXBsaWNhdGUgYWxlcnRzXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3Igbm9uLWZvcm0gZXJyb3JzIChmYXRhbCwgYXV0aCwgbmV0d29yaywgZXRjLiksIHJlbmRlciBpbiBmb3JtJ3MgZXJyb3IgY29udGFpbmVyXG4gICAgICAgIFJzeC5yZW5kZXJfZXJyb3IoZXJyb3IsIHRoaXMuJGlkKCdlcnJvcicpKTtcbiAgICB9XG5cbiAgICBhc3luYyBzdWJtaXQoKSB7XG4gICAgICAgIC8vIENsZWFyIGFueSBwcmV2aW91cyBlcnJvcnNcbiAgICAgICAgRm9ybV9VdGlscy5yZXNldF9mb3JtX2Vycm9ycyh0aGlzLiQpO1xuICAgICAgICB0aGlzLiRpZCgnZXJyb3InKS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIENsZWFyIHRhYiBlcnJvciBiYWRnZXMgaWYgdGFicyBhcmUgcHJlc2VudFxuICAgICAgICBpZiAodGhpcy50YWJzKSB7XG4gICAgICAgICAgICB0aGlzLnRhYnMuY2xlYXJfZXJyb3JfYmFkZ2VzKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXJpYWxpemUgYWxsIGZpZWxkIHZhbHVlc1xuICAgICAgICBsZXQgdmFsdWVzID0gdGhpcy52YWxzKCk7XG5cbiAgICAgICAgLy8gQ2FsbCBzdWJtaXQgaGFuZGxlclxuICAgICAgICBpZiAoIXRoaXMuYXJncy5jb250cm9sbGVyIHx8ICF0aGlzLmFyZ3MubWV0aG9kKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGb3JtOiBObyBjb250cm9sbGVyL21ldGhvZCBwcm92aWRlZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3JtIGNvbmZpZ3VyYXRpb24gZXJyb3I6IE1pc3NpbmcgY29udHJvbGxlciBvciBtZXRob2QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBCdWlsZCBBamF4IFVSTCBmcm9tIGNvbnRyb2xsZXIgYW5kIG1ldGhvZFxuICAgICAgICAgICAgY29uc3QgYWpheF91cmwgPSBgL19hamF4LyR7dGhpcy5hcmdzLmNvbnRyb2xsZXJ9LyR7dGhpcy5hcmdzLm1ldGhvZH1gO1xuXG4gICAgICAgICAgICAvLyBDYWxsIEFqYXggZW5kcG9pbnQgLSByZXNwb25zZSBpcyBkaXJlY3RseSB3aGF0IFBIUCByZXR1cm5lZFxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgQWpheC5jYWxsKGFqYXhfdXJsLCB2YWx1ZXMpO1xuXG4gICAgICAgICAgICAvLyBTdWNjZXNzISBIYW5kbGUgcmVzdWx0XG4gICAgICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdC5yZWRpcmVjdCkge1xuICAgICAgICAgICAgICAgIC8vIFJlZGlyZWN0IHRvIFVSTFxuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gcmVzdWx0LnJlZGlyZWN0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTdWNjZXNzIHdpdGhvdXQgcmVkaXJlY3RcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnRm9ybSBzdWJtaXR0ZWQgc3VjY2Vzc2Z1bGx5JywgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFJlbmRlciBlcnJvciAoaGFuZGxlcyBib3RoIHZhbGlkYXRpb24gYW5kIGdlbmVyaWMgZXJyb3JzKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXJfZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcbiAgICAgICAgdGhpcy4kLnNoYWxsb3dGaW5kKCcuRm9ybV9GaWVsZCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9ICQodGhpcykuY29tcG9uZW50KCk7XG4gICAgICAgICAgICBpZiAoY29tcG9uZW50ICYmICdzZWVkJyBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGNvbXBvbmVudC5zZWVkKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUGluX1ZlcmlmaWNhdGlvbl9Gb3JtXG4gKlxuICogU3BlY2lhbGl6ZWQgNi1kaWdpdCBQSU4gZW50cnkgZm9ybSB3aXRoIGF1dG8tbmF2aWdhdGlvbiBiZXR3ZWVuIGlucHV0cy5cbiAqIFNlZSBwaW5fdmVyaWZpY2F0aW9uX2Zvcm0uanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBBdXRvLWFkdmFuY2VzIHRvIG5leHQgaW5wdXQgd2hlbiBkaWdpdCBpcyBlbnRlcmVkXG4gKiAtIFNtYXJ0IGJhY2tzcGFjZTogY2xlYXJzIGN1cnJlbnQgYm94IGFuZCBtb3ZlcyB0byBwcmV2aW91c1xuICogLSBQYXN0ZSBzdXBwb3J0OiBkaXN0cmlidXRlcyBwYXN0ZWQgZGlnaXRzIGFjcm9zcyBhbGwgNiBpbnB1dHNcbiAqIC0gQXJyb3cga2V5IG5hdmlnYXRpb24gYmV0d2VlbiBpbnB1dHNcbiAqIC0gTnVtZXJpYy1vbmx5IGlucHV0IHZhbGlkYXRpb25cbiAqIC0gU2VsZWN0LWFsbCBvbiBmb2N1cyBmb3IgZWFzeSBkaWdpdCByZXBsYWNlbWVudFxuICogLSBWYWxpZGF0ZXMgYWxsIDYgZGlnaXRzIGVudGVyZWQgYmVmb3JlIGFsbG93aW5nIHN1Ym1pc3Npb25cbiAqIC0gUHJvdmlkZXMgdmFsKCkgZ2V0dGVyL3NldHRlciBmb3IgcHJvZ3JhbW1hdGljIFBJTiBhY2Nlc3NcbiAqL1xuY2xhc3MgUGluX1ZlcmlmaWNhdGlvbl9Gb3JtIGV4dGVuZHMgUnN4X0Zvcm0ge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgICAgIHRoaXMucGluX2xlbmd0aCA9IDY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IG9yIHNldCB0aGUgUElOIHZhbHVlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgUElOIChkaXN0cmlidXRlcyBhY3Jvc3MgaW5wdXRzKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEN1cnJlbnQgUElOIHZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gY29sbGVjdCBhbGwgZGlnaXRzXG4gICAgICAgICAgICBsZXQgcGluID0gJyc7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcGluICs9IHRoaXMuJGlkKGBkaWdpdF8ke2l9YCkudmFsKCkgfHwgJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGluO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gZGlzdHJpYnV0ZSBkaWdpdHMgYWNyb3NzIGlucHV0c1xuICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gc3RyKHZhbHVlIHx8ICcnKS5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke2l9YCkudmFsKGRpZ2l0c1tpXSB8fCAnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBGb2N1cyBmaXJzdCBlbXB0eSBpbnB1dCBvciBsYXN0IGlucHV0XG4gICAgICAgICAgICBjb25zdCBmaXJzdF9lbXB0eSA9IHRoaXMuX2ZpbmRfZmlyc3RfZW1wdHlfaW5kZXgoKTtcbiAgICAgICAgICAgIGlmIChmaXJzdF9lbXB0eSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtmaXJzdF9lbXB0eX1gKVswXS5mb2N1cygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHt0aGlzLnBpbl9sZW5ndGggLSAxfWApWzBdLmZvY3VzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaW5kIHRoZSBmaXJzdCBlbXB0eSBpbnB1dCBpbmRleFxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEluZGV4IG9mIGZpcnN0IGVtcHR5IGlucHV0LCBvciAtMSBpZiBhbGwgZmlsbGVkXG4gICAgICovXG4gICAgX2ZpbmRfZmlyc3RfZW1wdHlfaW5kZXgoKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS52YWwoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNb3ZlIGZvY3VzIHRvIHNwZWNpZmljIGlucHV0IGluZGV4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gICAgICovXG4gICAgX2ZvY3VzX2lucHV0KGluZGV4KSB7XG4gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5waW5fbGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZChgZGlnaXRfJHtpbmRleH1gKTtcbiAgICAgICAgICAgIGlmICgkaW5wdXQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICAkaW5wdXRbMF0uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGNvbnRlbnQgaWYgdGhlcmUgaXMgYW55XG4gICAgICAgICAgICAgICAgJGlucHV0WzBdLnNlbGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlIHBhc3RlIGV2ZW50IC0gZGlzdHJpYnV0ZSBkaWdpdHMgYWNyb3NzIGlucHV0c1xuICAgICAqIEBwYXJhbSB7Q2xpcGJvYXJkRXZlbnR9IGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRfaW5kZXhcbiAgICAgKi9cbiAgICBfaGFuZGxlX3Bhc3RlKGUsIHN0YXJ0X2luZGV4KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAvLyBHZXQgcGFzdGVkIGRhdGFcbiAgICAgICAgY29uc3QgcGFzdGUgPSAoZS5vcmlnaW5hbEV2ZW50IHx8IGUpLmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dCcpO1xuICAgICAgICBjb25zdCBkaWdpdHMgPSBwYXN0ZS5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuXG4gICAgICAgIGlmICghZGlnaXRzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEaXN0cmlidXRlIGRpZ2l0cyBzdGFydGluZyBmcm9tIGN1cnJlbnQgaW5wdXRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWdpdHMubGVuZ3RoICYmIChzdGFydF9pbmRleCArIGkpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke3N0YXJ0X2luZGV4ICsgaX1gKS52YWwoZGlnaXRzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvY3VzIG5leHQgZW1wdHkgaW5wdXQgb3IgbGFzdCBpbnB1dFxuICAgICAgICBjb25zdCBuZXh0X2luZGV4ID0gTWF0aC5taW4oc3RhcnRfaW5kZXggKyBkaWdpdHMubGVuZ3RoLCB0aGlzLnBpbl9sZW5ndGggLSAxKTtcbiAgICAgICAgdGhpcy5fZm9jdXNfaW5wdXQobmV4dF9pbmRleCk7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHN1cGVyLm9uX3JlYWR5KCk7XG5cbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IHVwIGV2ZW50IGhhbmRsZXJzIGZvciBlYWNoIGlucHV0XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKGBkaWdpdF8ke2l9YCk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IGk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBpbnB1dCBldmVudCAtIGF1dG8tYWR2YW5jZVxuICAgICAgICAgICAgJGlucHV0Lm9uKCdpbnB1dCcsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9ICQodGhpcykudmFsKCk7XG5cbiAgICAgICAgICAgICAgICAvLyBPbmx5IGFsbG93IG51bWVyaWMgaW5wdXRcbiAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljID0gdmFsdWUucmVwbGFjZSgvW14wLTldL2csICcnKTtcbiAgICAgICAgICAgICAgICBpZiAobnVtZXJpYyAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS52YWwobnVtZXJpYyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSWYgbXVsdGlwbGUgZGlnaXRzIHdlcmUgZW50ZXJlZCAocGFzdGUpLCBkaXN0cmlidXRlIHRoZW1cbiAgICAgICAgICAgICAgICBpZiAobnVtZXJpYy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX2hhbmRsZV9wYXN0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2ZW50RGVmYXVsdDogKCkgPT4ge30sXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEV2ZW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcGJvYXJkRGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREYXRhOiAoKSA9PiBudW1lcmljXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBdXRvLWFkdmFuY2UgdG8gbmV4dCBpbnB1dCBpZiBkaWdpdCB3YXMgZW50ZXJlZFxuICAgICAgICAgICAgICAgIGlmIChudW1lcmljLmxlbmd0aCA9PT0gMSAmJiBpbmRleCA8IHRoYXQucGluX2xlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fZm9jdXNfaW5wdXQoaW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gSGFuZGxlIGtleWRvd24gZm9yIGJhY2tzcGFjZVxuICAgICAgICAgICAgJGlucHV0Lm9uKCdrZXlkb3duJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIC8vIEJhY2tzcGFjZSBrZXlcbiAgICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdCYWNrc3BhY2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRfdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGN1cnJlbnQgaW5wdXQgaXMgZW1wdHksIG1vdmUgdG8gcHJldmlvdXMgYW5kIGNsZWFyIGl0XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3VycmVudF92YWx1ZSAmJiBpbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuJGlkKGBkaWdpdF8ke2luZGV4IC0gMX1gKS52YWwoJycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fZm9jdXNfaW5wdXQoaW5kZXggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBjdXJyZW50IGlucHV0IGhhcyB2YWx1ZSwgaXQgd2lsbCBiZSBjbGVhcmVkIGJ5IGRlZmF1bHQgYmVoYXZpb3JcbiAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHdlIHN0YXkgb24gY3VycmVudCBpbnB1dFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFycm93IGxlZnRcbiAgICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdBcnJvd0xlZnQnICYmIGluZGV4ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4IC0gMSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXJyb3cgcmlnaHRcbiAgICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdBcnJvd1JpZ2h0JyAmJiBpbmRleCA8IHRoYXQucGluX2xlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9mb2N1c19pbnB1dChpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUgcGFzdGUgZXZlbnRcbiAgICAgICAgICAgICRpbnB1dC5vbigncGFzdGUnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5faGFuZGxlX3Bhc3RlKGUsIGluZGV4KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTZWxlY3QgYWxsIG9uIGZvY3VzIGZvciBlYXN5IHJlcGxhY2VtZW50XG4gICAgICAgICAgICAkaW5wdXQub24oJ2ZvY3VzJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKVswXS5zZWxlY3QoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9jdXMgZmlyc3QgaW5wdXQgb24gbG9hZFxuICAgICAgICB0aGlzLl9mb2N1c19pbnB1dCgwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSBzdWJtaXQgdG8gdmFsaWRhdGUgUElOIGlzIGNvbXBsZXRlXG4gICAgICovXG4gICAgYXN5bmMgc3VibWl0KCkge1xuICAgICAgICBjb25zdCBwaW4gPSB0aGlzLnZhbCgpO1xuXG4gICAgICAgIC8vIENsZWFyIHByZXZpb3VzIGVycm9yc1xuICAgICAgICB0aGlzLiRpZCgnZXJyb3JfY29udGFpbmVyJykuaGlkZSgpLmVtcHR5KCk7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgUElOIGlzIDYgZGlnaXRzXG4gICAgICAgIGlmIChwaW4ubGVuZ3RoICE9PSB0aGlzLnBpbl9sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdlcnJvcl9jb250YWluZXInKVxuICAgICAgICAgICAgICAgIC50ZXh0KCdQbGVhc2UgZW50ZXIgYWxsIDYgZGlnaXRzJylcbiAgICAgICAgICAgICAgICAuc2hvdygpO1xuXG4gICAgICAgICAgICAvLyBNYXJrIGlucHV0cyBhcyBpbnZhbGlkXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke2l9YCkuYWRkQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSBpbnZhbGlkIGNsYXNzIGZyb20gYWxsIGlucHV0c1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtpfWApLnJlbW92ZUNsYXNzKCdpcy1pbnZhbGlkJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDYWxsIHBhcmVudCBzdWJtaXQgKHdoaWNoIHdpbGwgdXNlIGNvbnRyb2xsZXIvbWV0aG9kIGlmIHByb3ZpZGVkKVxuICAgICAgICBhd2FpdCBzdXBlci5zdWJtaXQoKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fRmllbGRfQWJzdHJhY3RcbiAqXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBmb3JtIGZpZWxkIHdyYXBwZXJzLiBQcm92aWRlcyBjb3JlIGZ1bmN0aW9uYWxpdHkgd2l0aG91dCB2aXN1YWwgZm9ybWF0dGluZy5cbiAqIFNlZSBmb3JtX2ZpZWxkX2Fic3RyYWN0LmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gRGlzY292ZXJzIGFuZCBjb25maWd1cmVzIGNoaWxkIFdpZGdldCBjb21wb25lbnRcbiAqIC0gU2V0cyBkYXRhLW5hbWUgYXR0cmlidXRlIG9uIHdpZGdldCBmb3IgZm9ybSB2YWx1ZSBjb2xsZWN0aW9uXG4gKiAtIFNldHMgbmFtZSBhdHRyaWJ1dGUgb24gbmF0aXZlIGlucHV0cyBmb3IgRm9ybV9VdGlscyBjb21wYXRpYmlsaXR5XG4gKiAtIFdpcmVzIGxhYmVsICdmb3InIGF0dHJpYnV0ZSB0byBpbnB1dCBlbGVtZW50IElEIGZvciBhY2Nlc3NpYmlsaXR5IChpZiBsYWJlbCBleGlzdHMpXG4gKiAtIFByb3ZpZGVzIHNlZWQoKSBzdXBwb3J0IGZvciBkZWJ1Zy90ZXN0aW5nIGRhdGFcbiAqIC0gQnJpZGdlcyBiZXR3ZWVuIGZvcm0gdmFsaWRhdGlvbiBzdGF0ZSBhbmQgY2hpbGQgd2lkZ2V0XG4gKi9cbmNsYXNzIEZvcm1fRmllbGRfQWJzdHJhY3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEZpbmQgcGFyZW50IGZvcm0gZm9yIGVycm9yIGRpc3BsYXlcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5jbG9zZXN0KCcuUnN4X0Zvcm0nKTtcbiAgICAgICAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignRm9ybV9GaWVsZF9BYnN0cmFjdCBtdXN0IGJlIGluc2lkZSBhIFJzeF9Gb3JtIGNvbXBvbmVudCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEZpbmQgY2hpbGQgd2lkZ2V0IGFuZCBzZXQgaXRzIGRhdGEtbmFtZSBhdHRyaWJ1dGVcbiAgICAgICAgbGV0ICR3aWRnZXQgPSB0aGlzLiQuZmluZCgnLldpZGdldCcpLmZpcnN0KCk7XG5cbiAgICAgICAgaWYgKCEkd2lkZ2V0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oXG4gICAgICAgICAgICAgICAgYEZvcm1fRmllbGRfQWJzdHJhY3QgXCIke3RoaXMuYXJncy5uYW1lfVwiIGhhcyBubyAuV2lkZ2V0IGNoaWxkLiBFdmVyeSBGb3JtX0ZpZWxkIG11c3QgY29udGFpbiBleGFjdGx5IG9uZSB3aWRnZXQgKFRleHRfSW5wdXQsIFd5c2l3eWdfSW5wdXQsIGV0Yy4pYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkYXRhLW5hbWUgb24gdGhlIHdpZGdldCBzbyBSc3hfRm9ybSBjYW4gY29sbGVjdCB2YWx1ZXNcbiAgICAgICAgJHdpZGdldC5hdHRyKCdkYXRhLW5hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG5cbiAgICAgICAgbGV0ICRpbnB1dCA9IHRoaXMuJC5maW5kKCdpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYScpLmZpcnN0KCk7XG4gICAgICAgIGlmICgkaW5wdXQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIC8vIEFsc28gc2V0IG5hbWUgYXR0cmlidXRlIG9uIG5hdGl2ZSBpbnB1dHMgZm9yIEZvcm1fVXRpbHMgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgLy8gVG9kbzogY2xldmVyIHdheSB0byBkZWFsIHdpdGggdGhpcyBmb3Igbm9uIHN0YW5kYXJkIGlucHV0IGVsZW1lbnRzXG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcblxuICAgICAgICAgICAgLy8gU2V0IHRoZSBmb3IgZmllbGQgdG8gdGhlIGVsZW1lbnQgaWYgbGFiZWwgZXhpc3RzIChmb3IgY2hpbGQgY2xhc3NlcylcbiAgICAgICAgICAgIC8vIFRvZG86IGNsZXZlciB3YXkgdG8gZGVhbCB3aXRoIHRoaXMgZm9yIG5vbiBzdGFuZGFyZCBpbnB1dCBlbGVtZW50c1xuICAgICAgICAgICAgbGV0ICRsYWJlbCA9IHRoaXMuJGlkKCdmb3JtX2xhYmVsJyk7XG4gICAgICAgICAgICBpZiAoJGxhYmVsLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgJGxhYmVsLmF0dHIoJ2ZvcicsICRpbnB1dC5hdHRyKCdpZCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9lcnJvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybS5nZXRfZXJyb3IodGhpcy5hcmdzLm5hbWUpO1xuICAgIH1cblxuICAgIGhhc19lcnJvcigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5nZXRfZXJyb3IoKTtcbiAgICB9XG5cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBpZiAoIXRoaXMuYXJncy5zZWVkZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmQgY2hpbGQgd2lkZ2V0XG4gICAgICAgIGxldCAkd2lkZ2V0ID0gdGhpcy4kLmZpbmQoJy5XaWRnZXQnKS5maXJzdCgpO1xuICAgICAgICBpZiAoISR3aWRnZXQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB3aWRnZXRfY29tcG9uZW50ID0gJHdpZGdldC5jb21wb25lbnQoKTtcbiAgICAgICAgaWYgKCF3aWRnZXRfY29tcG9uZW50IHx8ICF3aWRnZXRfY29tcG9uZW50LnZhbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FsbCB0aGUgc2VlZGVyIGVuZHBvaW50IChBamF4IHJvdXRlIHJlZmVyZW5jZSBsaWtlIGZvcm0gJGFjdGlvbilcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IGF3YWl0IEFqYXguY2FsbCh0aGlzLmFyZ3Muc2VlZGVyLCB7fSk7XG4gICAgICAgICAgICB3aWRnZXRfY29tcG9uZW50LnZhbCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBTZWVkZXIgZXJyb3IgZm9yICR7dGhpcy5hcmdzLm5hbWV9OmAsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8qKlxuICogRm9ybV9GaWVsZFxuICpcbiAqIEZvcm0gZmllbGQgd3JhcHBlciB0aGF0IGFkZHMgbGFiZWxzLCBoZWxwIHRleHQsIGFuZCByZXF1aXJlZCBpbmRpY2F0b3JzLlxuICogU2VlIGZvcm1fZmllbGQuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogRXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IHRvIGluaGVyaXQgYWxsIGNvcmUgZnVuY3Rpb25hbGl0eS5cbiAqIFRoaXMgY2xhc3MgZXhpc3RzIHByaW1hcmlseSBmb3IgdGVtcGxhdGUgaW5oZXJpdGFuY2UgYW5kIGFueSBmdXR1cmVcbiAqIGZvcm1hdHRlZC1maWVsZC1zcGVjaWZpYyBiZWhhdmlvci5cbiAqL1xuY2xhc3MgRm9ybV9GaWVsZCBleHRlbmRzIEZvcm1fRmllbGRfQWJzdHJhY3Qge1xuICAgIC8vIEFsbCBmdW5jdGlvbmFsaXR5IGluaGVyaXRlZCBmcm9tIEZvcm1fRmllbGRfQWJzdHJhY3RcbiAgICAvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBmb3JtYXR0ZWQgdmlzdWFsIHdyYXBwZXIgdmlhIGl0cyB0ZW1wbGF0ZVxufVxuIiwiLyoqXG4gKiBGb3JtX0hpZGRlbl9GaWVsZCAtIEhpZGRlbiBpbnB1dCBmaWVsZCBjb21wb25lbnRcbiAqXG4gKiBFeHRlbmRzIEZvcm1fRmllbGRfQWJzdHJhY3QgYnV0IElTIHRoZSBpbnB1dCBlbGVtZW50IGl0c2VsZiAodXNpbmcgdGFnPVwiaW5wdXRcIiB0eXBlPVwiaGlkZGVuXCIpLlxuICogU2VlIGZvcm1faGlkZGVuX2ZpZWxkLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gU2V0cyB2YWx1ZSBhdHRyaWJ1dGUgZHluYW1pY2FsbHkgaW4gb25fY3JlYXRlKClcbiAqIC0gT3ZlcnJpZGVzIG9uX3JlYWR5KCkgdG8gaGFuZGxlIHRoYXQgdGhpcy4kIElTIGJvdGggdGhlIHdpZGdldCBhbmQgdGhlIGlucHV0XG4gKiAtIFByb3ZpZGVzIHZhbCgpIG1ldGhvZCBmb3IgZ2V0dGluZy9zZXR0aW5nIHRoZSBoaWRkZW4gdmFsdWVcbiAqL1xuY2xhc3MgRm9ybV9IaWRkZW5fRmllbGQgZXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIHNldCB1cCBmb3JtIHJlZmVyZW5jZVxuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcblxuICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZSBhdHRyaWJ1dGUgKGNhbid0IGJlIGRvbmUgaW4gRGVmaW5lIHRhZylcbiAgICAgICAgdGhpcy4kLmF0dHIoJ3ZhbHVlJywgJycpO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBPdmVycmlkZSBwYXJlbnQgb25fcmVhZHkoKSBiZWNhdXNlIHRoaXMuJCBJUyB0aGUgd2lkZ2V0IGFuZCB0aGUgaW5wdXRcbiAgICAgICAgLy8gU2V0IGRhdGEtbmFtZSBvbiB0aGlzLiQgKHdoaWNoIGlzIHRoZSBpbnB1dCBlbGVtZW50KVxuICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1uYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuXG4gICAgICAgIC8vIFNldCBuYW1lIGF0dHJpYnV0ZSBvbiB0aGlzLiQgZm9yIEZvcm1fVXRpbHMgY29tcGF0aWJpbGl0eVxuICAgICAgICB0aGlzLiQuYXR0cignbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGhpZGRlbiBpbnB1dCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXIgLSB0aGlzLiQgaXMgdGhlIGlucHV0IGVsZW1lbnQgaXRzZWxmXG4gICAgICAgICAgICByZXR1cm4gdGhpcy4kLnZhbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gdXBkYXRlIHRoZSBpbnB1dCB2YWx1ZSBkaXJlY3RseSAodGhpcy4kIGlzIHRoZSBpbnB1dClcbiAgICAgICAgICAgIHRoaXMuJC52YWwodmFsdWUgfHwgJycpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfRGFzaGJvYXJkIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX0Rhc2hib2FyZFwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfRGFzaGJvYXJkIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0Rhc2hib2FyZC5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCIvKipcbiAqIENsaWVudHNfRGF0YUdyaWQgQ29tcG9uZW50XG4gKlxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yIGNsaWVudHMgZGF0YWdyaWQuXG4gKiBBbGwgZnVuY3Rpb25hbGl0eSBpcyBpbiBEYXRhR3JpZF9BYnN0cmFjdC5cbiAqL1xuY2xhc3MgQ2xpZW50c19EYXRhR3JpZCBleHRlbmRzIERhdGFHcmlkX0Fic3RyYWN0IHtcbiAgICAvLyBBbGwgYmVoYXZpb3IgaW5oZXJpdGVkIGZyb20gRGF0YUdyaWRfQWJzdHJhY3Rcbn1cbiIsImNsYXNzIEZyb250ZW5kX0NsaWVudHNfRWRpdCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJCgnLkZyb250ZW5kX0NsaWVudHNfRWRpdCcpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSGFuZGxlIGR5bmFtaWMgdGFnIGFkZGl0aW9uXG4gICAgICAgICQoJyNhZGQtdGFnJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCB0YWdfaHRtbCA9IGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIG5hbWU9XCJ0YWdzW11cIiBwbGFjZWhvbGRlcj1cImUuZy4sIFZJUCwgRW50ZXJwcmlzZSwgU3RyYXRlZ2ljIFBhcnRuZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyIHJlbW92ZS10YWdcIiB0eXBlPVwiYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGA7XG4gICAgICAgICAgICAkKCcjdGFncy1jb250YWluZXInKS5hcHBlbmQodGFnX2h0bWwpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgdGFnIHJlbW92YWxcbiAgICAgICAgJChkb2N1bWVudCkub24oJ2NsaWNrJywgJy5yZW1vdmUtdGFnJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgY29uc3QgJGJ1dHRvbiA9ICQoZS5jdXJyZW50VGFyZ2V0KTtcbiAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGlmIG1vcmUgdGhhbiBvbmUgdGFnIGZpZWxkIGV4aXN0c1xuICAgICAgICAgICAgaWYgKCQoJyN0YWdzLWNvbnRhaW5lciAuaW5wdXQtZ3JvdXAnKS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgJGJ1dHRvbi5jbG9zZXN0KCcuaW5wdXQtZ3JvdXAnKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIHZhbHVlIG9mIHRoZSBsYXN0IHJlbWFpbmluZyBmaWVsZFxuICAgICAgICAgICAgICAgICRidXR0b24uY2xvc2VzdCgnLmlucHV0LWdyb3VwJykuZmluZCgnaW5wdXQnKS52YWwoJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9DbGllbnRzX0VkaXQuaW5pdCgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX0NsaWVudHNfVmlldyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9DbGllbnRzX1ZpZXdcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICBjb25zb2xlX2RlYnVnKCdDTElFTlQnLCAnRnJvbnRlbmRfQ2xpZW50c19WaWV3IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGRlbGV0ZSBidXR0b25cbiAgICAgICAgJCgnI2RlbGV0ZS1jbGllbnQtYnRuJykub24oJ2NsaWNrJywgYXN5bmMgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkZWxlbWVudCA9ICQodGhpcyk7XG4gICAgICAgICAgICBjb25zdCBjbGllbnRfaWQgPSAkZWxlbWVudC5kYXRhKCdjbGllbnQtaWQnKTtcblxuICAgICAgICAgICAgY29uc3QgY29uZmlybWVkID0gYXdhaXQgTW9kYWwuY29uZmlybShcbiAgICAgICAgICAgICAgICAnRGVsZXRlIENsaWVudCcsXG4gICAgICAgICAgICAgICAgJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBjbGllbnQ/XFxuXFxuVGhpcyBhY3Rpb24gY2FuIGJlIHVuZG9uZSBieSByZXN0b3JpbmcgdGhlIGNsaWVudC4nLFxuICAgICAgICAgICAgICAgICdEZWxldGUnLFxuICAgICAgICAgICAgICAgICdDYW5jZWwnXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlybWVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLmRlbGV0ZSh7IGlkOiBjbGllbnRfaWQgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVsb2FkIHRoZSBwYWdlIHRvIHNob3cgZGVsZXRlZCBzdGF0dXNcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQocmVzdWx0Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBkZWxldGUgY2xpZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgcmVzdG9yZSBidXR0b25cbiAgICAgICAgJCgnI3Jlc3RvcmUtY2xpZW50LWJ0bicpLm9uKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50X2lkID0gJGVsZW1lbnQuZGF0YSgnY2xpZW50LWlkJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IE1vZGFsLmNvbmZpcm0oXG4gICAgICAgICAgICAgICAgJ1Jlc3RvcmUgQ2xpZW50JyxcbiAgICAgICAgICAgICAgICAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHJlc3RvcmUgdGhpcyBjbGllbnQ/JyxcbiAgICAgICAgICAgICAgICAnUmVzdG9yZScsXG4gICAgICAgICAgICAgICAgJ0NhbmNlbCdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChjb25maXJtZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIucmVzdG9yZSh7IGlkOiBjbGllbnRfaWQgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVsb2FkIHRoZSBwYWdlIHRvIHNob3cgcmVzdG9yZWQgc3RhdHVzXG4gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3VsdC5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gcmVzdG9yZSBjbGllbnQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0NsaWVudHNfVmlldy5pbml0KCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfQ2xpZW50cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJCgnLkZyb250ZW5kX0NsaWVudHMnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfQ2xpZW50cyBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0NsaWVudHMuaW5pdCgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1RlYW0ge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfVGVhbVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfVGVhbSBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19UZWFtLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX05vdGlmaWNhdGlvbnMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfTm90aWZpY2F0aW9uc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfTm90aWZpY2F0aW9ucyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX0JpbGxpbmcge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZ1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19CaWxsaW5nLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX0ltcG9ydCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc19JbXBvcnRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX0ltcG9ydCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19JbXBvcnQuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfQXBpIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX0FwaVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfQXBpIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1NldHRpbmdzX0FwaS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19UZW1wbGF0ZXMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9TZXR0aW5nc19UZW1wbGF0ZXMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX0F1ZGl0IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX0F1ZGl0XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9TZXR0aW5nc19BdWRpdCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19BdWRpdC5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXkge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXkgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3Mge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5nc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5ncyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX1NldHRpbmdzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eSBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiLyoqXHJcbiAqIFVzZXJzX0RhdGFHcmlkIENvbXBvbmVudFxyXG4gKlxyXG4gKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBmb3IgY2xpZW50cyBkYXRhZ3JpZC5cclxuICogQWxsIGZ1bmN0aW9uYWxpdHkgaXMgaW4gRGF0YUdyaWRfQWJzdHJhY3QuXHJcbiAqL1xyXG5jbGFzcyBVc2Vyc19EYXRhR3JpZCBleHRlbmRzIERhdGFHcmlkX0Fic3RyYWN0IHtcclxuICAgIC8vIEFsbCBiZWhhdmlvciBpbmhlcml0ZWQgZnJvbSBEYXRhR3JpZF9BYnN0cmFjdFxyXG59XHJcbiIsIi8qKlxuICogQWRkX1VzZXJfRm9ybVxuICpcbiAqIE1vZGFsIGZvcm0gY29tcG9uZW50IGZvciBpbnZpdGluZyB1c2VycyB0byB0aGUgY3VycmVudCBzaXRlLlxuICogU2VlIGFkZF91c2VyX2Zvcm0uanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBJbXBsZW1lbnRzIHZhbHMoKSBtZXRob2QgZm9yIGZvcm0gZGF0YSBleHRyYWN0aW9uXG4gKiAtIFByb3ZpZGVzIGRlZmF1bHQgcm9sZV9pZCAoTWVtYmVyID0gMylcbiAqL1xuY2xhc3MgQWRkX1VzZXJfRm9ybSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgZm9ybSB2YWx1ZXNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3ZhbHVlc10gLSBJZiBwcm92aWRlZCwgcG9wdWxhdGVzIGZvcm0gd2l0aCB0aGVzZSB2YWx1ZXNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fG51bGx9IC0gRm9ybSB2YWx1ZXMgaWYgZ2V0dGluZywgbnVsbCBpZiBzZXR0aW5nXG4gICAgICovXG4gICAgLy8gdmFscyh2YWx1ZXMpIHtcbiAgICAvLyAgICAgY29uc3QgZm9ybSA9IHRoaXMuJC5maW5kKCdmb3JtJyk7XG4gICAgLy8gICAgIGlmICh2YWx1ZXMpIHtcbiAgICAvLyAgICAgICAgIC8vIFNldHRlciAtIHBvcHVsYXRlIGZvcm1cbiAgICAvLyAgICAgICAgIGZvcm0uZmluZCgnW25hbWU9XCJlbWFpbFwiXScpLnZhbCh2YWx1ZXMuZW1haWwgfHwgJycpO1xuICAgIC8vICAgICAgICAgZm9ybS5maW5kKCdbbmFtZT1cImZpcnN0X25hbWVcIl0nKS52YWwodmFsdWVzLmZpcnN0X25hbWUgfHwgJycpO1xuICAgIC8vICAgICAgICAgZm9ybS5maW5kKCdbbmFtZT1cImxhc3RfbmFtZVwiXScpLnZhbCh2YWx1ZXMubGFzdF9uYW1lIHx8ICcnKTtcbiAgICAvLyAgICAgICAgIGZvcm0uZmluZCgnW25hbWU9XCJyb2xlX2lkXCJdJykudmFsKHZhbHVlcy5yb2xlX2lkIHx8IDMpOyAvLyBEZWZhdWx0IHRvIE1lbWJlclxuICAgIC8vICAgICAgICAgZm9ybS5maW5kKCdbbmFtZT1cInBob25lXCJdJykudmFsKHZhbHVlcy5waG9uZSB8fCAnJyk7XG4gICAgLy8gICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAvLyAgICAgfSBlbHNlIHtcbiAgICAvLyAgICAgICAgIC8vIEdldHRlciAtIGV4dHJhY3QgZm9ybSB2YWx1ZXNcbiAgICAvLyAgICAgICAgIHJldHVybiB7XG4gICAgLy8gICAgICAgICAgICAgZW1haWw6IGZvcm0uZmluZCgnW25hbWU9XCJlbWFpbFwiXScpLnZhbCgpLFxuICAgIC8vICAgICAgICAgICAgIGZpcnN0X25hbWU6IGZvcm0uZmluZCgnW25hbWU9XCJmaXJzdF9uYW1lXCJdJykudmFsKCksXG4gICAgLy8gICAgICAgICAgICAgbGFzdF9uYW1lOiBmb3JtLmZpbmQoJ1tuYW1lPVwibGFzdF9uYW1lXCJdJykudmFsKCksXG4gICAgLy8gICAgICAgICAgICAgcm9sZV9pZDogcGFyc2VJbnQoZm9ybS5maW5kKCdbbmFtZT1cInJvbGVfaWRcIl0nKS52YWwoKSkgfHwgMyxcbiAgICAvLyAgICAgICAgICAgICBwaG9uZTogZm9ybS5maW5kKCdbbmFtZT1cInBob25lXCJdJykudmFsKClcbiAgICAvLyAgICAgICAgIH07XG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG59XG4iLCIvKipcbiAqIEFkZF9Vc2VyX01vZGFsIC0gTW9kYWwgZm9yIGFkZGluZy9pbnZpdGluZyBuZXcgdXNlcnMgdG8gc2l0ZVxuICpcbiAqIERpc3BsYXlzIGZvcm0gdG8gY29sbGVjdCB1c2VyIGluZm9ybWF0aW9uIGFuZCBjcmVhdGUgcGVuZGluZyBpbnZpdGF0aW9uLlxuICogVXNlcyBBZGRfVXNlcl9Nb2RhbF9Gb3JtIGNvbXBvbmVudCBmb3IgVUkgYW5kIHZhbGlkYXRpb24uXG4gKlxuICogUmV0dXJucyBjcmVhdGVkIHVzZXIgcmVjb3JkIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGNhbmNlbC5cbiAqL1xuY2xhc3MgQWRkX1VzZXJfTW9kYWwgZXh0ZW5kcyBNb2RhbF9BYnN0cmFjdCB7XG4gICAgLyoqXG4gICAgICogU2hvdyBhZGQgdXNlciBtb2RhbFxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0fGZhbHNlPn0gVXNlciByZWNvcmQgb24gc3VjY2VzcywgZmFsc2Ugb24gY2FuY2VsXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNob3coKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLmZvcm0oe1xuICAgICAgICAgICAgdGl0bGU6ICdBZGQgVXNlcicsXG4gICAgICAgICAgICBjb21wb25lbnQ6ICdBZGRfVXNlcl9Nb2RhbF9Gb3JtJyxcbiAgICAgICAgICAgIG9uX3N1Ym1pdDogYXN5bmMgKGZvcm0pID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmb3JtLnZhbHMoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuYWRkX3VzZXIodmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsgLy8gQ2xvc2UgbW9kYWwsIHJldHVybiB1c2VyIGRhdGFcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBSZW5kZXIgZXJyb3IgKGZvcm0gaGFuZGxlcyBib3RoIHZhbGlkYXRpb24gYW5kIGdlbmVyaWMgZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBmb3JtLnJlbmRlcl9lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gS2VlcCBtb2RhbCBvcGVuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBmYWxzZTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNlbmRfVXNlcl9JbnZpdGVfTW9kYWwgLSBNb2RhbCBmb3Igc2VuZGluZy9yZXNlbmRpbmcgdXNlciBpbnZpdGF0aW9uc1xuICpcbiAqIEhhbmRsZXMgYm90aCBpbml0aWFsIGludml0YXRpb24gc2VuZGluZyAoYWZ0ZXIgdXNlciBjcmVhdGlvbikgYW5kIHJlc2VuZGluZ1xuICogZXhwaXJlZC9wZW5kaW5nIGludml0YXRpb25zLiBDYWxscyBiYWNrZW5kIGVuZHBvaW50IHRvIGdlbmVyYXRlIG5ldyBpbnZpdGVcbiAqIGNvZGUgYW5kIGRpc3BsYXlzIFVSTCBmb3IgdGVzdGluZyAodW50aWwgZW1haWwgc3lzdGVtIGltcGxlbWVudGVkKS5cbiAqXG4gKiBSZXR1cm5zIGludml0ZSBkYXRhIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGVycm9yLlxuICovXG5jbGFzcyBTZW5kX1VzZXJfSW52aXRlX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICAgIC8qKlxuICAgICAqIFNob3cgc2VuZCBpbnZpdGUgbW9kYWwgYW5kIHRyaWdnZXIgYmFja2VuZCBpbnZpdGVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1c2VyX2lkIC0gVXNlciBJRCB0byBzZW5kIGludml0ZSB0b1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdHxmYWxzZT59IEludml0ZSBkYXRhIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGVycm9yXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNob3codXNlcl9pZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQ2FsbCBiYWNrZW5kIHRvIHNlbmQvcmVzZW5kIGludml0ZVxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuc2VuZF9pbnZpdGUoe3VzZXJfaWR9KTtcblxuICAgICAgICAgICAgLy8gU2hvdyBpbnZpdGUgVVJMIGZvciB0ZXN0aW5nICh1bnRpbCBlbWFpbCBzeXN0ZW0gaW1wbGVtZW50ZWQpXG4gICAgICAgICAgICBpZiAocmVzdWx0Lmludml0ZV91cmwpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBNb2RhbC5hbGVydChcbiAgICAgICAgICAgICAgICAgICAgJ1VzZXIgSW52aXRlZCBTdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgICAgICAgICBgSW52aXRhdGlvbiBzZW50IVxcblxcblRlc3QgaW52aXRhdGlvbiBVUkw6XFxuJHtyZXN1bHQuaW52aXRlX3VybH1gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFNob3cgZXJyb3IgdG8gdXNlclxuICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoZXJyb3IsICdGYWlsZWQgdG8gU2VuZCBJbnZpdGF0aW9uJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoJy5Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEhhbmRsZSBBZGQgVXNlciBidXR0b24gY2xpY2tcbiAgICAgICAgJCgnI2J0bl9hZGRfdXNlcicpLm9uKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGF3YWl0IEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudC5oYW5kbGVfYWRkX3VzZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIHVzZXIgd29ya2Zsb3c6IHNob3cgYWRkIG1vZGFsLCByZWZyZXNoIGdyaWQsIHNob3cgaW52aXRlIG1vZGFsXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGhhbmRsZV9hZGRfdXNlcigpIHtcbiAgICAgICAgLy8gU2hvdyBhZGQgdXNlciBtb2RhbFxuICAgICAgICBjb25zdCB1c2VyID0gYXdhaXQgQWRkX1VzZXJfTW9kYWwuc2hvdygpO1xuXG4gICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAvLyBSZWZyZXNoIHRoZSB1c2VyIGxpc3RcbiAgICAgICAgICAgICQoJy5Vc2Vyc19EYXRhR3JpZCcpLmNvbXBvbmVudCgpLnJlbG9hZCgpO1xuXG4gICAgICAgICAgICAvLyBTaG93IHNlbmQgaW52aXRlIG1vZGFsXG4gICAgICAgICAgICBhd2FpdCBTZW5kX1VzZXJfSW52aXRlX01vZGFsLnNob3codXNlci5pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQuaW5pdCgpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogRWRpdF9Vc2VyX01vZGFsIC0gTW9kYWwgZm9yIGVkaXRpbmcgZXhpc3RpbmcgdXNlciBpbmZvcm1hdGlvblxuICpcbiAqIERpc3BsYXlzIGZvcm0gdG8gdXBkYXRlIHVzZXIgcHJvZmlsZSBpbmZvcm1hdGlvbi5cbiAqIFVzZXMgRWRpdF9Vc2VyX01vZGFsX0Zvcm0gY29tcG9uZW50IGZvciBVSSBhbmQgdmFsaWRhdGlvbi5cbiAqXG4gKiBSZXR1cm5zIHVwZGF0ZWQgdXNlciByZWNvcmQgb24gc3VjY2VzcywgZmFsc2Ugb24gY2FuY2VsLlxuICovXG5jbGFzcyBFZGl0X1VzZXJfTW9kYWwgZXh0ZW5kcyBNb2RhbF9BYnN0cmFjdCB7XG4gICAgLyoqXG4gICAgICogU2hvdyBlZGl0IHVzZXIgbW9kYWxcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1c2VyX2lkIC0gSUQgb2YgdXNlciB0byBlZGl0XG4gICAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0fGZhbHNlPn0gVXBkYXRlZCB1c2VyIHJlY29yZCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBjYW5jZWxcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgc2hvdyh1c2VyX2lkKSB7XG4gICAgICAgIC8vIExvYWQgdXNlciBkYXRhIGZvciBlZGl0aW5nXG4gICAgICAgIGxldCB1c2VyX2RhdGE7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB1c2VyX2RhdGEgPSBhd2FpdCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlci5nZXRfdXNlcl9mb3JfZWRpdCh7dXNlcl9pZH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoZXJyb3IsICdGYWlsZWQgdG8gTG9hZCBVc2VyJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAgICAgICAgICAgIHRpdGxlOiAnRWRpdCBVc2VyJyxcbiAgICAgICAgICAgIGNvbXBvbmVudDogJ0VkaXRfVXNlcl9Nb2RhbF9Gb3JtJyxcbiAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzOiB7ZGF0YTogdXNlcl9kYXRhfSxcbiAgICAgICAgICAgIG9uX3N1Ym1pdDogYXN5bmMgKGZvcm0pID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmb3JtLnZhbHMoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuc2F2ZV91c2VyKHZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7IC8vIENsb3NlIG1vZGFsLCByZXR1cm4gdXNlciBkYXRhXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVuZGVyIGVycm9yIChmb3JtIGhhbmRsZXMgYm90aCB2YWxpZGF0aW9uIGFuZCBnZW5lcmljIGVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm9ybS5yZW5kZXJfZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEtlZXAgbW9kYWwgb3BlblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgZmFsc2U7XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoJy5Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfVmlldycpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSGFuZGxlIEVkaXQgVXNlciBidXR0b24gY2xpY2tcbiAgICAgICAgJCgnI2J0bl9lZGl0X3VzZXInKS5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhd2FpdCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfVmlldy5oYW5kbGVfZWRpdF91c2VyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBSZXNlbmQgSW52aXRlIGJ1dHRvbiBjbGlja1xuICAgICAgICAkKCcjYnRuX3Jlc2VuZF9pbnZpdGUnKS5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhd2FpdCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfVmlldy5oYW5kbGVfcmVzZW5kX2ludml0ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFZGl0IHVzZXIgd29ya2Zsb3c6IHNob3cgZWRpdCBtb2RhbCwgcmVmcmVzaCBwYWdlIG9uIHNhdmVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgaGFuZGxlX2VkaXRfdXNlcigpIHtcbiAgICAgICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBwYWdlIGRhdGFcbiAgICAgICAgY29uc3QgdXNlcl9pZCA9IHdpbmRvdy5yc3hhcHAucGFnZV9kYXRhPy51c2VyX2lkO1xuXG4gICAgICAgIGlmICghdXNlcl9pZCkge1xuICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoJ1VzZXIgSUQgbm90IGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IGVkaXQgdXNlciBtb2RhbFxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBFZGl0X1VzZXJfTW9kYWwuc2hvdyh1c2VyX2lkKTtcblxuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAvLyBSZWZyZXNoIHBhZ2UgdG8gc2hvdyB1cGRhdGVkIHVzZXIgaW5mb3JtYXRpb25cbiAgICAgICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzZW5kIGludml0ZSB3b3JrZmxvdzogY2FsbCBzZW5kIGludml0ZSBtb2RhbFxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBoYW5kbGVfcmVzZW5kX2ludml0ZSgpIHtcbiAgICAgICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBwYWdlIGRhdGFcbiAgICAgICAgY29uc3QgdXNlcl9pZCA9IHdpbmRvdy5yc3hhcHAucGFnZV9kYXRhPy51c2VyX2lkO1xuXG4gICAgICAgIGlmICghdXNlcl9pZCkge1xuICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoJ1VzZXIgSUQgbm90IGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IHNlbmQgaW52aXRlIG1vZGFsXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFNlbmRfVXNlcl9JbnZpdGVfTW9kYWwuc2hvdyh1c2VyX2lkKTtcblxuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAvLyBSZWZyZXNoIHBhZ2UgdG8gc2hvdyB1cGRhdGVkIGludml0ZSBzdGF0dXNcbiAgICAgICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcuaW5pdCgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3Mge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5ncyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19TaXRlX1NldHRpbmdzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsIi8qKlxuICogU2V0dGluZ3MgUGFnZSBKYXZhU2NyaXB0XG4gKi9cbmNsYXNzIEZyb250ZW5kX1NldHRpbmdzIHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoZSBzZXR0aW5ncyBwYWdlXG4gICAgICovXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgLy8gT25seSBpbml0aWFsaXplIGlmIHdlJ3JlIG9uIHRoZSBzZXR0aW5ncyBwYWdlXG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc1wiKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcIkpTX0lOSVRcIiwgXCJTZXR0aW5ncyBwYWdlIGluaXRpYWxpemVkXCIpO1xuXG4gICAgICAgIC8vIEhhbmRsZSBzaWRlYmFyIG5hdmlnYXRpb25cbiAgICAgICAgJCgnLnNpZGViYXIgLm5hdi1saW5rJykub24oJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgY29uc3QgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRsaW5rLmF0dHIoJ2hyZWYnKSA9PT0gJyMnKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBhY3RpdmUgZnJvbSBhbGwgbGlua3NcbiAgICAgICAgICAgICAgICAkKCcuc2lkZWJhciAubmF2LWxpbmsnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgLy8gQWRkIGFjdGl2ZSB0byBjbGlja2VkXG4gICAgICAgICAgICAgICAgJGxpbmsuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2VjdGlvbiA9ICRsaW5rLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcIlVJXCIsIFwiU2V0dGluZ3Mgc2VjdGlvbiBjbGlja2VkOlwiLCBzZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGZvcm0gc3VibWlzc2lvbnNcbiAgICAgICAgJCgnZm9ybScpLm9uKCdzdWJtaXQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBjb25zdCAkZm9ybSA9ICQodGhpcyk7XG4gICAgICAgICAgICBjb25zdCBmb3JtRGF0YSA9ICRmb3JtLnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcIkZPUk1cIiwgXCJTZXR0aW5ncyBmb3JtIHN1Ym1pdHRlZFwiLCBmb3JtRGF0YSk7XG5cbiAgICAgICAgICAgIC8vIFNob3cgc3VjY2VzcyBtZXNzYWdlIChtb2NrKVxuICAgICAgICAgICAgY29uc3QgJGFsZXJ0ID0gJCgnPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MgYWxlcnQtZGlzbWlzc2libGUgZmFkZSBzaG93XCIgcm9sZT1cImFsZXJ0XCI+JylcbiAgICAgICAgICAgICAgICAuaHRtbCgnU2V0dGluZ3Mgc2F2ZWQgc3VjY2Vzc2Z1bGx5ISA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZVwiIGRhdGEtYnMtZGlzbWlzcz1cImFsZXJ0XCI+PC9idXR0b24+Jyk7XG5cbiAgICAgICAgICAgICRmb3JtLmNsb3Nlc3QoJy5jYXJkLWJvZHknKS5wcmVwZW5kKCRhbGVydCk7XG5cbiAgICAgICAgICAgIC8vIEF1dG8tZGlzbWlzcyBhZnRlciAzIHNlY29uZHNcbiAgICAgICAgICAgIC8vIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgLy8gICAgICRhbGVydC5mYWRlT3V0KCgpID0+ICRhbGVydC5yZW1vdmUoKSk7XG4gICAgICAgICAgICAvLyB9LCAzMDAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUXVpY2sgYWN0aW9uIGJ1dHRvbnNcbiAgICAgICAgJCgnLmNhcmQtYm9keSAuYnRuLXByaW1hcnknKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRidXR0b24gPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgYWN0aW9uID0gJGJ1dHRvbi50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcIlVJXCIsIFwiUXVpY2sgYWN0aW9uOlwiLCBhY3Rpb24pO1xuXG4gICAgICAgICAgICAvLyBTaW11bGF0ZSBhY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsVGV4dCA9ICRidXR0b24uaHRtbCgpO1xuICAgICAgICAgICAgJGJ1dHRvbi5odG1sKCc8c3BhbiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHNwaW5uZXItYm9yZGVyLXNtIG1lLTFcIj48L3NwYW4+IFByb2Nlc3NpbmcuLi4nKTtcbiAgICAgICAgICAgICRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgJGJ1dHRvbi5odG1sKG9yaWdpbmFsVGV4dCk7XG4gICAgICAgICAgICAgICAgJGJ1dHRvbi5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgICAgICAgIH0sIDE1MDApO1xuICAgICAgICB9KTtcbiAgICB9XG59IiwiLyoqXG4gKiBDb250YWN0c19EYXRhR3JpZCBDb21wb25lbnRcbiAqXG4gKiBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBmb3IgY29udGFjdHMgZGF0YWdyaWQuXG4gKiBBbGwgZnVuY3Rpb25hbGl0eSBpcyBpbiBEYXRhR3JpZF9BYnN0cmFjdC5cbiAqL1xuY2xhc3MgQ29udGFjdHNfRGF0YUdyaWQgZXh0ZW5kcyBEYXRhR3JpZF9BYnN0cmFjdCB7XG4gICAgLy8gQWxsIGJlaGF2aW9yIGluaGVyaXRlZCBmcm9tIERhdGFHcmlkX0Fic3RyYWN0XG59XG4iLCJjbGFzcyBEYXRhX1RhYmxlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVuZGVyKCkge1xuICAgICAgICAvLyBIaWRlIHVudGlsIGRhdGEgbG9hZHMgdG8gcHJldmVudCB2aXN1YWwgZ2xpdGNoZXNcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnZm9vdGVyJykuY3NzKCdvcGFjaXR5JywgJzAnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIElmIGRhdGFfc291cmNlIHByb3ZpZGVkLCBmZXRjaCBkYXRhXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IGF3YWl0IHRoaXMuZmV0Y2hfZGF0YSgpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5jb2x1bW5zICYmIHRoaXMuYXJncy5yb3dzKSB7XG4gICAgICAgICAgICAvLyBVc2UgcHJvdmlkZWQgc3RhdGljIGRhdGFcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB0aGlzLmFyZ3MuY29sdW1ucyxcbiAgICAgICAgICAgICAgICByb3dzOiB0aGlzLmFyZ3Mucm93cyxcbiAgICAgICAgICAgICAgICB0b3RhbDogdGhpcy5hcmdzLnJvd3MubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHN0YXJ0OiAxLFxuICAgICAgICAgICAgICAgIGVuZDogdGhpcy5hcmdzLnJvd3MubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGN1cnJlbnRfcGFnZTogMSxcbiAgICAgICAgICAgICAgICB0b3RhbF9wYWdlczogMSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2hvdyBmb290ZXIgYWZ0ZXIgcmVuZGVyXG4gICAgICAgIHRoaXMuJGlkKCdmb290ZXInKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgIC8vIEJ1aWxkIGNvbHVtbiBoZWFkZXJzIHdpdGggc29ydGluZ1xuICAgICAgICBpZiAodGhpcy5kYXRhLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRfaGVhZGVycyh0aGlzLmRhdGEuY29sdW1ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXR1cCBzZWFyY2ggaWYgZW5hYmxlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnNlYXJjaGFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dXBfc2VhcmNoKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXR1cCBjb2x1bW4gdmlzaWJpbGl0eSB0b2dnbGUgaWYgZW5hYmxlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbHVtbl90b2dnbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dXBfY29sdW1uX3RvZ2dsZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0dXAgYnVsayBhY3Rpb25zXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYnVsa19hY3Rpb25zKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwX2J1bGtfYWN0aW9ucygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXR0YWNoIHJvdyBjaGVja2JveCBsaXN0ZW5lcnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5yb3ctY2hlY2tib3gnKS5vbignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVfYnVsa19zZWxlY3Rpb24oKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0dXAgcGFnaW5hdGlvbiBjbGljayBoYW5kbGVyc1xuICAgICAgICBjb25zdCAkcGFnaW5hdGlvbiA9IHRoaXMuJGlkKCdwYWdpbmF0aW9uJyk7XG4gICAgICAgICRwYWdpbmF0aW9uLiQuZmluZCgnLnBhZ2UtbGluaycpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBjb25zdCBwYWdlX3RleHQgPSAkKGUudGFyZ2V0KS50ZXh0KCk7XG4gICAgICAgICAgICBpZiAocGFnZV90ZXh0ID09PSAnUHJldmlvdXMnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkX3BhZ2UodGhpcy5kYXRhLmN1cnJlbnRfcGFnZSAtIDEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwYWdlX3RleHQgPT09ICdOZXh0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZF9wYWdlKHRoaXMuZGF0YS5jdXJyZW50X3BhZ2UgKyAxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFnZSA9IGludChwYWdlX3RleHQpO1xuICAgICAgICAgICAgICAgIGlmICghaXNOYU4ocGFnZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkX3BhZ2UocGFnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBidWlsZF9oZWFkZXJzKGNvbHVtbnMpIHtcbiAgICAgICAgY29uc3QgJGhlYWRlcl9yb3cgPSB0aGlzLiRpZCgnaGVhZGVyX3JvdycpO1xuXG4gICAgICAgIC8vIFNraXAgZmlyc3QgY2VsbCBpZiBidWxrIGFjdGlvbnMgKGFscmVhZHkgaGFzIEJ1bGtfU2VsZWN0aW9uKVxuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmFyZ3MuYnVsa19hY3Rpb25zID8gMSA6IDA7XG5cbiAgICAgICAgY29sdW1ucy5mb3JFYWNoKChjb2wsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCAkdGggPSAkKCc8dGg+Jyk7XG5cbiAgICAgICAgICAgIGlmIChjb2wuc29ydGFibGUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHNvcnRhYmxlIGNvbHVtbiBoZWFkZXJcbiAgICAgICAgICAgICAgICBjb25zdCAkc29ydGFibGUgPSAkKCc8ZGl2PicpLmFkZENsYXNzKCdTb3J0YWJsZV9Db2x1bW5fSGVhZGVyJykuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgICdkYXRhLWNvbHVtbic6IGNvbC5maWVsZCxcbiAgICAgICAgICAgICAgICAgICAgJ2RhdGEtc29ydCc6ICdub25lJyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0ICR0ZXh0ID0gJCgnPHNwYW4+JykudGV4dChjb2wubGFiZWwgfHwgY29sLmZpZWxkKTtcbiAgICAgICAgICAgICAgICBjb25zdCAkaWNvbiA9ICQoJzxzcGFuPicpLmF0dHIoJ2RhdGEtaWQnLCAnc29ydF9pY29uJykuaHRtbCgnPGkgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+4oeFPC9pPicpO1xuXG4gICAgICAgICAgICAgICAgJHNvcnRhYmxlLmFwcGVuZCgkdGV4dCkuYXBwZW5kKCcgJykuYXBwZW5kKCRpY29uKTtcbiAgICAgICAgICAgICAgICAkc29ydGFibGUuY3NzKCdjdXJzb3InLCAncG9pbnRlcicpO1xuXG4gICAgICAgICAgICAgICAgJHNvcnRhYmxlLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVfc29ydChjb2wuZmllbGQpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgJHRoLmFwcGVuZCgkc29ydGFibGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAkdGgudGV4dChjb2wubGFiZWwgfHwgY29sLmZpZWxkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbC53aWR0aCkge1xuICAgICAgICAgICAgICAgICR0aC5jc3MoJ3dpZHRoJywgY29sLndpZHRoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJGhlYWRlcl9yb3cuYXBwZW5kKCR0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEFkZCBhY3Rpb25zIGNvbHVtbiBoZWFkZXIgaWYgcm93X2FjdGlvbnMgZW5hYmxlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJvd19hY3Rpb25zKSB7XG4gICAgICAgICAgICBjb25zdCAkdGggPSAkKCc8dGg+JykudGV4dCgnQWN0aW9ucycpLmNzcygnd2lkdGgnLCAnMTAwcHgnKTtcbiAgICAgICAgICAgICRoZWFkZXJfcm93LmFwcGVuZCgkdGgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0dXBfc2VhcmNoKCkge1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kaWQoJ3NlYXJjaF9jb250YWluZXInKTtcbiAgICAgICAgY29uc3QgJHNlYXJjaCA9ICQoJzxpbnB1dD4nKVxuICAgICAgICAgICAgLmF0dHIoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzZWFyY2gnLFxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiAnU2VhcmNoLi4uJyxcbiAgICAgICAgICAgICAgICBjbGFzczogJ2Zvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc20nLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jc3MoJ3dpZHRoJywgJzIwMHB4Jyk7XG5cbiAgICAgICAgJGNvbnRhaW5lci5hcHBlbmQoJHNlYXJjaCk7XG5cbiAgICAgICAgbGV0IHRpbWVvdXQ7XG4gICAgICAgICRzZWFyY2gub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaF9xdWVyeSA9IGUudGFyZ2V0LnZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkX2RhdGEoKTtcbiAgICAgICAgICAgIH0sIDMwMCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNldHVwX2NvbHVtbl90b2dnbGUoKSB7XG4gICAgICAgIGNvbnN0ICRjb250YWluZXIgPSB0aGlzLiRpZCgnY29sdW1uX3RvZ2dsZV9jb250YWluZXInKTtcbiAgICAgICAgY29uc3QgJHRvZ2dsZSA9ICQoJzxkaXY+JykuYWRkQ2xhc3MoJ0NvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZScpO1xuICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkdG9nZ2xlKTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIGNvbXBvbmVudCBtYW51YWxseVxuICAgICAgICBjb25zdCB0b2dnbGVfY29tcG9uZW50ID0gJHRvZ2dsZS5jb21wb25lbnQoKTtcbiAgICAgICAgaWYgKHRvZ2dsZV9jb21wb25lbnQpIHtcbiAgICAgICAgICAgIHRvZ2dsZV9jb21wb25lbnQuYXJncy5jb2x1bW5zID0gdGhpcy5kYXRhLmNvbHVtbnM7XG4gICAgICAgICAgICB0b2dnbGVfY29tcG9uZW50LmFyZ3MudGFibGUgPSB0aGlzLiRpZCgndGFibGUnKS4kO1xuICAgICAgICAgICAgdG9nZ2xlX2NvbXBvbmVudC5idWlsZF9tZW51KHRoaXMuZGF0YS5jb2x1bW5zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldHVwX2J1bGtfYWN0aW9ucygpIHtcbiAgICAgICAgY29uc3QgJGJ1bGtfc2VsZWN0aW9uID0gdGhpcy4kaWQoJ2J1bGtfc2VsZWN0aW9uJyk7XG4gICAgICAgICRidWxrX3NlbGVjdGlvbi4kLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IGUudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgICAgICB0aGlzLiQuZmluZCgnLnJvdy1jaGVja2JveCcpLnByb3AoJ2NoZWNrZWQnLCBjaGVja2VkKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlX2J1bGtfc2VsZWN0aW9uKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVwZGF0ZV9idWxrX3NlbGVjdGlvbigpIHtcbiAgICAgICAgY29uc3QgY2hlY2tlZCA9IHRoaXMuJC5maW5kKCcucm93LWNoZWNrYm94OmNoZWNrZWQnKS5sZW5ndGg7XG4gICAgICAgIGNvbnN0ICRidWxrX2JhciA9IHRoaXMuJGlkKCdidWxrX2JhcicpO1xuXG4gICAgICAgIGlmIChjaGVja2VkID4gMCkge1xuICAgICAgICAgICAgJGJ1bGtfYmFyLiQuc2hvdygpO1xuICAgICAgICAgICAgJGJ1bGtfYmFyLnNldF9jb3VudChjaGVja2VkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRidWxrX2Jhci4kLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGhhbmRsZV9zb3J0KGZpZWxkKSB7XG4gICAgICAgIC8vIFRvZ2dsZSBzb3J0IGRpcmVjdGlvblxuICAgICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5zb3J0X2ZpZWxkID09PSBmaWVsZCA/IHRoaXMuc29ydF9kaXJlY3Rpb24gOiAnbm9uZSc7XG4gICAgICAgIHRoaXMuc29ydF9kaXJlY3Rpb24gPSBjdXJyZW50ID09PSAnbm9uZScgPyAnYXNjJyA6IGN1cnJlbnQgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgIHRoaXMuc29ydF9maWVsZCA9IGZpZWxkO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBzb3J0IGljb25cbiAgICAgICAgdGhpcy4kaWQoJ2hlYWRlcl9yb3cnKVxuICAgICAgICAgICAgLmZpbmQoJ1tkYXRhLWNvbHVtbl0nKVxuICAgICAgICAgICAgLmVhY2goXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCAkc29ydGFibGUgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2wgPSAkc29ydGFibGUuYXR0cignZGF0YS1jb2x1bW4nKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGljb24gPSAkc29ydGFibGUuZmluZCgnW2RhdGEtaWQ9XCJzb3J0X2ljb25cIl0nKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sID09PSBmaWVsZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJHNvcnRhYmxlLmF0dHIoJ2RhdGEtc29ydCcsIHRoaXMuc29ydF9kaXJlY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc29ydF9kaXJlY3Rpb24gPT09ICdhc2MnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGljb24uaHRtbCgnPGkgY2xhc3M9XCJ0ZXh0LXByaW1hcnlcIj7ihpE8L2k+Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc29ydF9kaXJlY3Rpb24gPT09ICdkZXNjJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1wcmltYXJ5XCI+4oaTPC9pPicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaWNvbi5odG1sKCc8aSBjbGFzcz1cInRleHQtbXV0ZWRcIj7ih4U8L2k+Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkc29ydGFibGUuYXR0cignZGF0YS1zb3J0JywgJ25vbmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1tdXRlZFwiPuKHhTwvaT4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKVxuICAgICAgICAgICAgKTtcblxuICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgbG9hZF9wYWdlKHBhZ2UpIHtcbiAgICAgICAgaWYgKHBhZ2UgPCAxIHx8IHBhZ2UgPiB0aGlzLmRhdGEudG90YWxfcGFnZXMpIHJldHVybjtcbiAgICAgICAgdGhpcy5jdXJyZW50X3BhZ2UgPSBwYWdlO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgZmV0Y2hfZGF0YSgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgcGFnZTogdGhpcy5jdXJyZW50X3BhZ2UgfHwgMSxcbiAgICAgICAgICAgIHBlcl9wYWdlOiB0aGlzLmFyZ3MucGVyX3BhZ2UgfHwgMjAsXG4gICAgICAgICAgICBzb3J0X2ZpZWxkOiB0aGlzLnNvcnRfZmllbGQsXG4gICAgICAgICAgICBzb3J0X2RpcmVjdGlvbjogdGhpcy5zb3J0X2RpcmVjdGlvbixcbiAgICAgICAgICAgIHNlYXJjaDogdGhpcy5zZWFyY2hfcXVlcnksXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gQ2FsbCBkYXRhIHNvdXJjZSAoY2FuIGJlIFVSTCBvciBmdW5jdGlvbilcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmFyZ3MuZGF0YV9zb3VyY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFyZ3MuZGF0YV9zb3VyY2UocGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwodGhpcy5hcmdzLmRhdGFfc291cmNlLCB3aW5kb3cubG9jYXRpb24ub3JpZ2luKTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHBhcmFtcykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtc1trZXldKSB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChrZXksIHBhcmFtc1trZXldKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3NlbGVjdGVkX2lkcygpIHtcbiAgICAgICAgY29uc3QgaWRzID0gW107XG4gICAgICAgIHRoaXMuJC5maW5kKCcucm93LWNoZWNrYm94OmNoZWNrZWQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlkcy5wdXNoKCQodGhpcykudmFsKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGlkcztcbiAgICB9XG5cbiAgICBhc3luYyByZWxvYWRfZGF0YSgpIHtcbiAgICAgICAgLy8gU2hvdyBsb2FkaW5nIHN0YXRlXG4gICAgICAgIGNvbnN0ICR0Ym9keSA9IHRoaXMuJGlkKCd0Ym9keScpO1xuICAgICAgICAkdGJvZHkuaHRtbChgXG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49XCIxMDBcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHNwaW5uZXItYm9yZGVyLXNtXCIgcm9sZT1cInN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5Mb2FkaW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgdGV4dC1tdXRlZFwiPkxvYWRpbmcgZGF0YS4uLjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICBgKTtcblxuICAgICAgICAvLyBGZXRjaCBuZXcgZGF0YVxuICAgICAgICB0aGlzLmRhdGEgPSBhd2FpdCB0aGlzLmZldGNoX2RhdGEoKTtcblxuICAgICAgICAvLyBSZS1yZW5kZXIgZW50aXJlIGNvbXBvbmVudFxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbn1cbiIsImNsYXNzIENsaWVudF9TZWxlY3Rvcl9JbnB1dCBleHRlbmRzIEFqYXhfU2VsZWN0X0lucHV0IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICAvLyBMb2FkIGNsaWVudHMgdmlhIEFqYXggZW5kcG9pbnQgaWYgZGF0YSBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBhd2FpdCBGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmdldF9jbGllbnRzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVc2UgcGFyZW50IG9uX2xvYWQgZm9yIGN1c3RvbSBkYXRhIGVuZHBvaW50c1xuICAgICAgICAgICAgYXdhaXQgc3VwZXIub25fbG9hZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBTZXQgZGVmYXVsdCBwbGFjZWhvbGRlciBpZiBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5wbGFjZWhvbGRlciA9ICdTZWxlY3QgQ2xpZW50Li4uJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgQWpheF9TZWxlY3RfSW5wdXRcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX0NvbnRhY3RzX0VkaXQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICAvLyBObyBpbml0aWFsaXphdGlvbiBuZWVkZWQgLSBzdWJtaXQgYnV0dG9uIGF1dG9tYXRpY2FsbHkgd2lyZWQgYnkgUnN4X0Zvcm1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Db250YWN0c19FZGl0LmluaXQoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9Db250YWN0c19WaWV3IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKCcuRnJvbnRlbmRfQ29udGFjdHNfVmlldycpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9Db250YWN0c19WaWV3IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Db250YWN0c19WaWV3LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfQ29udGFjdHMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoJy5Gcm9udGVuZF9Db250YWN0cycpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9Db250YWN0cyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgIC8vICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIC8vIH0pO1xuXG4gICAgICAgIC8vIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgLy8gJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Db250YWN0cy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn1cbiIsIi8qKlxuICogUHJvamVjdHNfRGF0YUdyaWQgQ29tcG9uZW50XG4gKlxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yIHByb2plY3RzIGRhdGFncmlkLlxuICogQWxsIGZ1bmN0aW9uYWxpdHkgaXMgaW4gRGF0YUdyaWRfQWJzdHJhY3QuXG4gKi9cbmNsYXNzIFByb2plY3RzX0RhdGFHcmlkIGV4dGVuZHMgRGF0YUdyaWRfQWJzdHJhY3Qge1xuICAgIC8vIEFsbCBiZWhhdmlvciBpbmhlcml0ZWQgZnJvbSBEYXRhR3JpZF9BYnN0cmFjdFxufVxuIiwiY2xhc3MgRnJvbnRlbmRfUHJvamVjdHNfRWRpdCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIC8vIE5vIGluaXRpYWxpemF0aW9uIG5lZWRlZCAtIHN1Ym1pdCBidXR0b24gYXV0b21hdGljYWxseSB3aXJlZCBieSBSc3hfRm9ybVxuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1Byb2plY3RzX0VkaXQuaW5pdCgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX1Byb2plY3RzX0xpc3Qge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUHJvamVjdHNfTGlzdFwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfUHJvamVjdHNfTGlzdCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Qcm9qZWN0c19MaXN0LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1Byb2plY3RzX1ZpZXcge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUHJvamVjdHNfVmlld1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfUHJvamVjdHNfVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Qcm9qZWN0c19WaWV3LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1Byb2plY3RzX0FkZCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9Qcm9qZWN0c19BZGRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Byb2plY3RzX0FkZCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Qcm9qZWN0c19BZGQuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfUHJvamVjdHMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUHJvamVjdHNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Byb2plY3RzIGluaXRpYWxpemVkJyk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUHJvamVjdHMuaW5pdCgpO1xuICAgIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9UYXNrcyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9UYXNrc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfVGFza3MgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfVGFza3MuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfVGFza3NfVmlldyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9UYXNrc19WaWV3XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9UYXNrc19WaWV3IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1Rhc2tzX1ZpZXcuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfVGFza3NfQWRkIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1Rhc2tzX0FkZFwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfVGFza3NfQWRkIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1Rhc2tzX0FkZC5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9DYWxlbmRhciB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9DYWxlbmRhclwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfQ2FsZW5kYXIgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfQ2FsZW5kYXIuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX0NhbGVuZGFyX0V2ZW50IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0NhbGVuZGFyX0V2ZW50LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX0ludm9pY2VzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX0ludm9pY2VzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9JbnZvaWNlcyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9JbnZvaWNlcy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9JbnZvaWNlc19WaWV3IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX0ludm9pY2VzX1ZpZXdcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX0ludm9pY2VzX1ZpZXcgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfSW52b2ljZXNfVmlldy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCIvKipcbiAqIEZyb250ZW5kX0ludm9pY2VzX0FkZCBDb21wb25lbnRcbiAqXG4gKiBIYW5kbGVzIGR5bmFtaWMgbGluZSBpdGVtcyBhbmQgaW52b2ljZSBjYWxjdWxhdGlvbnNcbiAqL1xuY2xhc3MgRnJvbnRlbmRfSW52b2ljZXNfQWRkIHtcbiAgICBzdGF0aWMgbGluZV9pdGVtX2NvdW50ID0gMTtcblxuICAgIHN0YXRpYyBhc3luYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9JbnZvaWNlc19BZGRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBBZGQgbGluZSBpdGVtIGJ1dHRvblxuICAgICAgICAkKCcjYWRkTGluZUl0ZW0nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQuYWRkX2xpbmVfaXRlbSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJbml0aWFsIGNhbGN1bGF0aW9uXG4gICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5jYWxjdWxhdGVfdG90YWxzKCk7XG5cbiAgICAgICAgLy8gQXR0YWNoIGV2ZW50IGhhbmRsZXJzIHRvIGV4aXN0aW5nIGxpbmUgaXRlbXNcbiAgICAgICAgRnJvbnRlbmRfSW52b2ljZXNfQWRkLmF0dGFjaF9saW5lX2l0ZW1faGFuZGxlcnMoKTtcblxuICAgICAgICAvLyBUYXggcmF0ZSBjaGFuZ2VcbiAgICAgICAgJCgnI3RheF9yYXRlJykub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgRnJvbnRlbmRfSW52b2ljZXNfQWRkLmNhbGN1bGF0ZV90b3RhbHMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGF0dGFjaF9saW5lX2l0ZW1faGFuZGxlcnMoKSB7XG4gICAgICAgIC8vIFF1YW50aXR5IGFuZCByYXRlIGNoYW5nZXNcbiAgICAgICAgJCgnLml0ZW0tcXVhbnRpdHksIC5pdGVtLXJhdGUnKS5vZmYoJ2lucHV0Jykub24oJ2lucHV0JywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQudXBkYXRlX2xpbmVfaXRlbV9hbW91bnQoJCh0aGlzKS5jbG9zZXN0KCd0cicpKTtcbiAgICAgICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5jYWxjdWxhdGVfdG90YWxzKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlbW92ZSBpdGVtIGJ1dHRvbnNcbiAgICAgICAgJCgnLnJlbW92ZS1pdGVtJykub2ZmKCdjbGljaycpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJHJvdyA9ICQodGhpcykuY2xvc2VzdCgndHInKTtcbiAgICAgICAgICAgIGlmICgkKCcjbGluZUl0ZW1zQm9keSB0cicpLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAkcm93LnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5jYWxjdWxhdGVfdG90YWxzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFsZXJ0KCdJbnZvaWNlIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgbGluZSBpdGVtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBhZGRfbGluZV9pdGVtKCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IEZyb250ZW5kX0ludm9pY2VzX0FkZC5saW5lX2l0ZW1fY291bnQrKztcbiAgICAgICAgY29uc3QgJHJvdyA9ICQoYFxuICAgICAgICAgICAgPHRyIGNsYXNzPVwibGluZS1pdGVtXCI+XG4gICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiBuYW1lPVwiaXRlbXNbJHtpbmRleH1dW2Rlc2NyaXB0aW9uXVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkl0ZW0gZGVzY3JpcHRpb25cIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc20gdGV4dC1lbmQgaXRlbS1xdWFudGl0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiaXRlbXNbJHtpbmRleH1dW3F1YW50aXR5XVwiIHZhbHVlPVwiMVwiIG1pbj1cIjBcIiBzdGVwPVwiMC4wMVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAgaW5wdXQtZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPiQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHRleHQtZW5kIGl0ZW0tcmF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cIml0ZW1zWyR7aW5kZXh9XVtyYXRlXVwiIHZhbHVlPVwiMC4wMFwiIG1pbj1cIjBcIiBzdGVwPVwiMC4wMVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtZW5kXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy1ib2xkIGl0ZW0tYW1vdW50XCI+JDAuMDA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tZGFuZ2VyIHJlbW92ZS1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgYCk7XG5cbiAgICAgICAgJCgnI2xpbmVJdGVtc0JvZHknKS5hcHBlbmQoJHJvdyk7XG4gICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5hdHRhY2hfbGluZV9pdGVtX2hhbmRsZXJzKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIHVwZGF0ZV9saW5lX2l0ZW1fYW1vdW50KHJvdykge1xuICAgICAgICBjb25zdCBxdWFudGl0eSA9IGZsb2F0KHJvdy5maW5kKCcuaXRlbS1xdWFudGl0eScpLnZhbCgpKSB8fCAwO1xuICAgICAgICBjb25zdCByYXRlID0gZmxvYXQocm93LmZpbmQoJy5pdGVtLXJhdGUnKS52YWwoKSkgfHwgMDtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gcXVhbnRpdHkgKiByYXRlO1xuXG4gICAgICAgIHJvdy5maW5kKCcuaXRlbS1hbW91bnQnKS50ZXh0KGAkJHthbW91bnQudG9GaXhlZCgyKX1gKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY2FsY3VsYXRlX3RvdGFscygpIHtcbiAgICAgICAgbGV0IHN1YnRvdGFsID0gMDtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgc3VidG90YWwgZnJvbSBhbGwgbGluZSBpdGVtc1xuICAgICAgICAkKCcjbGluZUl0ZW1zQm9keSB0cicpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCBxdWFudGl0eSA9IGZsb2F0KCQodGhpcykuZmluZCgnLml0ZW0tcXVhbnRpdHknKS52YWwoKSkgfHwgMDtcbiAgICAgICAgICAgIGNvbnN0IHJhdGUgPSBmbG9hdCgkKHRoaXMpLmZpbmQoJy5pdGVtLXJhdGUnKS52YWwoKSkgfHwgMDtcbiAgICAgICAgICAgIHN1YnRvdGFsICs9IHF1YW50aXR5ICogcmF0ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRheFxuICAgICAgICBjb25zdCB0YXhfcmF0ZSA9IGZsb2F0KCQoJyN0YXhfcmF0ZScpLnZhbCgpKSB8fCAwO1xuICAgICAgICBjb25zdCB0YXhfYW1vdW50ID0gc3VidG90YWwgKiAodGF4X3JhdGUgLyAxMDApO1xuICAgICAgICBjb25zdCB0b3RhbCA9IHN1YnRvdGFsICsgdGF4X2Ftb3VudDtcblxuICAgICAgICAvLyBVcGRhdGUgZGlzcGxheXNcbiAgICAgICAgJCgnI3N1YnRvdGFsRGlzcGxheScpLnRleHQoYCQke3N1YnRvdGFsLnRvRml4ZWQoMil9YCk7XG4gICAgICAgICQoJyN0YXhEaXNwbGF5JykudGV4dChgJCR7dGF4X2Ftb3VudC50b0ZpeGVkKDIpfWApO1xuICAgICAgICAkKCcjdG90YWxEaXNwbGF5JykudGV4dChgJCR7dG90YWwudG9GaXhlZCgyKX1gKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9SZXBvcnRzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1JlcG9ydHNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1JlcG9ydHMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUmVwb3J0cy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9SZXBvcnRzX1JldmVudWUge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9SZXBvcnRzX1JldmVudWUgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1JlcG9ydHNfQ2xpZW50cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9SZXBvcnRzX0NsaWVudHNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1JlcG9ydHNfQ2xpZW50cyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9SZXBvcnRzX0NsaWVudHMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9SZXBvcnRzX1Byb2plY3RzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9SZXBvcnRzX1Byb2plY3RzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1JlcG9ydHNfUHJvamVjdHMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfUmVwb3J0c19UaW1lIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1JlcG9ydHNfVGltZVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfUmVwb3J0c19UaW1lIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1JlcG9ydHNfVGltZS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCIvKipcbiAqIEphdmFTY3JpcHQgZm9yIEZyb250ZW5kX0FjY291bnQgdmlld1xuICovXG5jbGFzcyBGcm9udGVuZF9BY2NvdW50IHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoZSB2aWV3IHdoZW4gYXBwIGlzIHJlYWR5XG4gICAgICogVGhpcyBtZXRob2QgaXMgYXV0b21hdGljYWxseSBjYWxsZWQgYnkgUlNYIGZyYW1ld29ya1xuICAgICAqIE5vIG1hbnVhbCByZWdpc3RyYXRpb24gaXMgcmVxdWlyZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiB0aGlzIHNwZWNpZmljIHBhZ2VcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX0FjY291bnRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBWaWV3LXNwZWNpZmljIGluaXRpYWxpemF0aW9uXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9BY2NvdW50IGluaXRpYWxpemVkJyk7XG4gICAgfVxufSIsIi8qKlxuICogQXV0by1nZW5lcmF0ZWQgSmF2YVNjcmlwdCBzdHViIGZvciBSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyIHtcbiAgICAvKipcbiAgICAgKiBDYWxsIFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyOjpjb3VudHJpZXMgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBjb3VudHJpZXMocGFyYW1zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIEFqYXguY2FsbCgnL19hamF4L1JzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyL2NvdW50cmllcycsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlcjo6c3RhdGVzIHZpYSBBamF4LmNhbGwoKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIG9iamVjdCB0byBwYXNzIHRvIHRoZSBtZXRob2RcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgc3RhdGVzKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Sc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci9zdGF0ZXMnLCBwYXJhbXMpO1xuICAgIH1cblxufVxuXG4vLyBQYXRoIHByb3BlcnRpZXMgZm9yIHR5cGUtc2FmZSByb3V0aW5nXG5Sc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci5jb3VudHJpZXMucGF0aCA9ICcvX2FqYXgvUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIvY291bnRyaWVzJztcblJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLnN0YXRlcy5wYXRoID0gJy9fYWpheC9Sc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci9zdGF0ZXMnO1xuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIENsaWVudF9EZXBhcnRtZW50X01vZGVsXG4gKiBETyBOT1QgRURJVCAtIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGVkXG4gKi9cblxuY2xhc3MgQ2xpZW50X0RlcGFydG1lbnRfTW9kZWwgZXh0ZW5kcyBSc3hfSnNfTW9kZWwge1xuICAgIHN0YXRpYyBnZXQgbmFtZSgpIHtcbiAgICAgICAgcmV0dXJuICdDbGllbnRfRGVwYXJ0bWVudF9Nb2RlbCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY2xpZW50IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgY2xpZW50KCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9DbGllbnRfRGVwYXJ0bWVudF9Nb2RlbC8ke3RoaXMuaWR9L2NsaWVudGAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY29udGFjdHMgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBjb250YWN0cygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ2xpZW50X0RlcGFydG1lbnRfTW9kZWwvJHt0aGlzLmlkfS9jb250YWN0c2AsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY3JlYXRlZF9ieSByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZWRfYnkoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL0NsaWVudF9EZXBhcnRtZW50X01vZGVsLyR7dGhpcy5pZH0vY3JlYXRlZF9ieWAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG59XG4iLCIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIEphdmFTY3JpcHQgc3R1YiBmb3IgQ2xpZW50X01vZGVsXG4gKiBETyBOT1QgRURJVCAtIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGVkXG4gKi9cblxuY2xhc3MgQ2xpZW50X01vZGVsIGV4dGVuZHMgUnN4X0pzX01vZGVsIHtcbiAgICBzdGF0aWMgZ2V0IG5hbWUoKSB7XG4gICAgICAgIHJldHVybiAnQ2xpZW50X01vZGVsJztcbiAgICB9XG5cbiAgICBzdGF0aWMgUFJJT1JJVFlfTE9XID0gMTtcbiAgICBzdGF0aWMgUFJJT1JJVFlfTUVESVVNID0gMjtcbiAgICBzdGF0aWMgUFJJT1JJVFlfSElHSCA9IDM7XG4gICAgc3RhdGljIFBSSU9SSVRZX1VSR0VOVCA9IDQ7XG5cbiAgICBzdGF0aWMgcHJpb3JpdHlfZW51bV92YWwoKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSBbXTtcbiAgICAgICAgZGF0YVsxXSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9MT1dcIixcImxhYmVsXCI6XCJMb3dcIixcImJhZGdlXCI6XCJiZy1zZWNvbmRhcnlcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMSk7XG4gICAgICAgIGRhdGFbMl0gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfTUVESVVNXCIsXCJsYWJlbFwiOlwiTWVkaXVtXCIsXCJiYWRnZVwiOlwiYmctcHJpbWFyeVwifTtcbiAgICAgICAgb3JkZXIucHVzaCgyKTtcbiAgICAgICAgZGF0YVszXSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9ISUdIXCIsXCJsYWJlbFwiOlwiSGlnaFwiLFwiYmFkZ2VcIjpcImJnLXdhcm5pbmdcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMyk7XG4gICAgICAgIGRhdGFbNF0gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfVVJHRU5UXCIsXCJsYWJlbFwiOlwiVXJnZW50XCIsXCJiYWRnZVwiOlwiYmctZGFuZ2VyXCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDQpO1xuICAgICAgICAvLyBSZXR1cm4gUHJveHkgdGhhdCBtYWludGFpbnMgc29ydCBvcmRlciBmb3IgZW51bWVyYXRpb25cbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eShkYXRhLCB7XG4gICAgICAgICAgICBvd25LZXlzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmRlci5tYXAoU3RyaW5nKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRhcmdldFtwcm9wXVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIHByaW9yaXR5X2xhYmVsX2xpc3QoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xuICAgICAgICB2YWx1ZXNbMV0gPSAnTG93JztcbiAgICAgICAgdmFsdWVzWzJdID0gJ01lZGl1bSc7XG4gICAgICAgIHZhbHVlc1szXSA9ICdIaWdoJztcbiAgICAgICAgdmFsdWVzWzRdID0gJ1VyZ2VudCc7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgc3RhdGljIHByaW9yaXR5X2VudW1fc2VsZWN0KCkge1xuICAgICAgICBjb25zdCBmdWxsRGF0YSA9IHRoaXMucHJpb3JpdHlfZW51bV92YWwoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBcbiAgICAgICAgLy8gRXh0cmFjdCBsYWJlbHMgZnJvbSBmdWxsIGRhdGEsIHJlc3BlY3Rpbmcgc2VsZWN0YWJsZSBmbGFnXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZ1bGxEYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gZnVsbERhdGFba2V5XTtcbiAgICAgICAgICAgIGlmIChpdGVtLnNlbGVjdGFibGUgIT09IGZhbHNlICYmIGl0ZW0ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBkYXRhW2tleV0gPSBpdGVtLmxhYmVsO1xuICAgICAgICAgICAgICAgIG9yZGVyLnB1c2gocGFyc2VJbnQoa2V5KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBiaWxsaW5nX2NvbnRhY3QgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBiaWxsaW5nX2NvbnRhY3QoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL0NsaWVudF9Nb2RlbC8ke3RoaXMuaWR9L2JpbGxpbmdfY29udGFjdGAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY29udGFjdHMgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBjb250YWN0cygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ2xpZW50X01vZGVsLyR7dGhpcy5pZH0vY29udGFjdHNgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGRlcGFydG1lbnRzIHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgZGVwYXJ0bWVudHMoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL0NsaWVudF9Nb2RlbC8ke3RoaXMuaWR9L2RlcGFydG1lbnRzYCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBjcmVhdGVkX2J5IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlZF9ieSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ2xpZW50X01vZGVsLyR7dGhpcy5pZH0vY3JlYXRlZF9ieWAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggb3duZXIgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBvd25lcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ2xpZW50X01vZGVsLyR7dGhpcy5pZH0vb3duZXJgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxufVxuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIENvbnRhY3RfTW9kZWxcbiAqIERPIE5PVCBFRElUIC0gVGhpcyBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgcmVnZW5lcmF0ZWRcbiAqL1xuXG5jbGFzcyBDb250YWN0X01vZGVsIGV4dGVuZHMgUnN4X0pzX01vZGVsIHtcbiAgICBzdGF0aWMgZ2V0IG5hbWUoKSB7XG4gICAgICAgIHJldHVybiAnQ29udGFjdF9Nb2RlbCc7XG4gICAgfVxuXG4gICAgc3RhdGljIFBSSU9SSVRZX0xPVyA9IDE7XG4gICAgc3RhdGljIFBSSU9SSVRZX01FRElVTSA9IDI7XG4gICAgc3RhdGljIFBSSU9SSVRZX0hJR0ggPSAzO1xuICAgIHN0YXRpYyBQUklPUklUWV9VUkdFTlQgPSA0O1xuXG4gICAgc3RhdGljIHByaW9yaXR5X2VudW1fdmFsKCkge1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgIGNvbnN0IG9yZGVyID0gW107XG4gICAgICAgIGRhdGFbMV0gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfTE9XXCIsXCJsYWJlbFwiOlwiTG93XCIsXCJiYWRnZVwiOlwiYmctc2Vjb25kYXJ5XCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDEpO1xuICAgICAgICBkYXRhWzJdID0ge1wiY29uc3RhbnRcIjpcIlBSSU9SSVRZX01FRElVTVwiLFwibGFiZWxcIjpcIk1lZGl1bVwiLFwiYmFkZ2VcIjpcImJnLXByaW1hcnlcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMik7XG4gICAgICAgIGRhdGFbM10gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfSElHSFwiLFwibGFiZWxcIjpcIkhpZ2hcIixcImJhZGdlXCI6XCJiZy13YXJuaW5nXCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDMpO1xuICAgICAgICBkYXRhWzRdID0ge1wiY29uc3RhbnRcIjpcIlBSSU9SSVRZX1VSR0VOVFwiLFwibGFiZWxcIjpcIlVyZ2VudFwiLFwiYmFkZ2VcIjpcImJnLWRhbmdlclwifTtcbiAgICAgICAgb3JkZXIucHVzaCg0KTtcbiAgICAgICAgLy8gUmV0dXJuIFByb3h5IHRoYXQgbWFpbnRhaW5zIHNvcnQgb3JkZXIgZm9yIGVudW1lcmF0aW9uXG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoZGF0YSwge1xuICAgICAgICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JkZXIubWFwKFN0cmluZyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wIGluIHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0YXJnZXRbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBwcmlvcml0eV9sYWJlbF9saXN0KCkge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSB7fTtcbiAgICAgICAgdmFsdWVzWzFdID0gJ0xvdyc7XG4gICAgICAgIHZhbHVlc1syXSA9ICdNZWRpdW0nO1xuICAgICAgICB2YWx1ZXNbM10gPSAnSGlnaCc7XG4gICAgICAgIHZhbHVlc1s0XSA9ICdVcmdlbnQnO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIHN0YXRpYyBwcmlvcml0eV9lbnVtX3NlbGVjdCgpIHtcbiAgICAgICAgY29uc3QgZnVsbERhdGEgPSB0aGlzLnByaW9yaXR5X2VudW1fdmFsKCk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSBbXTtcbiAgICAgICAgXG4gICAgICAgIC8vIEV4dHJhY3QgbGFiZWxzIGZyb20gZnVsbCBkYXRhLCByZXNwZWN0aW5nIHNlbGVjdGFibGUgZmxhZ1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBmdWxsRGF0YSkge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IGZ1bGxEYXRhW2tleV07XG4gICAgICAgICAgICBpZiAoaXRlbS5zZWxlY3RhYmxlICE9PSBmYWxzZSAmJiBpdGVtLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgZGF0YVtrZXldID0gaXRlbS5sYWJlbDtcbiAgICAgICAgICAgICAgICBvcmRlci5wdXNoKHBhcnNlSW50KGtleSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBSZXR1cm4gUHJveHkgdGhhdCBtYWludGFpbnMgc29ydCBvcmRlciBmb3IgZW51bWVyYXRpb25cbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eShkYXRhLCB7XG4gICAgICAgICAgICBvd25LZXlzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmRlci5tYXAoU3RyaW5nKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRhcmdldFtwcm9wXVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY2xpZW50IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgY2xpZW50KCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9Db250YWN0X01vZGVsLyR7dGhpcy5pZH0vY2xpZW50YCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBkZXBhcnRtZW50IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgZGVwYXJ0bWVudCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ29udGFjdF9Nb2RlbC8ke3RoaXMuaWR9L2RlcGFydG1lbnRgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIHJlcG9ydHNfdG8gcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyByZXBvcnRzX3RvKCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9Db250YWN0X01vZGVsLyR7dGhpcy5pZH0vcmVwb3J0c190b2AsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggZGlyZWN0X3JlcG9ydHMgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBkaXJlY3RfcmVwb3J0cygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ29udGFjdF9Nb2RlbC8ke3RoaXMuaWR9L2RpcmVjdF9yZXBvcnRzYCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBjcmVhdGVkX2J5IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlZF9ieSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvQ29udGFjdF9Nb2RlbC8ke3RoaXMuaWR9L2NyZWF0ZWRfYnlgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIG93bmVyIHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgb3duZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL0NvbnRhY3RfTW9kZWwvJHt0aGlzLmlkfS9vd25lcmAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG59XG4iLCIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIEphdmFTY3JpcHQgc3R1YiBmb3IgUHJvamVjdF9Nb2RlbFxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIFByb2plY3RfTW9kZWwgZXh0ZW5kcyBSc3hfSnNfTW9kZWwge1xuICAgIHN0YXRpYyBnZXQgbmFtZSgpIHtcbiAgICAgICAgcmV0dXJuICdQcm9qZWN0X01vZGVsJztcbiAgICB9XG5cbiAgICBzdGF0aWMgU1RBVFVTX1BMQU5OSU5HID0gMTtcbiAgICBzdGF0aWMgU1RBVFVTX0FDVElWRSA9IDI7XG4gICAgc3RhdGljIFNUQVRVU19PTl9IT0xEID0gMztcbiAgICBzdGF0aWMgU1RBVFVTX0NPTVBMRVRFRCA9IDQ7XG4gICAgc3RhdGljIFNUQVRVU19DQU5DRUxMRUQgPSA1O1xuXG4gICAgc3RhdGljIHN0YXR1c19lbnVtX3ZhbCgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBkYXRhWzFdID0ge1wiY29uc3RhbnRcIjpcIlNUQVRVU19QTEFOTklOR1wiLFwibGFiZWxcIjpcIlBsYW5uaW5nXCIsXCJiYWRnZVwiOlwiYmctaW5mb1wifTtcbiAgICAgICAgb3JkZXIucHVzaCgxKTtcbiAgICAgICAgZGF0YVsyXSA9IHtcImNvbnN0YW50XCI6XCJTVEFUVVNfQUNUSVZFXCIsXCJsYWJlbFwiOlwiQWN0aXZlXCIsXCJiYWRnZVwiOlwiYmctc3VjY2Vzc1wifTtcbiAgICAgICAgb3JkZXIucHVzaCgyKTtcbiAgICAgICAgZGF0YVszXSA9IHtcImNvbnN0YW50XCI6XCJTVEFUVVNfT05fSE9MRFwiLFwibGFiZWxcIjpcIk9uIEhvbGRcIixcImJhZGdlXCI6XCJiZy13YXJuaW5nXCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDMpO1xuICAgICAgICBkYXRhWzRdID0ge1wiY29uc3RhbnRcIjpcIlNUQVRVU19DT01QTEVURURcIixcImxhYmVsXCI6XCJDb21wbGV0ZWRcIixcImJhZGdlXCI6XCJiZy1wcmltYXJ5XCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDQpO1xuICAgICAgICBkYXRhWzVdID0ge1wiY29uc3RhbnRcIjpcIlNUQVRVU19DQU5DRUxMRURcIixcImxhYmVsXCI6XCJDYW5jZWxsZWRcIixcImJhZGdlXCI6XCJiZy1zZWNvbmRhcnlcIn07XG4gICAgICAgIG9yZGVyLnB1c2goNSk7XG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgc3RhdHVzX2xhYmVsX2xpc3QoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xuICAgICAgICB2YWx1ZXNbMV0gPSAnUGxhbm5pbmcnO1xuICAgICAgICB2YWx1ZXNbMl0gPSAnQWN0aXZlJztcbiAgICAgICAgdmFsdWVzWzNdID0gJ09uIEhvbGQnO1xuICAgICAgICB2YWx1ZXNbNF0gPSAnQ29tcGxldGVkJztcbiAgICAgICAgdmFsdWVzWzVdID0gJ0NhbmNlbGxlZCc7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgc3RhdGljIHN0YXR1c19lbnVtX3NlbGVjdCgpIHtcbiAgICAgICAgY29uc3QgZnVsbERhdGEgPSB0aGlzLnN0YXR1c19lbnVtX3ZhbCgpO1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgIGNvbnN0IG9yZGVyID0gW107XG4gICAgICAgIFxuICAgICAgICAvLyBFeHRyYWN0IGxhYmVscyBmcm9tIGZ1bGwgZGF0YSwgcmVzcGVjdGluZyBzZWxlY3RhYmxlIGZsYWdcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnVsbERhdGEpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBmdWxsRGF0YVtrZXldO1xuICAgICAgICAgICAgaWYgKGl0ZW0uc2VsZWN0YWJsZSAhPT0gZmFsc2UgJiYgaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IGl0ZW0ubGFiZWw7XG4gICAgICAgICAgICAgICAgb3JkZXIucHVzaChwYXJzZUludChrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gUmV0dXJuIFByb3h5IHRoYXQgbWFpbnRhaW5zIHNvcnQgb3JkZXIgZm9yIGVudW1lcmF0aW9uXG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoZGF0YSwge1xuICAgICAgICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JkZXIubWFwKFN0cmluZyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wIGluIHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0YXJnZXRbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBQUklPUklUWV9MT1cgPSAxO1xuICAgIHN0YXRpYyBQUklPUklUWV9NRURJVU0gPSAyO1xuICAgIHN0YXRpYyBQUklPUklUWV9ISUdIID0gMztcbiAgICBzdGF0aWMgUFJJT1JJVFlfVVJHRU5UID0gNDtcblxuICAgIHN0YXRpYyBwcmlvcml0eV9lbnVtX3ZhbCgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBkYXRhWzFdID0ge1wiY29uc3RhbnRcIjpcIlBSSU9SSVRZX0xPV1wiLFwibGFiZWxcIjpcIkxvd1wiLFwiYmFkZ2VcIjpcImJnLXNlY29uZGFyeVwifTtcbiAgICAgICAgb3JkZXIucHVzaCgxKTtcbiAgICAgICAgZGF0YVsyXSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9NRURJVU1cIixcImxhYmVsXCI6XCJNZWRpdW1cIixcImJhZGdlXCI6XCJiZy1wcmltYXJ5XCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDIpO1xuICAgICAgICBkYXRhWzNdID0ge1wiY29uc3RhbnRcIjpcIlBSSU9SSVRZX0hJR0hcIixcImxhYmVsXCI6XCJIaWdoXCIsXCJiYWRnZVwiOlwiYmctd2FybmluZ1wifTtcbiAgICAgICAgb3JkZXIucHVzaCgzKTtcbiAgICAgICAgZGF0YVs0XSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9VUkdFTlRcIixcImxhYmVsXCI6XCJVcmdlbnRcIixcImJhZGdlXCI6XCJiZy1kYW5nZXJcIn07XG4gICAgICAgIG9yZGVyLnB1c2goNCk7XG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcHJpb3JpdHlfbGFiZWxfbGlzdCgpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0ge307XG4gICAgICAgIHZhbHVlc1sxXSA9ICdMb3cnO1xuICAgICAgICB2YWx1ZXNbMl0gPSAnTWVkaXVtJztcbiAgICAgICAgdmFsdWVzWzNdID0gJ0hpZ2gnO1xuICAgICAgICB2YWx1ZXNbNF0gPSAnVXJnZW50JztcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICBzdGF0aWMgcHJpb3JpdHlfZW51bV9zZWxlY3QoKSB7XG4gICAgICAgIGNvbnN0IGZ1bGxEYXRhID0gdGhpcy5wcmlvcml0eV9lbnVtX3ZhbCgpO1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgIGNvbnN0IG9yZGVyID0gW107XG4gICAgICAgIFxuICAgICAgICAvLyBFeHRyYWN0IGxhYmVscyBmcm9tIGZ1bGwgZGF0YSwgcmVzcGVjdGluZyBzZWxlY3RhYmxlIGZsYWdcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnVsbERhdGEpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBmdWxsRGF0YVtrZXldO1xuICAgICAgICAgICAgaWYgKGl0ZW0uc2VsZWN0YWJsZSAhPT0gZmFsc2UgJiYgaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IGl0ZW0ubGFiZWw7XG4gICAgICAgICAgICAgICAgb3JkZXIucHVzaChwYXJzZUludChrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gUmV0dXJuIFByb3h5IHRoYXQgbWFpbnRhaW5zIHNvcnQgb3JkZXIgZm9yIGVudW1lcmF0aW9uXG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoZGF0YSwge1xuICAgICAgICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JkZXIubWFwKFN0cmluZyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wIGluIHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0YXJnZXRbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGNsaWVudCByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIGNsaWVudCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvUHJvamVjdF9Nb2RlbC8ke3RoaXMuaWR9L2NsaWVudGAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY2xpZW50X2RlcGFydG1lbnQgcmVsYXRpb25zaGlwXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFJlbGF0ZWQgbW9kZWwgaW5zdGFuY2Uocykgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBhc3luYyBjbGllbnRfZGVwYXJ0bWVudCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvUHJvamVjdF9Nb2RlbC8ke3RoaXMuaWR9L2NsaWVudF9kZXBhcnRtZW50YCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBjb250YWN0IHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgY29udGFjdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCBmZXRjaCByZWxhdGlvbnNoaXAgd2l0aG91dCBpZCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaF9yZWwvUHJvamVjdF9Nb2RlbC8ke3RoaXMuaWR9L2NvbnRhY3RgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIHRhc2tzIHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgdGFza3MoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL1Byb2plY3RfTW9kZWwvJHt0aGlzLmlkfS90YXNrc2AsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY3JlYXRlZF9ieSByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZWRfYnkoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL1Byb2plY3RfTW9kZWwvJHt0aGlzLmlkfS9jcmVhdGVkX2J5YCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBvd25lciByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIG93bmVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9Qcm9qZWN0X01vZGVsLyR7dGhpcy5pZH0vb3duZXJgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxufVxuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIFRhc2tfTW9kZWxcbiAqIERPIE5PVCBFRElUIC0gVGhpcyBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgcmVnZW5lcmF0ZWRcbiAqL1xuXG5jbGFzcyBUYXNrX01vZGVsIGV4dGVuZHMgUnN4X0pzX01vZGVsIHtcbiAgICBzdGF0aWMgZ2V0IG5hbWUoKSB7XG4gICAgICAgIHJldHVybiAnVGFza19Nb2RlbCc7XG4gICAgfVxuXG4gICAgc3RhdGljIFNUQVRVU19QRU5ESU5HID0gMTtcbiAgICBzdGF0aWMgU1RBVFVTX0lOX1BST0dSRVNTID0gMjtcbiAgICBzdGF0aWMgU1RBVFVTX0NPTVBMRVRFRCA9IDM7XG4gICAgc3RhdGljIFNUQVRVU19DQU5DRUxMRUQgPSA0O1xuXG4gICAgc3RhdGljIHN0YXR1c19lbnVtX3ZhbCgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBkYXRhWzFdID0ge1wiY29uc3RhbnRcIjpcIlNUQVRVU19QRU5ESU5HXCIsXCJsYWJlbFwiOlwiUGVuZGluZ1wiLFwiYmFkZ2VcIjpcImJnLXNlY29uZGFyeVwifTtcbiAgICAgICAgb3JkZXIucHVzaCgxKTtcbiAgICAgICAgZGF0YVsyXSA9IHtcImNvbnN0YW50XCI6XCJTVEFUVVNfSU5fUFJPR1JFU1NcIixcImxhYmVsXCI6XCJJbiBQcm9ncmVzc1wiLFwiYmFkZ2VcIjpcImJnLWluZm9cIn07XG4gICAgICAgIG9yZGVyLnB1c2goMik7XG4gICAgICAgIGRhdGFbM10gPSB7XCJjb25zdGFudFwiOlwiU1RBVFVTX0NPTVBMRVRFRFwiLFwibGFiZWxcIjpcIkNvbXBsZXRlZFwiLFwiYmFkZ2VcIjpcImJnLXN1Y2Nlc3NcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMyk7XG4gICAgICAgIGRhdGFbNF0gPSB7XCJjb25zdGFudFwiOlwiU1RBVFVTX0NBTkNFTExFRFwiLFwibGFiZWxcIjpcIkNhbmNlbGxlZFwiLFwiYmFkZ2VcIjpcImJnLWRhbmdlclwifTtcbiAgICAgICAgb3JkZXIucHVzaCg0KTtcbiAgICAgICAgLy8gUmV0dXJuIFByb3h5IHRoYXQgbWFpbnRhaW5zIHNvcnQgb3JkZXIgZm9yIGVudW1lcmF0aW9uXG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoZGF0YSwge1xuICAgICAgICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JkZXIubWFwKFN0cmluZyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wIGluIHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0YXJnZXRbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBzdGF0dXNfbGFiZWxfbGlzdCgpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0ge307XG4gICAgICAgIHZhbHVlc1sxXSA9ICdQZW5kaW5nJztcbiAgICAgICAgdmFsdWVzWzJdID0gJ0luIFByb2dyZXNzJztcbiAgICAgICAgdmFsdWVzWzNdID0gJ0NvbXBsZXRlZCc7XG4gICAgICAgIHZhbHVlc1s0XSA9ICdDYW5jZWxsZWQnO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIHN0YXRpYyBzdGF0dXNfZW51bV9zZWxlY3QoKSB7XG4gICAgICAgIGNvbnN0IGZ1bGxEYXRhID0gdGhpcy5zdGF0dXNfZW51bV92YWwoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBcbiAgICAgICAgLy8gRXh0cmFjdCBsYWJlbHMgZnJvbSBmdWxsIGRhdGEsIHJlc3BlY3Rpbmcgc2VsZWN0YWJsZSBmbGFnXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZ1bGxEYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gZnVsbERhdGFba2V5XTtcbiAgICAgICAgICAgIGlmIChpdGVtLnNlbGVjdGFibGUgIT09IGZhbHNlICYmIGl0ZW0ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBkYXRhW2tleV0gPSBpdGVtLmxhYmVsO1xuICAgICAgICAgICAgICAgIG9yZGVyLnB1c2gocGFyc2VJbnQoa2V5KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgUFJJT1JJVFlfTE9XID0gMTtcbiAgICBzdGF0aWMgUFJJT1JJVFlfTUVESVVNID0gMjtcbiAgICBzdGF0aWMgUFJJT1JJVFlfSElHSCA9IDM7XG4gICAgc3RhdGljIFBSSU9SSVRZX1VSR0VOVCA9IDQ7XG5cbiAgICBzdGF0aWMgcHJpb3JpdHlfZW51bV92YWwoKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSBbXTtcbiAgICAgICAgZGF0YVsxXSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9MT1dcIixcImxhYmVsXCI6XCJMb3dcIixcImJhZGdlXCI6XCJiZy1zZWNvbmRhcnlcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMSk7XG4gICAgICAgIGRhdGFbMl0gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfTUVESVVNXCIsXCJsYWJlbFwiOlwiTWVkaXVtXCIsXCJiYWRnZVwiOlwiYmctcHJpbWFyeVwifTtcbiAgICAgICAgb3JkZXIucHVzaCgyKTtcbiAgICAgICAgZGF0YVszXSA9IHtcImNvbnN0YW50XCI6XCJQUklPUklUWV9ISUdIXCIsXCJsYWJlbFwiOlwiSGlnaFwiLFwiYmFkZ2VcIjpcImJnLXdhcm5pbmdcIn07XG4gICAgICAgIG9yZGVyLnB1c2goMyk7XG4gICAgICAgIGRhdGFbNF0gPSB7XCJjb25zdGFudFwiOlwiUFJJT1JJVFlfVVJHRU5UXCIsXCJsYWJlbFwiOlwiVXJnZW50XCIsXCJiYWRnZVwiOlwiYmctZGFuZ2VyXCJ9O1xuICAgICAgICBvcmRlci5wdXNoKDQpO1xuICAgICAgICAvLyBSZXR1cm4gUHJveHkgdGhhdCBtYWludGFpbnMgc29ydCBvcmRlciBmb3IgZW51bWVyYXRpb25cbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eShkYXRhLCB7XG4gICAgICAgICAgICBvd25LZXlzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmRlci5tYXAoU3RyaW5nKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRhcmdldFtwcm9wXVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIHByaW9yaXR5X2xhYmVsX2xpc3QoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xuICAgICAgICB2YWx1ZXNbMV0gPSAnTG93JztcbiAgICAgICAgdmFsdWVzWzJdID0gJ01lZGl1bSc7XG4gICAgICAgIHZhbHVlc1szXSA9ICdIaWdoJztcbiAgICAgICAgdmFsdWVzWzRdID0gJ1VyZ2VudCc7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgc3RhdGljIHByaW9yaXR5X2VudW1fc2VsZWN0KCkge1xuICAgICAgICBjb25zdCBmdWxsRGF0YSA9IHRoaXMucHJpb3JpdHlfZW51bV92YWwoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBcbiAgICAgICAgLy8gRXh0cmFjdCBsYWJlbHMgZnJvbSBmdWxsIGRhdGEsIHJlc3BlY3Rpbmcgc2VsZWN0YWJsZSBmbGFnXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZ1bGxEYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gZnVsbERhdGFba2V5XTtcbiAgICAgICAgICAgIGlmIChpdGVtLnNlbGVjdGFibGUgIT09IGZhbHNlICYmIGl0ZW0ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBkYXRhW2tleV0gPSBpdGVtLmxhYmVsO1xuICAgICAgICAgICAgICAgIG9yZGVyLnB1c2gocGFyc2VJbnQoa2V5KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCB0YXNrYWJsZSByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIHRhc2thYmxlKCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9UYXNrX01vZGVsLyR7dGhpcy5pZH0vdGFza2FibGVgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGFzc2lnbmVkX3RvIHJlbGF0aW9uc2hpcFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBSZWxhdGVkIG1vZGVsIGluc3RhbmNlKHMpIG9yIGZhbHNlXG4gICAgICovXG4gICAgYXN5bmMgYXNzaWduZWRfdG8oKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL1Rhc2tfTW9kZWwvJHt0aGlzLmlkfS9hc3NpZ25lZF90b2AsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFyZXNwb25zZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2UgdG8gbW9kZWwgaW5zdGFuY2UocylcbiAgICAgICAgLy8gRnJhbWV3b3JrIGhhbmRsZXMgaW5zdGFudGlhdGlvbiBiYXNlZCBvbiByZWxhdGlvbnNoaXAgdHlwZVxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggY3JlYXRlZF9ieSByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZWRfYnkoKSB7XG4gICAgICAgIGlmICghdGhpcy5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgZmV0Y2ggcmVsYXRpb25zaGlwIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogYC9fZmV0Y2hfcmVsL1Rhc2tfTW9kZWwvJHt0aGlzLmlkfS9jcmVhdGVkX2J5YCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29udmVydCByZXNwb25zZSB0byBtb2RlbCBpbnN0YW5jZShzKVxuICAgICAgICAvLyBGcmFtZXdvcmsgaGFuZGxlcyBpbnN0YW50aWF0aW9uIGJhc2VkIG9uIHJlbGF0aW9uc2hpcCB0eXBlXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaCBzdWJ0YXNrcyByZWxhdGlvbnNoaXBcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUmVsYXRlZCBtb2RlbCBpbnN0YW5jZShzKSBvciBmYWxzZVxuICAgICAqL1xuICAgIGFzeW5jIHN1YnRhc2tzKCkge1xuICAgICAgICBpZiAoIXRoaXMuaWQpIHtcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignQ2Fubm90IGZldGNoIHJlbGF0aW9uc2hpcCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoX3JlbC9UYXNrX01vZGVsLyR7dGhpcy5pZH0vc3VidGFza3NgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlIHRvIG1vZGVsIGluc3RhbmNlKHMpXG4gICAgICAgIC8vIEZyYW1ld29yayBoYW5kbGVzIGluc3RhbnRpYXRpb24gYmFzZWQgb24gcmVsYXRpb25zaGlwIHR5cGVcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cblxufVxuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIERlbW9fUHJvZHVjdF9Nb2RlbFxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIERlbW9fUHJvZHVjdF9Nb2RlbCBleHRlbmRzIFJzeF9Kc19Nb2RlbCB7XG4gICAgc3RhdGljIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gJ0RlbW9fUHJvZHVjdF9Nb2RlbCc7XG4gICAgfVxuXG4gICAgc3RhdGljIFNUQVRVU19BVkFJTEFCTEUgPSAxO1xuICAgIHN0YXRpYyBTVEFUVVNfT1VUX09GX1NUT0NLID0gMjtcbiAgICBzdGF0aWMgU1RBVFVTX0RJU0NPTlRJTlVFRCA9IDM7XG5cbiAgICBzdGF0aWMgc3RhdHVzX2lkX2VudW1fdmFsKCkge1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgIGNvbnN0IG9yZGVyID0gW107XG4gICAgICAgIGRhdGFbMV0gPSB7XCJjb25zdGFudFwiOlwiU1RBVFVTX0FWQUlMQUJMRVwiLFwibGFiZWxcIjpcIkF2YWlsYWJsZVwiLFwib3JkZXJcIjoxfTtcbiAgICAgICAgb3JkZXIucHVzaCgxKTtcbiAgICAgICAgZGF0YVsyXSA9IHtcImNvbnN0YW50XCI6XCJTVEFUVVNfT1VUX09GX1NUT0NLXCIsXCJsYWJlbFwiOlwiT3V0IG9mIFN0b2NrXCIsXCJvcmRlclwiOjJ9O1xuICAgICAgICBvcmRlci5wdXNoKDIpO1xuICAgICAgICBkYXRhWzNdID0ge1wiY29uc3RhbnRcIjpcIlNUQVRVU19ESVNDT05USU5VRURcIixcImxhYmVsXCI6XCJEaXNjb250aW51ZWRcIixcIm9yZGVyXCI6M307XG4gICAgICAgIG9yZGVyLnB1c2goMyk7XG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgc3RhdHVzX2lkX2xhYmVsX2xpc3QoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xuICAgICAgICB2YWx1ZXNbMV0gPSAnQXZhaWxhYmxlJztcbiAgICAgICAgdmFsdWVzWzJdID0gJ091dCBvZiBTdG9jayc7XG4gICAgICAgIHZhbHVlc1szXSA9ICdEaXNjb250aW51ZWQnO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIHN0YXRpYyBzdGF0dXNfaWRfZW51bV9zZWxlY3QoKSB7XG4gICAgICAgIGNvbnN0IGZ1bGxEYXRhID0gdGhpcy5zdGF0dXNfaWRfZW51bV92YWwoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBvcmRlciA9IFtdO1xuICAgICAgICBcbiAgICAgICAgLy8gRXh0cmFjdCBsYWJlbHMgZnJvbSBmdWxsIGRhdGEsIHJlc3BlY3Rpbmcgc2VsZWN0YWJsZSBmbGFnXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZ1bGxEYXRhKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gZnVsbERhdGFba2V5XTtcbiAgICAgICAgICAgIGlmIChpdGVtLnNlbGVjdGFibGUgIT09IGZhbHNlICYmIGl0ZW0ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBkYXRhW2tleV0gPSBpdGVtLmxhYmVsO1xuICAgICAgICAgICAgICAgIG9yZGVyLnB1c2gocGFyc2VJbnQoa2V5KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBQcm94eSB0aGF0IG1haW50YWlucyBzb3J0IG9yZGVyIGZvciBlbnVtZXJhdGlvblxuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGRhdGEsIHtcbiAgICAgICAgICAgIG93bktleXMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yZGVyLm1hcChTdHJpbmcpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCBpbiB0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGFyZ2V0W3Byb3BdXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgQ0FURUdPUllfRUxFQ1RST05JQ1MgPSAxO1xuICAgIHN0YXRpYyBDQVRFR09SWV9DTE9USElORyA9IDI7XG4gICAgc3RhdGljIENBVEVHT1JZX0JPT0tTID0gMztcbiAgICBzdGF0aWMgQ0FURUdPUllfRk9PRCA9IDQ7XG5cbiAgICBzdGF0aWMgY2F0ZWdvcnlfaWRfZW51bV92YWwoKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgY29uc3Qgb3JkZXIgPSBbXTtcbiAgICAgICAgZGF0YVsxXSA9IHtcImNvbnN0YW50XCI6XCJDQVRFR09SWV9FTEVDVFJPTklDU1wiLFwibGFiZWxcIjpcIkVsZWN0cm9uaWNzXCIsXCJvcmRlclwiOjF9O1xuICAgICAgICBvcmRlci5wdXNoKDEpO1xuICAgICAgICBkYXRhWzJdID0ge1wiY29uc3RhbnRcIjpcIkNBVEVHT1JZX0NMT1RISU5HXCIsXCJsYWJlbFwiOlwiQ2xvdGhpbmdcIixcIm9yZGVyXCI6Mn07XG4gICAgICAgIG9yZGVyLnB1c2goMik7XG4gICAgICAgIGRhdGFbM10gPSB7XCJjb25zdGFudFwiOlwiQ0FURUdPUllfQk9PS1NcIixcImxhYmVsXCI6XCJCb29rc1wiLFwib3JkZXJcIjozfTtcbiAgICAgICAgb3JkZXIucHVzaCgzKTtcbiAgICAgICAgZGF0YVs0XSA9IHtcImNvbnN0YW50XCI6XCJDQVRFR09SWV9GT09EXCIsXCJsYWJlbFwiOlwiRm9vZCAmIEJldmVyYWdlXCIsXCJvcmRlclwiOjR9O1xuICAgICAgICBvcmRlci5wdXNoKDQpO1xuICAgICAgICAvLyBSZXR1cm4gUHJveHkgdGhhdCBtYWludGFpbnMgc29ydCBvcmRlciBmb3IgZW51bWVyYXRpb25cbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eShkYXRhLCB7XG4gICAgICAgICAgICBvd25LZXlzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmRlci5tYXAoU3RyaW5nKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRhcmdldFtwcm9wXVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGNhdGVnb3J5X2lkX2xhYmVsX2xpc3QoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xuICAgICAgICB2YWx1ZXNbMV0gPSAnRWxlY3Ryb25pY3MnO1xuICAgICAgICB2YWx1ZXNbMl0gPSAnQ2xvdGhpbmcnO1xuICAgICAgICB2YWx1ZXNbM10gPSAnQm9va3MnO1xuICAgICAgICB2YWx1ZXNbNF0gPSAnRm9vZCAmIEJldmVyYWdlJztcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICBzdGF0aWMgY2F0ZWdvcnlfaWRfZW51bV9zZWxlY3QoKSB7XG4gICAgICAgIGNvbnN0IGZ1bGxEYXRhID0gdGhpcy5jYXRlZ29yeV9pZF9lbnVtX3ZhbCgpO1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG4gICAgICAgIGNvbnN0IG9yZGVyID0gW107XG4gICAgICAgIFxuICAgICAgICAvLyBFeHRyYWN0IGxhYmVscyBmcm9tIGZ1bGwgZGF0YSwgcmVzcGVjdGluZyBzZWxlY3RhYmxlIGZsYWdcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZnVsbERhdGEpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBmdWxsRGF0YVtrZXldO1xuICAgICAgICAgICAgaWYgKGl0ZW0uc2VsZWN0YWJsZSAhPT0gZmFsc2UgJiYgaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IGl0ZW0ubGFiZWw7XG4gICAgICAgICAgICAgICAgb3JkZXIucHVzaChwYXJzZUludChrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gUmV0dXJuIFByb3h5IHRoYXQgbWFpbnRhaW5zIHNvcnQgb3JkZXIgZm9yIGVudW1lcmF0aW9uXG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoZGF0YSwge1xuICAgICAgICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JkZXIubWFwKFN0cmluZyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wIGluIHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0YXJnZXRbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXI6OmRhdGFncmlkX2ZldGNoIHZpYSBBamF4LmNhbGwoKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIG9iamVjdCB0byBwYXNzIHRvIHRoZSBtZXRob2RcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZGF0YWdyaWRfZmV0Y2gocGFyYW1zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIEFqYXguY2FsbCgnL19hamF4L0Zyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci9kYXRhZ3JpZF9mZXRjaCcsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXI6OnNhdmUgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzYXZlKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIvc2F2ZScsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXI6OmRlbGV0ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGRlbGV0ZShwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyL2RlbGV0ZScsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXI6OnJlc3RvcmUgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyByZXN0b3JlKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIvcmVzdG9yZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5kYXRhZ3JpZF9mZXRjaC5wYXRoID0gJy9fYWpheC9Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIvZGF0YWdyaWRfZmV0Y2gnO1xuRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLnNhdmUucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyL3NhdmUnO1xuRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLmRlbGV0ZS5wYXRoID0gJy9fYWpheC9Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIvZGVsZXRlJztcbkZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5yZXN0b3JlLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci9yZXN0b3JlJztcbiIsIi8qKlxuICogQXV0by1nZW5lcmF0ZWQgSmF2YVNjcmlwdCBzdHViIGZvciBGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0VkaXRfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRWRpdF9Db250cm9sbGVyIHtcbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRWRpdF9Db250cm9sbGVyOjpzYXZlX3Byb2ZpbGUgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzYXZlX3Byb2ZpbGUocGFyYW1zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIEFqYXguY2FsbCgnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRWRpdF9Db250cm9sbGVyL3NhdmVfcHJvZmlsZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRWRpdF9Db250cm9sbGVyLnNhdmVfcHJvZmlsZS5wYXRoID0gJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0VkaXRfQ29udHJvbGxlci9zYXZlX3Byb2ZpbGUnO1xuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX1NldHRpbmdzX0NvbnRyb2xsZXI6OnVwZGF0ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHVwZGF0ZShwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5nc19Db250cm9sbGVyL3VwZGF0ZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlci51cGRhdGUucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5nc19Db250cm9sbGVyL3VwZGF0ZSc7XG4iLCIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIEphdmFTY3JpcHQgc3R1YiBmb3IgRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5X0NvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIENhbGwgRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlcjo6Y2hhbmdlX3Bhc3N3b3JkIHZpYSBBamF4LmNhbGwoKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIG9iamVjdCB0byBwYXNzIHRvIHRoZSBtZXRob2RcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY2hhbmdlX3Bhc3N3b3JkKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eV9Db250cm9sbGVyL2NoYW5nZV9wYXNzd29yZCcsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eV9Db250cm9sbGVyOjpyZXZva2Vfc2Vzc2lvbiB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHJldm9rZV9zZXNzaW9uKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eV9Db250cm9sbGVyL3Jldm9rZV9zZXNzaW9uJywgcGFyYW1zKTtcbiAgICB9XG5cbn1cblxuLy8gUGF0aCBwcm9wZXJ0aWVzIGZvciB0eXBlLXNhZmUgcm91dGluZ1xuRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlci5jaGFuZ2VfcGFzc3dvcmQucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlci9jaGFuZ2VfcGFzc3dvcmQnO1xuRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlci5yZXZva2Vfc2Vzc2lvbi5wYXRoID0gJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eV9Db250cm9sbGVyL3Jldm9rZV9zZXNzaW9uJztcbiIsIi8qKlxuICogQXV0by1nZW5lcmF0ZWQgSmF2YVNjcmlwdCBzdHViIGZvciBGcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c19Db250cm9sbGVyXG4gKiBETyBOT1QgRURJVCAtIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGVkXG4gKi9cblxuY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c19Db250cm9sbGVyOjpnZW5lcmF0ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGdlbmVyYXRlKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c19Db250cm9sbGVyL2dlbmVyYXRlJywgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzX0NvbnRyb2xsZXI6OnJldm9rZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHJldm9rZShwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlci9yZXZva2UnLCBwYXJhbXMpO1xuICAgIH1cblxufVxuXG4vLyBQYXRoIHByb3BlcnRpZXMgZm9yIHR5cGUtc2FmZSByb3V0aW5nXG5Gcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c19Db250cm9sbGVyLmdlbmVyYXRlLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzX0NvbnRyb2xsZXIvZ2VuZXJhdGUnO1xuRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlci5yZXZva2UucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlci9yZXZva2UnO1xuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyXG4gKiBETyBOT1QgRURJVCAtIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGVkXG4gKi9cblxuY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIENhbGwgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXI6OmRhdGFncmlkX2ZldGNoIHZpYSBBamF4LmNhbGwoKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIG9iamVjdCB0byBwYXNzIHRvIHRoZSBtZXRob2RcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZGF0YWdyaWRfZmV0Y2gocGFyYW1zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIEFqYXguY2FsbCgnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyL2RhdGFncmlkX2ZldGNoJywgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyOjphZGRfdXNlciB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGFkZF91c2VyKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlci9hZGRfdXNlcicsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlcjo6Z2V0X3VzZXJfZm9yX2VkaXQgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBnZXRfdXNlcl9mb3JfZWRpdChwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIvZ2V0X3VzZXJfZm9yX2VkaXQnLCBwYXJhbXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGwgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXI6OnNhdmVfdXNlciB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNhdmVfdXNlcihwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIvc2F2ZV91c2VyJywgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyOjpzZW5kX2ludml0ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNlbmRfaW52aXRlKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlci9zZW5kX2ludml0ZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLmRhdGFncmlkX2ZldGNoLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyL2RhdGFncmlkX2ZldGNoJztcbkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLmFkZF91c2VyLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyL2FkZF91c2VyJztcbkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLmdldF91c2VyX2Zvcl9lZGl0LnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyL2dldF91c2VyX2Zvcl9lZGl0JztcbkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLnNhdmVfdXNlci5wYXRoID0gJy9fYWpheC9Gcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlci9zYXZlX3VzZXInO1xuRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuc2VuZF9pbnZpdGUucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIvc2VuZF9pbnZpdGUnO1xuIiwiLyoqXG4gKiBBdXRvLWdlbmVyYXRlZCBKYXZhU2NyaXB0IHN0dWIgZm9yIEZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3NfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3NfQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9TZXR0aW5nc19TaXRlX1NldHRpbmdzX0NvbnRyb2xsZXI6OnVwZGF0ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHVwZGF0ZShwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyL3VwZGF0ZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3NfQ29udHJvbGxlci51cGRhdGUucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyL3VwZGF0ZSc7XG4iLCIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIEphdmFTY3JpcHQgc3R1YiBmb3IgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclxuICogRE8gTk9UIEVESVQgLSBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSByZWdlbmVyYXRlZFxuICovXG5cbmNsYXNzIEZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIENhbGwgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlcjo6ZGF0YWdyaWRfZmV0Y2ggdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBkYXRhZ3JpZF9mZXRjaChwYXJhbXMgPSB7fSkge1xuICAgICAgICByZXR1cm4gQWpheC5jYWxsKCcvX2FqYXgvRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci9kYXRhZ3JpZF9mZXRjaCcsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyOjpnZXRfY2xpZW50cyB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGdldF9jbGllbnRzKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyL2dldF9jbGllbnRzJywgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXI6OmdldF9jbGllbnQgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBnZXRfY2xpZW50KHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyL2dldF9jbGllbnQnLCBwYXJhbXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGwgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlcjo6c2F2ZSB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNhdmUocGFyYW1zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIEFqYXguY2FsbCgnL19hamF4L0Zyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIvc2F2ZScsIHBhcmFtcyk7XG4gICAgfVxuXG59XG5cbi8vIFBhdGggcHJvcGVydGllcyBmb3IgdHlwZS1zYWZlIHJvdXRpbmdcbkZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIuZGF0YWdyaWRfZmV0Y2gucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci9kYXRhZ3JpZF9mZXRjaCc7XG5Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmdldF9jbGllbnRzLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIvZ2V0X2NsaWVudHMnO1xuRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50LnBhdGggPSAnL19hamF4L0Zyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIvZ2V0X2NsaWVudCc7XG5Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLnNhdmUucGF0aCA9ICcvX2FqYXgvRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci9zYXZlJztcbiIsIi8qKlxuICogQXV0by1nZW5lcmF0ZWQgSmF2YVNjcmlwdCBzdHViIGZvciBGcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyXG4gKiBETyBOT1QgRURJVCAtIFRoaXMgZmlsZSBpcyBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGVkXG4gKi9cblxuY2xhc3MgRnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogQ2FsbCBGcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyOjpkYXRhZ3JpZF9mZXRjaCB2aWEgQWpheC5jYWxsKClcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gUGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGRhdGFncmlkX2ZldGNoKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyL2RhdGFncmlkX2ZldGNoJywgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIEZyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXI6OnNhdmUgdmlhIEFqYXguY2FsbCgpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFBhcmFtZXRlcnMgb2JqZWN0IHRvIHBhc3MgdG8gdGhlIG1ldGhvZFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzYXZlKHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBBamF4LmNhbGwoJy9fYWpheC9Gcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyL3NhdmUnLCBwYXJhbXMpO1xuICAgIH1cblxufVxuXG4vLyBQYXRoIHByb3BlcnRpZXMgZm9yIHR5cGUtc2FmZSByb3V0aW5nXG5Gcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyLmRhdGFncmlkX2ZldGNoLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXIvZGF0YWdyaWRfZmV0Y2gnO1xuRnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlci5zYXZlLnBhdGggPSAnL19hamF4L0Zyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXIvc2F2ZSc7XG4iLCI8IS0tXG5Db250YWN0c19EYXRhR3JpZFxuXG5DdXN0b20gZGF0YWdyaWQgZm9yIGNvbnRhY3RzIHdpdGggc3BlY2lhbGl6ZWQgcm93IHJlbmRlcmluZy5cbldyYXBzIGJhc2UgRGF0YUdyaWQgY29tcG9uZW50LlxuXG5BUkdVTUVOVFM6XG4gICAgJGFwaSAtIEFQSSBjb250cm9sbGVyIGNsYXNzXG4tLT5cbjxEZWZpbmU6RGF0YUdyaWRfQWJzdHJhY3QgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+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+XG4iLCI8JS0tIEV4dGVuZHMgRGF0YWdyaWRfQWJzdHJhY3QgLS0lPlxuXG48RGVmaW5lOkNsaWVudHNfRGF0YUdyaWRcbiAgICBleHRlbmRzPVwiRGF0YUdyaWRfQWJzdHJhY3RcIlxuICAgICRkYXRhX3NvdXJjZT1Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIuZGF0YWdyaWRfZmV0Y2hcbiAgICAkc29ydD1cImlkXCJcbiAgICAkb3JkZXI9XCJkZXNjXCJcbiAgICAkcGVyX3BhZ2U9MTVcbiAgICBjbGFzcz1cImNhcmQgRGF0YUdyaWRcIj5cblxuICAgIDwjREdfQ2FyZF9IZWFkZXI+XG4gICAgICAgIDxDYXJkX1RpdGxlPkNsaWVudCBMaXN0PC9DYXJkX1RpdGxlPlxuICAgICAgICA8Q2FyZF9IZWFkZXJfUmlnaHQ+XG4gICAgICAgICAgICA8U2VhcmNoX0lucHV0ICRpZD1cImZpbHRlcl9pbnB1dFwiIC8+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnkgYnRuLXNtXCI+RmlsdGVyPC9idXR0b24+XG4gICAgICAgIDwvQ2FyZF9IZWFkZXJfUmlnaHQ+XG4gICAgPC8jREdfQ2FyZF9IZWFkZXI+XG5cbiAgICA8I0RHX1RhYmxlX0hlYWRlcj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiICRpZD1cInNlbGVjdF9hbGxcIiAvPlxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiaWRcIj5JRDwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cIm5hbWVcIj5Db21wYW55IE5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjaXR5XCI+TG9jYXRpb248L3RoPlxuICAgICAgICAgICAgPHRoPlBob25lPC90aD5cbiAgICAgICAgICAgIDx0aD5XZWJzaXRlPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwicHJpb3JpdHlcIj5Qcmlvcml0eTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNyZWF0ZWRfYXRcIj5DcmVhdGVkPC90aD5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMjBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNER19UYWJsZV9IZWFkZXI+XG5cbiAgICA8I3Jvdz5cbiAgICAgICAgPHRyICRocmVmPVJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyJywndmlldycscm93LmlkKT5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHJvdy1jaGVja2JveFwiIHR5cGU9XCJjaGVja2JveFwiIHZhbHVlPVwiPCU9IHJvdy5pZCAlPlwiIC8+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICNDTDwlPSBTdHJpbmcocm93LmlkKS5wYWRTdGFydCgzLCAnMCcpICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlPSByb3cubmFtZSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LmNpdHkgJiYgcm93LnN0YXRlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlPSByb3cuY2l0eSAlPiwgPCU9IHJvdy5zdGF0ZSAlPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LmNpdHkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5jaXR5ICU+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cuc3RhdGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5zdGF0ZSAlPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIC1cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSByb3cucGhvbmUgfHwgJy0nICU+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LndlYnNpdGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSByb3cud2Vic2l0ZSAlPlwiIHRhcmdldD1cIl9ibGFua1wiIGNsYXNzPVwidGV4dC1kZWNvcmF0aW9uLW5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktbGluay00NWRlZ1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIC1cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cucHJpb3JpdHkgPT09IDQpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5VcmdlbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cucHJpb3JpdHkgPT09IDMpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nXCI+SGlnaDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5wcmlvcml0eSA9PT0gMikgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXByaW1hcnlcIj5NZWRpdW08L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zZWNvbmRhcnlcIj5Mb3c8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD48JT0gbmV3IERhdGUocm93LmNyZWF0ZWRfYXQpLnRvTG9jYWxlRGF0ZVN0cmluZygpICU+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5XCIgaHJlZj1cIi9jbGllbnRzL3ZpZXcvPCU9IHJvdy5pZCAlPlwiIHRpdGxlPVwiVmlld1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jcm93PlxuXG48L0RlZmluZTpDbGllbnRzX0RhdGFHcmlkPiIsIjwhLS1cbkFkZF9Vc2VyX01vZGFsX0Zvcm0gLSBNb2RhbCBmb3JtIGZvciBpbnZpdGluZyB1c2VycyB0byBzaXRlXG5cbkFsbG93cyBhZG1pbnMgdG8gaW52aXRlIHVzZXJzIGJ5IGVtYWlsLiBDcmVhdGVzIGEgcGVuZGluZyBpbnZpdGF0aW9uIHJlY29yZFxud2l0aCBhbiBpbnZpdGVfY29kZSB0aGF0IGV4cGlyZXMgYWZ0ZXIgY29uZmlndXJlZCBkYXlzLiBVc2VyIHJlY2VpdmVzIGludml0YXRpb25cblVSTCB0byBhY2NlcHQgYW5kIGNyZWF0ZSB0aGVpciBhY2NvdW50LlxuXG5GaWVsZHM6XG4tIGVtYWlsIChyZXF1aXJlZCk6IFVzZXIncyBlbWFpbCBhZGRyZXNzIGZvciBpbnZpdGF0aW9uXG4tIGZpcnN0X25hbWUgKHJlcXVpcmVkKTogVXNlcidzIGZpcnN0IG5hbWVcbi0gbGFzdF9uYW1lIChyZXF1aXJlZCk6IFVzZXIncyBsYXN0IG5hbWVcbi0gcm9sZV9pZCAocmVxdWlyZWQpOiBVc2VyJ3Mgcm9sZSAoT3duZXIvQWRtaW4vTWVtYmVyL1ZpZXdlcilcbi0gcGhvbmUgKG9wdGlvbmFsKTogVXNlcidzIHBob25lIG51bWJlclxuXG5Gb3JtIGZvbGxvd3MgUnN4X0Zvcm0gcGF0dGVybiB3aXRoIEZvcm1fRmllbGQgKyBpbnB1dCBjb21wb25lbnRzLlxuVmFsaWRhdGlvbiBoYW5kbGVkIHNlcnZlci1zaWRlLCBlcnJvcnMgZGlzcGxheWVkIHZpYSBGb3JtX1V0aWxzLlxuLS0+XG5cbjxEZWZpbmU6QWRkX1VzZXJfTW9kYWxfRm9ybT5cblxuICA8UnN4X0Zvcm0gJGNvbnRyb2xsZXI9XCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlclwiICRtZXRob2Q9XCJhZGRfdXNlclwiPlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwiZW1haWxcIiAkbGFiZWw9XCJFbWFpbCBBZGRyZXNzXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgIDxUZXh0X0lucHV0ICR0eXBlPVwiZW1haWxcIiAkcGxhY2Vob2xkZXI9XCJ1c2VyQGV4YW1wbGUuY29tXCIgJGF1dG9mb2N1cz10cnVlIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgbWItM1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cImZpcnN0X25hbWVcIiAkbGFiZWw9XCJGaXJzdCBOYW1lXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgICAgPFRleHRfSW5wdXQgLz5cbiAgICAgICAgPC9Gb3JtX0ZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgbWItM1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cImxhc3RfbmFtZVwiICRsYWJlbD1cIkxhc3QgTmFtZVwiICRyZXF1aXJlZD10cnVlPlxuICAgICAgICAgIDxUZXh0X0lucHV0IC8+XG4gICAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwicm9sZV9pZFwiICRsYWJlbD1cIlJvbGVcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgPFNlbGVjdF9JbnB1dCAkb3B0aW9ucz1cIjwlPSBKU09OLnN0cmluZ2lmeShbXG4gICAgICAgICAge3ZhbHVlOiAzLCBsYWJlbDogJ01lbWJlcid9LFxuICAgICAgICAgIHt2YWx1ZTogMiwgbGFiZWw6ICdBZG1pbid9LFxuICAgICAgICAgIHt2YWx1ZTogMSwgbGFiZWw6ICdPd25lcid9LFxuICAgICAgICAgIHt2YWx1ZTogNCwgbGFiZWw6ICdWaWV3ZXInfVxuICAgICAgICBdKSAlPlwiIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJwaG9uZVwiICRsYWJlbD1cIlBob25lIE51bWJlclwiPlxuICAgICAgICA8UGhvbmVfVGV4dF9JbnB1dCAkcGxhY2Vob2xkZXI9XCIoNTU1KSAxMjMtNDU2N1wiIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgPC9Sc3hfRm9ybT5cblxuPC9EZWZpbmU6QWRkX1VzZXJfTW9kYWxfRm9ybT4iLCI8JS0tIFVzZXIgTWFuYWdlbWVudCBEYXRhR3JpZCBDb21wb25lbnQgLS0lPlxuXG48RGVmaW5lOlVzZXJzX0RhdGFHcmlkXG4gICAgZXh0ZW5kcz1cIkRhdGFHcmlkX0Fic3RyYWN0XCJcbiAgICAkZGF0YV9zb3VyY2U9RnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuZGF0YWdyaWRfZmV0Y2hcbiAgICAkc29ydD1cImlkXCJcbiAgICAkb3JkZXI9XCJkZXNjXCJcbiAgICAkcGVyX3BhZ2U9MTVcbiAgICBjbGFzcz1cImNhcmQgRGF0YUdyaWRcIj5cblxuICAgIDwjREdfQ2FyZF9IZWFkZXI+XG4gICAgICAgIDxDYXJkX1RpdGxlPlVzZXIgTGlzdDwvQ2FyZF9UaXRsZT5cbiAgICAgICAgPENhcmRfSGVhZGVyX1JpZ2h0PlxuICAgICAgICAgICAgPFNlYXJjaF9JbnB1dCAkaWQ9XCJmaWx0ZXJfaW5wdXRcIiAvPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGJ0bi1zbVwiPkZpbHRlcjwvYnV0dG9uPlxuICAgICAgICA8L0NhcmRfSGVhZGVyX1JpZ2h0PlxuICAgIDwvI0RHX0NhcmRfSGVhZGVyPlxuXG4gICAgPCNER19UYWJsZV9IZWFkZXI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiA0MHB4O1wiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAkaWQ9XCJzZWxlY3RfYWxsXCI+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiZmlyc3RfbmFtZVwiPk5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJlbWFpbFwiPkVtYWlsPC90aD5cbiAgICAgICAgICAgIDx0aD5TdGF0dXM8L3RoPlxuICAgICAgICAgICAgPHRoPlBob25lPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwidXNlcl9yb2xlX2lkXCI+Um9sZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNyZWF0ZWRfYXRcIj5DcmVhdGVkPC90aD5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMjBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNER19UYWJsZV9IZWFkZXI+XG5cbiAgICA8I3Jvdz5cbiAgICAgICAgPHRyIGRhdGEtaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyJywgJ3ZpZXcnLCByb3cuaWQpICU+XCI+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCByb3ctY2hlY2tib3hcIiB0eXBlPVwiY2hlY2tib3hcIiB2YWx1ZT1cIjwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI1U8JT0gU3RyaW5nKHJvdy5pZCkucGFkU3RhcnQoMywgJzAnKSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LmZpcnN0X25hbWUgfHwgcm93Lmxhc3RfbmFtZSkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8JT0gcm93LmZpcnN0X25hbWUgJT4gPCU9IHJvdy5sYXN0X25hbWUgJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8ZW0gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+Tm8gbmFtZSBzZXQ8L2VtPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5lbWFpbCAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93Lmludml0YXRpb25fc3RhdHVzID09PSAnYWNjZXB0ZWQnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5pbnZpdGF0aW9uX3N0YXR1cyA9PT0gJ2V4cGlyZWQnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+RXhwaXJlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5JbnZpdGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZSB8fCAnLScgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cudXNlcl9yb2xlX2lkX2xhYmVsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPjwlPSByb3cudXNlcl9yb2xlX2lkX2xhYmVsICU+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSBuZXcgRGF0ZShyb3cuY3JlYXRlZF9hdCkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXInLCAndmlldycsIHJvdy5pZCkgJT5cIiB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgIDwvI3Jvdz5cblxuPC9EZWZpbmU6VXNlcnNfRGF0YUdyaWQ+XG4iLCI8IS0tXG5FZGl0X1VzZXJfTW9kYWxfRm9ybSAtIE1vZGFsIGZvcm0gZm9yIGVkaXRpbmcgdXNlciBpbmZvcm1hdGlvblxuXG5BbGxvd3MgYWRtaW5zIHRvIHVwZGF0ZSB1c2VyIHByb2ZpbGUgaW5mb3JtYXRpb24gZm9yIGV4aXN0aW5nIHVzZXJzLlxuXG5GaWVsZHM6XG4tIGlkIChoaWRkZW4pOiBVc2VyIElEXG4tIGVtYWlsIChyZXF1aXJlZCk6IFVzZXIncyBlbWFpbCBhZGRyZXNzXG4tIGZpcnN0X25hbWUgKHJlcXVpcmVkKTogVXNlcidzIGZpcnN0IG5hbWVcbi0gbGFzdF9uYW1lIChyZXF1aXJlZCk6IFVzZXIncyBsYXN0IG5hbWVcbi0gcm9sZV9pZCAocmVxdWlyZWQpOiBVc2VyJ3Mgcm9sZSAoT3duZXIvQWRtaW4vTWVtYmVyL1ZpZXdlcilcbi0gcGhvbmUgKG9wdGlvbmFsKTogVXNlcidzIHBob25lIG51bWJlclxuXG5Gb3JtIGZvbGxvd3MgUnN4X0Zvcm0gcGF0dGVybiB3aXRoIEZvcm1fRmllbGQgKyBpbnB1dCBjb21wb25lbnRzLlxuVmFsaWRhdGlvbiBoYW5kbGVkIHNlcnZlci1zaWRlLCBlcnJvcnMgZGlzcGxheWVkIHZpYSBGb3JtX1V0aWxzLlxuLS0+XG5cbjxEZWZpbmU6RWRpdF9Vc2VyX01vZGFsX0Zvcm0+XG5cbiAgPFJzeF9Gb3JtICRjb250cm9sbGVyPVwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXJcIiAkbWV0aG9kPVwic2F2ZV91c2VyXCIgJGRhdGE9XCI8JT0gSlNPTi5zdHJpbmdpZnkodGhpcy5hcmdzLmRhdGEpICU+XCI+XG5cbiAgICA8Rm9ybV9IaWRkZW5fRmllbGQgJG5hbWU9XCJpZFwiIC8+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJlbWFpbFwiICRsYWJlbD1cIkVtYWlsIEFkZHJlc3NcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgPFRleHRfSW5wdXQgJHR5cGU9XCJlbWFpbFwiICRwbGFjZWhvbGRlcj1cInVzZXJAZXhhbXBsZS5jb21cIiAkYXV0b2ZvY3VzPXRydWUgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBtYi0zXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwiZmlyc3RfbmFtZVwiICRsYWJlbD1cIkZpcnN0IE5hbWVcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgICA8VGV4dF9JbnB1dCAvPlxuICAgICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBtYi0zXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwibGFzdF9uYW1lXCIgJGxhYmVsPVwiTGFzdCBOYW1lXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgICAgPFRleHRfSW5wdXQgLz5cbiAgICAgICAgPC9Gb3JtX0ZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJyb2xlX2lkXCIgJGxhYmVsPVwiUm9sZVwiICRyZXF1aXJlZD10cnVlPlxuICAgICAgICA8U2VsZWN0X0lucHV0ICRvcHRpb25zPVwiPCU9IEpTT04uc3RyaW5naWZ5KFtcbiAgICAgICAgICB7dmFsdWU6IDMsIGxhYmVsOiAnTWVtYmVyJ30sXG4gICAgICAgICAge3ZhbHVlOiAyLCBsYWJlbDogJ0FkbWluJ30sXG4gICAgICAgICAge3ZhbHVlOiAxLCBsYWJlbDogJ093bmVyJ30sXG4gICAgICAgICAge3ZhbHVlOiA0LCBsYWJlbDogJ1ZpZXdlcid9XG4gICAgICAgIF0pICU+XCIgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cInBob25lXCIgJGxhYmVsPVwiUGhvbmUgTnVtYmVyXCI+XG4gICAgICAgIDxQaG9uZV9UZXh0X0lucHV0ICRwbGFjZWhvbGRlcj1cIig1NTUpIDEyMy00NTY3XCIgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICA8L1JzeF9Gb3JtPlxuXG48L0RlZmluZTpFZGl0X1VzZXJfTW9kYWxfRm9ybT5cbiIsIjwlLS0gRXh0ZW5kcyBEYXRhZ3JpZF9BYnN0cmFjdCAtLSU+XG5cbjwlLS0gV2UgYXJlIGhlcmU6IHNlZWluZyBpZiAkZGF0YV9zb3VyY2Ugd2lsbCB3b3JrLjogLS0lPlxuYGBcbjxEZWZpbmU6Q29udGFjdHNfRGF0YUdyaWRcbiAgICBleHRlbmRzPVwiRGF0YUdyaWRfQWJzdHJhY3RcIlxuICAgICRkYXRhX3NvdXJjZT1Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmRhdGFncmlkX2ZldGNoXG4gICAgJHNvcnQ9XCJpZFwiXG4gICAgJG9yZGVyPVwiZGVzY1wiXG4gICAgJHBlcl9wYWdlPTE1XG4gICAgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8I0RHX0NhcmRfSGVhZGVyPlxuICAgICAgICA8Q2FyZF9UaXRsZT5Db250YWN0IExpc3Q8L0NhcmRfVGl0bGU+XG4gICAgICAgIDxDYXJkX0hlYWRlcl9SaWdodD5cbiAgICAgICAgICAgIDxTZWFyY2hfSW5wdXQgJGlkPVwiZmlsdGVyX2lucHV0XCIgLz5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBidG4tc21cIj5GaWx0ZXI8L2J1dHRvbj5cbiAgICAgICAgPC9DYXJkX0hlYWRlcl9SaWdodD5cbiAgICA8LyNER19DYXJkX0hlYWRlcj5cblxuICAgIDwjREdfVGFibGVfSGVhZGVyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgJGlkPVwic2VsZWN0X2FsbFwiIC8+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiZmlyc3RfbmFtZVwiPk5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJlbWFpbFwiPkVtYWlsPC90aD5cbiAgICAgICAgICAgIDx0aD5QaG9uZTwvdGg+XG4gICAgICAgICAgICA8dGg+Q29tcGFueTwvdGg+XG4gICAgICAgICAgICA8dGg+Um9sZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInByaW9yaXR5XCI+UHJpb3JpdHk8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjcmVhdGVkX2F0XCI+Q3JlYXRlZDwvdGg+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTIwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jREdfVGFibGVfSGVhZGVyPlxuXG4gICAgPCNyb3c+XG4gICAgICAgIDwlLS0gPCUgY29uc29sZS5sb2coXCJJIGFtIGEgcm93XCIsIHJvdyk7ICU+IC0tJT5cbiAgICAgICAgPHRyICRocmVmPVJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlcicsJ3ZpZXcnLHJvdy5pZCk+XG4gICAgICAgICAgICA8JS0tIDx0cj4gLS0lPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgcm93LWNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCI8JT0gcm93LmlkICU+XCIgLz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI0NUPCU9IFN0cmluZyhyb3cuaWQpLnBhZFN0YXJ0KDMsICcwJykgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5maXJzdF9uYW1lICU+IDwlPSByb3cubGFzdF9uYW1lICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlPSByb3cuZW1haWwgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZV93b3JrIHx8ICctJyAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHJvdy5jbGllbnRfaWQpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPENsaWVudF9MYWJlbCAkY2xpZW50X2lkPXJvdy5jbGllbnRfaWQgLz5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICAtXG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LnByaW9yaXR5ID09PSA0KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+VXJnZW50PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnByaW9yaXR5ID09PSAzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPkhpZ2g8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cucHJpb3JpdHkgPT09IDIpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWVkaXVtPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+TG93PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IG5ldyBEYXRlKHJvdy5jcmVhdGVkX2F0KS50b0xvY2FsZURhdGVTdHJpbmcoKSAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeVwiIGhyZWY9XCIvY29udGFjdHMvdmlldy88JT0gcm93LmlkICU+XCIgdGl0bGU9XCJWaWV3XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNyb3c+XG5cbjwvRGVmaW5lOkNvbnRhY3RzX0RhdGFHcmlkPiIsIjxEZWZpbmU6RGF0YV9UYWJsZSBjbGFzcz1cImNhcmRcIj5cblxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIj48JT0gdGhpcy5hcmdzLnRpdGxlIHx8ICdEYXRhIFRhYmxlJyAlPjwvaDU+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxuICAgICAgPGRpdiAkaWQ9XCJzZWFyY2hfY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICA8ZGl2ICRpZD1cImZpbHRlcl9jb250YWluZXJcIj48L2Rpdj5cbiAgICAgIDxkaXYgJGlkPVwiY29sdW1uX3RvZ2dsZV9jb250YWluZXJcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPEJ1bGtfQWN0aW9uX0JhciAkaWQ9XCJidWxrX2JhclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICA8QnV0dG9uX0RhbmdlciAkaWQ9XCJidWxrX2RlbGV0ZVwiPkRlbGV0ZSBTZWxlY3RlZDwvQnV0dG9uX0Rhbmdlcj5cbiAgICA8QnV0dG9uX1NlY29uZGFyeSAkaWQ9XCJidWxrX2V4cG9ydFwiPkV4cG9ydCBTZWxlY3RlZDwvQnV0dG9uX1NlY29uZGFyeT5cbiAgPC9CdWxrX0FjdGlvbl9CYXI+XG5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTBcIj5cbiAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgPFRhYmxlICRpZD1cInRhYmxlXCI+XG4gICAgICAgIDx0aGVhZD5cbiAgICAgICAgICA8dHIgJGlkPVwiaGVhZGVyX3Jvd1wiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5idWxrX2FjdGlvbnMpIHsgJT5cbiAgICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPEJ1bGtfU2VsZWN0aW9uICRpZD1cImJ1bGtfc2VsZWN0aW9uXCIgLz5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwhLS0gQ29sdW1uIGhlYWRlcnMgZHluYW1pY2FsbHkgZ2VuZXJhdGVkIC0tPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvdGhlYWQ+XG4gICAgICAgIDx0Ym9keSAkaWQ9XCJ0Ym9keVwiPlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgdGV4dC1tdXRlZFwiPkxvYWRpbmcgZGF0YS4uLjwvZGl2PlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8JSB9IGVsc2UgaWYgKHRoaXMuZGF0YS5yb3dzICYmIHRoaXMuZGF0YS5yb3dzLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiPlxuICAgICAgICAgICAgICAgIDxFbXB0eV9TdGF0ZVxuICAgICAgICAgICAgICAgICAgJGljb249XCJpbmJveFwiXG4gICAgICAgICAgICAgICAgICAkdGl0bGU9XCJObyBkYXRhIGF2YWlsYWJsZVwiXG4gICAgICAgICAgICAgICAgICAkbWVzc2FnZT1cIlRoZXJlIGFyZSBubyByZWNvcmRzIHRvIGRpc3BsYXlcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGZvciAobGV0IHJvdyBvZiB0aGlzLmRhdGEucm93cyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dHIgZGF0YS1pZD1cIjwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmJ1bGtfYWN0aW9ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHJvdy1jaGVja2JveFwiIHZhbHVlPVwiPCU9IHJvdy5pZCAlPlwiPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgY29sIG9mIHRoaXMuZGF0YS5jb2x1bW5zIHx8IFtdKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvd1tjb2wuZmllbGRdICU+PC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5yb3dfYWN0aW9ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8Um93X0FjdGlvbl9NZW51ICRpZD1cInJvd19hY3Rpb25zXzwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8JT0gdGhpcy5hcmdzLnJvd19hY3Rpb25zKHJvdykgJT5cbiAgICAgICAgICAgICAgICAgICAgPC9Sb3dfQWN0aW9uX01lbnU+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L1RhYmxlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiY2FyZC1mb290ZXJcIiAkaWQ9XCJmb290ZXJcIj5cbiAgICA8VGFibGVfUGFnaW5hdGlvblxuICAgICAgJGlkPVwicGFnaW5hdGlvblwiXG4gICAgICAkc3RhcnQ9dGhpcy5kYXRhLnN0YXJ0XG4gICAgICAkZW5kPXRoaXMuZGF0YS5lbmRcbiAgICAgICR0b3RhbD10aGlzLmRhdGEudG90YWxcbiAgICAgICRjdXJyZW50X3BhZ2U9dGhpcy5kYXRhLmN1cnJlbnRfcGFnZVxuICAgICAgJHRvdGFsX3BhZ2VzPXRoaXMuZGF0YS50b3RhbF9wYWdlc1xuICAgICAgLz5cbiAgPC9kaXY+XG5cbjwvRGVmaW5lOkRhdGFfVGFibGU+IiwiPERlZmluZTpDYXJkX0hlYWRlcl9SaWdodCBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxyXG5cclxuICA8JT0gY29udGVudCgpICU+XHJcblxyXG48L0RlZmluZTpDYXJkX0hlYWRlcl9SaWdodD4iLCI8IS0tXG5DbGllbnRfU2VsZWN0b3JfSW5wdXRcblxuU3BlY2lhbGl6ZWQgc2VsZWN0IGZvciBjbGllbnQgZHJvcGRvd25zIHdpdGggQWpheCBsb2FkaW5nLlxuRXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB3aXRoIGNsaWVudC1zcGVjaWZpYyBiZWhhdmlvci5cblxuJGRhdGEgLSBBamF4IGVuZHBvaW50IGZvciBjbGllbnQgZGF0YSAob3B0aW9uYWwsIGRlZmF1bHRzIHRvIEZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIuZ2V0X2NsaWVudHMoKSlcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIHRleHQgKGRlZmF1bHQ6IFwiU2VsZWN0IENsaWVudC4uLlwiKVxuJGRpc2FibGVkIC0gQm9vbGVhbiB0byBkaXNhYmxlIHRoZSBzZWxlY3RcblxuRmVhdHVyZXM6XG4tIExvYWRzIGNsaWVudCBsaXN0IHZpYSBBamF4IGF1dG9tYXRpY2FsbHlcbi0gSW5oZXJpdHMgYWxsIEFqYXhfU2VsZWN0X0lucHV0IGJlaGF2aW9yIChUb20gU2VsZWN0LCBzZWFyY2gsIGxvYWRpbmcgc3RhdGVzLCBldGMuKVxuLS0+XG48RGVmaW5lOkNsaWVudF9TZWxlY3Rvcl9JbnB1dCBleHRlbmRzPVwiQWpheF9TZWxlY3RfSW5wdXRcIiBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxzZWxlY3QgJGlkPVwiaW5wdXRcIiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAoIXRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzIHx8IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ1BsZWFzZSB3YWl0Li4uJyAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyICU+PC9vcHRpb24+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBvcHQgb2YgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQudmFsdWUgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdC52YWx1ZSkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0LmxhYmVsICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdCkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0ICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9zZWxlY3Q+XG48L0RlZmluZTpDbGllbnRfU2VsZWN0b3JfSW5wdXQ+XG4iLCI8JS0tIEV4dGVuZHMgRGF0YWdyaWRfQWJzdHJhY3QgLS0lPlxuXG48RGVmaW5lOlByb2plY3RzX0RhdGFHcmlkXG4gICAgZXh0ZW5kcz1cIkRhdGFHcmlkX0Fic3RyYWN0XCJcbiAgICAkZGF0YV9zb3VyY2U9RnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlci5kYXRhZ3JpZF9mZXRjaFxuICAgICRzb3J0PVwiY3JlYXRlZF9hdFwiXG4gICAgJHBlcl9wYWdlPTE1XG4gICAgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8I0RHX0NhcmRfSGVhZGVyPlxuICAgICAgICA8Q2FyZF9UaXRsZT5Qcm9qZWN0IExpc3Q8L0NhcmRfVGl0bGU+XG4gICAgICAgIDxDYXJkX0hlYWRlcl9SaWdodD5cbiAgICAgICAgICAgIDxTZWFyY2hfSW5wdXQgJGlkPVwiZmlsdGVyX2lucHV0XCIgLz5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBidG4tc21cIj5GaWx0ZXI8L2J1dHRvbj5cbiAgICAgICAgPC9DYXJkX0hlYWRlcl9SaWdodD5cbiAgICA8LyNER19DYXJkX0hlYWRlcj5cblxuICAgIDwjREdfVGFibGVfSGVhZGVyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgJGlkPVwic2VsZWN0X2FsbFwiIC8+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwibmFtZVwiPlByb2plY3QgTmFtZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNsaWVudF9pZFwiPkNsaWVudDwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInN0YXR1c1wiPlN0YXR1czwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInByaW9yaXR5XCI+UHJpb3JpdHk8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJzdGFydF9kYXRlXCI+U3RhcnQgRGF0ZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImR1ZV9kYXRlXCI+RHVlIERhdGU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjcmVhdGVkX2F0XCI+Q3JlYXRlZDwvdGg+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTIwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jREdfVGFibGVfSGVhZGVyPlxuXG4gICAgPCNyb3c+XG4gICAgICAgIDx0ciAkaHJlZj1Sc3guUm91dGUoJ0Zyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXInLCd2aWV3Jyxyb3cuaWQpPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgcm93LWNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCI8JT0gcm93LmlkICU+XCIgLz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI1BSPCU9IFN0cmluZyhyb3cuaWQpLnBhZFN0YXJ0KDMsICcwJykgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5uYW1lICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cuY2xpZW50KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlPSByb3cuY2xpZW50Lm5hbWUgJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICAtXG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LnN0YXR1cyA9PT0gMSkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWluZm9cIj5QbGFubmluZzwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5zdGF0dXMgPT09IDIpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnN0YXR1cyA9PT0gMykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5PbiBIb2xkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnN0YXR1cyA9PT0gNCkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXByaW1hcnlcIj5Db21wbGV0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cuc3RhdHVzID09PSA1KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+Q2FuY2VsbGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHJvdy5wcmlvcml0eSA9PT0gNCkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPlVyZ2VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5wcmlvcml0eSA9PT0gMykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5IaWdoPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnByaW9yaXR5ID09PSAyKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPk1lZGl1bTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPkxvdzwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSByb3cuc3RhcnRfZGF0ZSA/IG5ldyBEYXRlKHJvdy5zdGFydF9kYXRlKS50b0xvY2FsZURhdGVTdHJpbmcoKSA6ICctJyAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5kdWVfZGF0ZSA/IG5ldyBEYXRlKHJvdy5kdWVfZGF0ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOiAnLScgJT48L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSBuZXcgRGF0ZShyb3cuY3JlYXRlZF9hdCkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlcicsICd2aWV3Jywgcm93LmlkKSAlPlwiIHRpdGxlPVwiVmlld1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jcm93PlxuXG48L0RlZmluZTpQcm9qZWN0c19EYXRhR3JpZD5cbiIsIi8vIEphdmFTY3JpcHQgTWFuaWZlc3QgLSBHZW5lcmF0ZWQgYnkgQnVuZGxlQ29tcGlsZXJcbi8vIFJlZ2lzdGVycyBhbGwgY2xhc3NlcyBpbiB0aGlzIGJ1bmRsZSBmb3IgcnVudGltZSBpbnRyb3NwZWN0aW9uXG5NYW5pZmVzdC5fZGVmaW5lKFtcbiAgICBbTWFuaWZlc3QsIFwiTWFuaWZlc3RcIiwgbnVsbF0sXG4gICAgW1JzeF9CZWhhdmlvcnMsIFwiUnN4X0JlaGF2aW9yc1wiLCBudWxsXSxcbiAgICBbUnN4X0NhY2hlLCBcIlJzeF9DYWNoZVwiLCBudWxsXSxcbiAgICBbUnN4X0luaXQsIFwiUnN4X0luaXRcIiwgbnVsbF0sXG4gICAgW1JzeF9Kc19Nb2RlbCwgXCJSc3hfSnNfTW9kZWxcIiwgbnVsbF0sXG4gICAgW1JzeF9WaWV3X1RyYW5zaXRpb25zLCBcIlJzeF9WaWV3X1RyYW5zaXRpb25zXCIsIG51bGxdLFxuICAgIFtSZWFkV3JpdGVMb2NrLCBcIlJlYWRXcml0ZUxvY2tcIiwgbnVsbF0sXG4gICAgW0Zvcm1fVXRpbHMsIFwiRm9ybV9VdGlsc1wiLCBudWxsXSxcbiAgICBbRGVidWdnZXIsIFwiRGVidWdnZXJcIiwgbnVsbF0sXG4gICAgW1JzeF9KcV9IZWxwZXJzLCBcIlJzeF9KcV9IZWxwZXJzXCIsIG51bGxdLFxuICAgIFtSc3gsIFwiUnN4XCIsIG51bGxdLFxuICAgIFtBamF4LCBcIkFqYXhcIiwgbnVsbF0sXG4gICAgW0pxaHRtbF9Db21wb25lbnQsIFwiSnFodG1sX0NvbXBvbmVudFwiLCBfQmFzZV9KcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSnFodG1sX0ludGVncmF0aW9uLCBcIkpxaHRtbF9JbnRlZ3JhdGlvblwiLCBudWxsXSxcbiAgICBbRGF0YUdyaWRfQWJzdHJhY3QsIFwiRGF0YUdyaWRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0FjdGl2aXR5X0ZlZWQsIFwiQWN0aXZpdHlfRmVlZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWN0b3JfUmVmZXJlbmNlLCBcIkFjdG9yX1JlZmVyZW5jZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWR2YW5jZWRfU2VhcmNoX1BhbmVsLCBcIkFkdmFuY2VkX1NlYXJjaF9QYW5lbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWxlcnRfQmFubmVyLCBcIkFsZXJ0X0Jhbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQXZhdGFyLCBcIkF2YXRhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQmxvY2txdW90ZSwgXCJCbG9ja3F1b3RlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCcmVhZGNydW1icywgXCJCcmVhZGNydW1ic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19BY3Rpb25fQmFyLCBcIkJ1bGtfQWN0aW9uX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19TZWxlY3Rpb24sIFwiQnVsa19TZWxlY3Rpb25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9Hcm91cCwgXCJCdXR0b25fR3JvdXBcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9QcmltYXJ5LCBcIkJ1dHRvbl9QcmltYXJ5XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCdXR0b25fU2Vjb25kYXJ5LCBcIkJ1dHRvbl9TZWNvbmRhcnlcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbiwgXCJCdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhbGVuZGFyX0V2ZW50LCBcIkNhbGVuZGFyX0V2ZW50XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDYWxlbmRhcl9HcmlkLCBcIkNhbGVuZGFyX0dyaWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhcmQsIFwiQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hhcnRfQ29tcG9uZW50LCBcIkNoYXJ0X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hlY2tib3gsIFwiQ2hlY2tib3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NvZGVfQmxvY2ssIFwiQ29kZV9CbG9ja1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlLCBcIkNvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29tbWVudF9UaHJlYWQsIFwiQ29tbWVudF9UaHJlYWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0RhdGVfUGlja2VyLCBcIkRhdGVfUGlja2VyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtEcm9wZG93bl9NZW51LCBcIkRyb3Bkb3duX01lbnVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0VtcHR5X1N0YXRlLCBcIkVtcHR5X1N0YXRlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtFeHBvcnRfQnV0dG9uLCBcIkV4cG9ydF9CdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ZpbGVfVXBsb2FkLCBcIkZpbGVfVXBsb2FkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGaWx0ZXJfQmFyLCBcIkZpbHRlcl9CYXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fQWN0aW9uc19Db21wb25lbnQsIFwiRm9ybV9BY3Rpb25zX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9GaWVsZF9Hcm91cCwgXCJGb3JtX0ZpZWxkX0dyb3VwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGb3JtX0dyb3VwX0NvbXBvbmVudCwgXCJGb3JtX0dyb3VwX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9Sb3dfQ29tcG9uZW50LCBcIkZvcm1fUm93X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UsIFwiRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0dhbnR0X0NoYXJ0LCBcIkdhbnR0X0NoYXJ0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJY29uX0J1dHRvbiwgXCJJY29uX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX0xhYmVsLCBcIkljb25fV2l0aF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX1RleHQsIFwiSWNvbl9XaXRoX1RleHRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ljb24sIFwiSWNvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSW5mb19Cb3gsIFwiSW5mb19Cb3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0lubGluZV9FZGl0X0ZpZWxkLCBcIklubGluZV9FZGl0X0ZpZWxkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX0ljb24sIFwiSW5wdXRfV2l0aF9JY29uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX1ZhbGlkYXRpb24sIFwiSW5wdXRfV2l0aF9WYWxpZGF0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dCwgXCJJbnB1dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbS2FuYmFuX0JvYXJkLCBcIkthbmJhbl9Cb2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTGluaywgXCJMaW5rXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtMaXN0LCBcIkxpc3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0xvYWRpbmdfU2tlbGV0b24sIFwiTG9hZGluZ19Ta2VsZXRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTWV0cmljX0NhcmQsIFwiTWV0cmljX0NhcmRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vYmlsZV9IZWFkZXIsIFwiTW9iaWxlX0hlYWRlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfRGlhbG9nLCBcIk1vZGFsX0RpYWxvZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTXVsdGlfU2VsZWN0LCBcIk11bHRpX1NlbGVjdFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0JhZGdlLCBcIk5vdGlmaWNhdGlvbl9CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0Ryb3Bkb3duLCBcIk5vdGlmaWNhdGlvbl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbT3ZlcmR1ZV9JbmRpY2F0b3IsIFwiT3ZlcmR1ZV9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BhZ2VfSGVhZGVyLCBcIlBhZ2VfSGVhZGVyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlX1NlY3Rpb24sIFwiUGFnZV9TZWN0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlLCBcIlBhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BvcG92ZXIsIFwiUG9wb3ZlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUHJvZ3Jlc3NfQmFyLCBcIlByb2dyZXNzX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmFkaW9fQnV0dG9uLCBcIlJhZGlvX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmljaF9UZXh0X0VkaXRvciwgXCJSaWNoX1RleHRfRWRpdG9yXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtSb3dfQWN0aW9uX01lbnUsIFwiUm93X0FjdGlvbl9NZW51XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LCBcIlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlYXJjaF9CYXIsIFwiU2VhcmNoX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU2VhcmNoYWJsZV9TZWxlY3QsIFwiU2VhcmNoYWJsZV9TZWxlY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlbGVjdF9Ecm9wZG93biwgXCJTZWxlY3RfRHJvcGRvd25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NpZGViYXJfTmF2LCBcIlNpZGViYXJfTmF2XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTb3J0YWJsZV9Db2x1bW5fSGVhZGVyLCBcIlNvcnRhYmxlX0NvbHVtbl9IZWFkZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NwaW5uZXIsIFwiU3Bpbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdF9DYXJkLCBcIlN0YXRfQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdHVzX0JhZGdlLCBcIlN0YXR1c19CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFiX0NvbnRlbnQsIFwiVGFiX0NvbnRlbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYmxlX1BhZ2luYXRpb24sIFwiVGFibGVfUGFnaW5hdGlvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFibGUsIFwiVGFibGVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYnMsIFwiVGFic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnX0dyb3VwLCBcIlRhZ19Hcm91cFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnLCBcIlRhZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dF9EaXNwbGF5LCBcIlRleHRfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dGFyZWEsIFwiVGV4dGFyZWFcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RocmVlX0NvbHVtbl9MYXlvdXQsIFwiVGhyZWVfQ29sdW1uX0xheW91dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGltZV9QaWNrZXIsIFwiVGltZV9QaWNrZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RpbWVsaW5lLCBcIlRpbWVsaW5lXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUaW1lc3RhbXBfRGlzcGxheSwgXCJUaW1lc3RhbXBfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVG9vbHRpcCwgXCJUb29sdGlwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUb3BfTmF2LCBcIlRvcF9OYXZcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RyZW5kX0luZGljYXRvciwgXCJUcmVuZF9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1R3b19Db2x1bW5fTGF5b3V0LCBcIlR3b19Db2x1bW5fTGF5b3V0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtVc2VyX0F2YXRhcl9Ecm9wZG93biwgXCJVc2VyX0F2YXRhcl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfQWJzdHJhY3QsIFwiTW9kYWxfQWJzdHJhY3RcIiwgbnVsbF0sXG4gICAgW1JzeF9Nb2RhbCwgXCJSc3hfTW9kYWxcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vZGFsLCBcIk1vZGFsXCIsIG51bGxdLFxuICAgIFtCcmVhZGNydW1iX0l0ZW0sIFwiQnJlYWRjcnVtYl9JdGVtXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDbGllbnRfTGFiZWxfTGluaywgXCJDbGllbnRfTGFiZWxfTGlua1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2xpZW50X0xhYmVsLCBcIkNsaWVudF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9JbnB1dF9BYnN0cmFjdCwgXCJGb3JtX0lucHV0X0Fic3RyYWN0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUZXh0X0lucHV0LCBcIlRleHRfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0NoZWNrYm94X0lucHV0LCBcIkNoZWNrYm94X0lucHV0XCIsIEZvcm1fSW5wdXRfQWJzdHJhY3RdLFxuICAgIFtXeXNpd3lnX0lucHV0LCBcIld5c2l3eWdfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW1NlbGVjdF9JbnB1dCwgXCJTZWxlY3RfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0FqYXhfU2VsZWN0X0lucHV0LCBcIkFqYXhfU2VsZWN0X0lucHV0XCIsIFNlbGVjdF9JbnB1dF0sXG4gICAgW0N1cnJlbmN5X0lucHV0LCBcIkN1cnJlbmN5X0lucHV0XCIsIFRleHRfSW5wdXRdLFxuICAgIFtQaG9uZV9UZXh0X0lucHV0LCBcIlBob25lX1RleHRfSW5wdXRcIiwgVGV4dF9JbnB1dF0sXG4gICAgW1N0YXRlX1NlbGVjdF9JbnB1dCwgXCJTdGF0ZV9TZWxlY3RfSW5wdXRcIiwgQWpheF9TZWxlY3RfSW5wdXRdLFxuICAgIFtDb3VudHJ5X1NlbGVjdF9JbnB1dCwgXCJDb3VudHJ5X1NlbGVjdF9JbnB1dFwiLCBBamF4X1NlbGVjdF9JbnB1dF0sXG4gICAgW1Byb2ZpbGVfUGhvdG9fSW5wdXQsIFwiUHJvZmlsZV9QaG90b19JbnB1dFwiLCBGb3JtX0lucHV0X0Fic3RyYWN0XSxcbiAgICBbUnN4X1RhYnMsIFwiUnN4X1RhYnNcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1JzeF9UYWIsIFwiUnN4X1RhYlwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUnN4X0Zvcm0sIFwiUnN4X0Zvcm1cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1Bpbl9WZXJpZmljYXRpb25fRm9ybSwgXCJQaW5fVmVyaWZpY2F0aW9uX0Zvcm1cIiwgUnN4X0Zvcm1dLFxuICAgIFtGb3JtX0ZpZWxkX0Fic3RyYWN0LCBcIkZvcm1fRmllbGRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fRmllbGQsIFwiRm9ybV9GaWVsZFwiLCBGb3JtX0ZpZWxkX0Fic3RyYWN0XSxcbiAgICBbRm9ybV9IaWRkZW5fRmllbGQsIFwiRm9ybV9IaWRkZW5fRmllbGRcIiwgRm9ybV9GaWVsZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX0Rhc2hib2FyZCwgXCJGcm9udGVuZF9EYXNoYm9hcmRcIiwgbnVsbF0sXG4gICAgW0NsaWVudHNfRGF0YUdyaWQsIFwiQ2xpZW50c19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHNfRWRpdCwgXCJGcm9udGVuZF9DbGllbnRzX0VkaXRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHNfVmlldywgXCJGcm9udGVuZF9DbGllbnRzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHMsIFwiRnJvbnRlbmRfQ2xpZW50c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVGVhbSwgXCJGcm9udGVuZF9TZXR0aW5nc19UZWFtXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zLCBcIkZyb250ZW5kX1NldHRpbmdzX05vdGlmaWNhdGlvbnNcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX0JpbGxpbmcsIFwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZ1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0LCBcIkZyb250ZW5kX1NldHRpbmdzX0ltcG9ydFwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfQXBpLCBcIkZyb250ZW5kX1NldHRpbmdzX0FwaVwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzLCBcIkZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXQsIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRGlzcGxheSwgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXlcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5nc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHksIFwiRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzLCBcIkZyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzXCIsIG51bGxdLFxuICAgIFtVc2Vyc19EYXRhR3JpZCwgXCJVc2Vyc19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0FkZF9Vc2VyX0Zvcm0sIFwiQWRkX1VzZXJfRm9ybVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWRkX1VzZXJfTW9kYWwsIFwiQWRkX1VzZXJfTW9kYWxcIiwgTW9kYWxfQWJzdHJhY3RdLFxuICAgIFtTZW5kX1VzZXJfSW52aXRlX01vZGFsLCBcIlNlbmRfVXNlcl9JbnZpdGVfTW9kYWxcIiwgTW9kYWxfQWJzdHJhY3RdLFxuICAgIFtGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50XCIsIG51bGxdLFxuICAgIFtFZGl0X1VzZXJfTW9kYWwsIFwiRWRpdF9Vc2VyX01vZGFsXCIsIE1vZGFsX0Fic3RyYWN0XSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NcIiwgbnVsbF0sXG4gICAgW0NvbnRhY3RzX0RhdGFHcmlkLCBcIkNvbnRhY3RzX0RhdGFHcmlkXCIsIERhdGFHcmlkX0Fic3RyYWN0XSxcbiAgICBbRGF0YV9UYWJsZSwgXCJEYXRhX1RhYmxlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDbGllbnRfU2VsZWN0b3JfSW5wdXQsIFwiQ2xpZW50X1NlbGVjdG9yX0lucHV0XCIsIEFqYXhfU2VsZWN0X0lucHV0XSxcbiAgICBbRnJvbnRlbmRfQ29udGFjdHNfRWRpdCwgXCJGcm9udGVuZF9Db250YWN0c19FZGl0XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9Db250YWN0c19WaWV3LCBcIkZyb250ZW5kX0NvbnRhY3RzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NvbnRhY3RzLCBcIkZyb250ZW5kX0NvbnRhY3RzXCIsIG51bGxdLFxuICAgIFtQcm9qZWN0c19EYXRhR3JpZCwgXCJQcm9qZWN0c19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzX0VkaXQsIFwiRnJvbnRlbmRfUHJvamVjdHNfRWRpdFwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUHJvamVjdHNfTGlzdCwgXCJGcm9udGVuZF9Qcm9qZWN0c19MaXN0XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9Qcm9qZWN0c19WaWV3LCBcIkZyb250ZW5kX1Byb2plY3RzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzX0FkZCwgXCJGcm9udGVuZF9Qcm9qZWN0c19BZGRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzLCBcIkZyb250ZW5kX1Byb2plY3RzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9UYXNrcywgXCJGcm9udGVuZF9UYXNrc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfVGFza3NfVmlldywgXCJGcm9udGVuZF9UYXNrc19WaWV3XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9UYXNrc19BZGQsIFwiRnJvbnRlbmRfVGFza3NfQWRkXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9DYWxlbmRhciwgXCJGcm9udGVuZF9DYWxlbmRhclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnQsIFwiRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0ludm9pY2VzLCBcIkZyb250ZW5kX0ludm9pY2VzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9JbnZvaWNlc19WaWV3LCBcIkZyb250ZW5kX0ludm9pY2VzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0ludm9pY2VzX0FkZCwgXCJGcm9udGVuZF9JbnZvaWNlc19BZGRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1JlcG9ydHMsIFwiRnJvbnRlbmRfUmVwb3J0c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlLCBcIkZyb250ZW5kX1JlcG9ydHNfUmV2ZW51ZVwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzLCBcIkZyb250ZW5kX1JlcG9ydHNfQ2xpZW50c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cywgXCJGcm9udGVuZF9SZXBvcnRzX1Byb2plY3RzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9SZXBvcnRzX1RpbWUsIFwiRnJvbnRlbmRfUmVwb3J0c19UaW1lXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9BY2NvdW50LCBcIkZyb250ZW5kX0FjY291bnRcIiwgbnVsbF0sXG4gICAgW1JzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLCBcIlJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyXCIsIG51bGxdLFxuICAgIFtDbGllbnRfRGVwYXJ0bWVudF9Nb2RlbCwgXCJDbGllbnRfRGVwYXJ0bWVudF9Nb2RlbFwiLCBudWxsXSxcbiAgICBbQ2xpZW50X01vZGVsLCBcIkNsaWVudF9Nb2RlbFwiLCBudWxsXSxcbiAgICBbQ29udGFjdF9Nb2RlbCwgXCJDb250YWN0X01vZGVsXCIsIG51bGxdLFxuICAgIFtQcm9qZWN0X01vZGVsLCBcIlByb2plY3RfTW9kZWxcIiwgbnVsbF0sXG4gICAgW1Rhc2tfTW9kZWwsIFwiVGFza19Nb2RlbFwiLCBudWxsXSxcbiAgICBbRGVtb19Qcm9kdWN0X01vZGVsLCBcIkRlbW9fUHJvZHVjdF9Nb2RlbFwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLCBcIkZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9FZGl0X0NvbnRyb2xsZXIsIFwiRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9FZGl0X0NvbnRyb2xsZXJcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlciwgXCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX1NldHRpbmdzX0NvbnRyb2xsZXJcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5X0NvbnRyb2xsZXIsIFwiRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlfQ29udHJvbGxlclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlciwgXCJGcm9udGVuZF9TZXR0aW5nc19BcGlfS2V5c19Db250cm9sbGVyXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlciwgXCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyLCBcIkZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3NfQ29udHJvbGxlclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlciwgXCJGcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyLCBcIkZyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXJcIiwgbnVsbF1cbl0pO1xuXG4iLCIvLyBSU1ggUm91dGUgRGVmaW5pdGlvbnMgLSBHZW5lcmF0ZWQgYnkgQnVuZGxlQ29tcGlsZXJcbi8vIFByb3ZpZGVzIHJvdXRlIHBhdHRlcm5zIGZvciB0eXBlLXNhZmUgVVJMIGdlbmVyYXRpb25cblJzeC5fZGVmaW5lX3JvdXRlcyh7XG4gICAgXCJGcm9udGVuZF9EYXNoYm9hcmRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZGFzaGJvYXJkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9jbGllbnRzXCIsXG4gICAgICAgIFwidmlld1wiOiBcIi9jbGllbnRzL3ZpZXcvOmlkXCIsXG4gICAgICAgIFwiYWRkXCI6IFwiL2NsaWVudHMvYWRkXCIsXG4gICAgICAgIFwiZWRpdFwiOiBcIi9jbGllbnRzL2VkaXQvOmlkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfVGVhbV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy90ZWFtXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfTm90aWZpY2F0aW9uc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9ub3RpZmljYXRpb25zXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZ19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9iaWxsaW5nXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2ltcG9ydFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX0FwaV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9hcGlcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19UZW1wbGF0ZXNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdGVtcGxhdGVzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvYXVkaXRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19BY2NvdW50X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2FjY291bnRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19HZW5lcmFsX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2dlbmVyYWxcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Byb2ZpbGVcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXlfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvcHJvZmlsZV9kaXNwbGF5XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9FZGl0X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Byb2ZpbGVfZWRpdFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9zZXR0aW5nc1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Bhc3N3b3JkX3NlY3VyaXR5XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvYXBpX2tleXNcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50XCIsXG4gICAgICAgIFwidmlld1wiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvOmlkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9zaXRlX3NldHRpbmdzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvY29udGFjdHNcIixcbiAgICAgICAgXCJ2aWV3XCI6IFwiL2NvbnRhY3RzL3ZpZXcvOmlkXCIsXG4gICAgICAgIFwiYWRkXCI6IFwiL2NvbnRhY3RzL2FkZFwiLFxuICAgICAgICBcImVkaXRcIjogXCIvY29udGFjdHMvZWRpdC86aWRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9wcm9qZWN0c1wiLFxuICAgICAgICBcInZpZXdcIjogXCIvcHJvamVjdHMvdmlldy86aWRcIixcbiAgICAgICAgXCJhZGRcIjogXCIvcHJvamVjdHMvYWRkXCIsXG4gICAgICAgIFwiZWRpdFwiOiBcIi9wcm9qZWN0cy9lZGl0LzppZFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1Rhc2tzX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3Rhc2tzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfVGFza3NfVmlld19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi90YXNrcy92aWV3XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfVGFza3NfQWRkX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3Rhc2tzL2FkZFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0NhbGVuZGFyX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2NhbGVuZGFyXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvY2FsZW5kYXIvZXZlbnRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9JbnZvaWNlc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9pbnZvaWNlc1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0ludm9pY2VzX1ZpZXdfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvaW52b2ljZXMvdmlld1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0ludm9pY2VzX0FkZF9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9pbnZvaWNlcy9hZGRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9SZXBvcnRzX0NsaWVudHNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvcmVwb3J0cy9jbGllbnRzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzL3Byb2plY3RzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3JlcG9ydHMvcmV2ZW51ZVwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1JlcG9ydHNfVGltZV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzL3RpbWVcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9BY2NvdW50X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL2FjY291bnRcIlxuICAgIH1cbn0pO1xuIiwiJChkb2N1bWVudCkucmVhZHkoYXN5bmMgZnVuY3Rpb24oKSB7XG50cnkge1xuY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCAnRG9jdW1lbnQgcmVhZHksIHN0YXJ0aW5nIFJzeC5fcnN4X2NvcmVfYm9vdCcpO1xuYXdhaXQgUnN4Ll9yc3hfY29yZV9ib290KCk7XG5jb25zb2xlX2RlYnVnKCdSU1hfSU5JVCcsICdJbml0aWFsaXphdGlvbiBjb21wbGV0ZScpO1xufSBjYXRjaCAoZXJyb3IpIHtcbmNvbnNvbGUuZXJyb3IoJ1tSU1hfSU5JVF0gSW5pdGlhbGl6YXRpb24gZmFpbGVkOicsIGVycm9yKTtcbmNvbnNvbGUuZXJyb3IoJ1tSU1hfSU5JVF0gU3RhY2s6JywgZXJyb3Iuc3RhY2spO1xudGhyb3cgZXJyb3I7XG59XG59KTsiXSwic291cmNlUm9vdCI6IiJ9
|