UNPKG

faastjs

Version:

Serverless batch computing made simple.

170 lines 52.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.filterMessages = exports.FunctionExecutionMetrics = exports.FunctionStats = exports.CleanupOptionDefaults = exports.commonDefaults = void 0; const shared_1 = require("./shared"); exports.commonDefaults = { childProcess: true, childProcessMemoryMb: 0, concurrency: 100, description: "", exclude: [], include: [], rate: 0, env: {}, gc: "auto", maxRetries: 2, memorySize: 1024, mode: "auto", packageJson: "", useDependencyCaching: true, retentionInDays: 1, speculativeRetryThreshold: 3, timeout: 60, webpackOptions: {}, validateSerialization: true, debugOptions: {} }; exports.CleanupOptionDefaults = { deleteResources: true, deleteCaches: false, gcTimeout: 10 }; /** * Summary statistics for function invocations. * @remarks * ``` * localStartLatency remoteStartLatency executionTime * ◀──────────────────▶◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷◀──────────▶ * * ┌───────────────────────────────────┬──────────────────────────────────────┐ * │ │ │ * │ Local │ Cloud Provider │ * │ │ │ * │ ┌─────────┐ │ ┌──────────┐ ┌──────────┐ │ * │ │ │ │ │ │ │ │ │ * │ │ local │ │ │ request │ │ │ │ * │ invoke ────────▶│ queue │────┼──▶│ queue ├────────▶│ │ │ * │ │ │ │ │ │ │ │ │ * │ └─────────┘ │ └──────────┘ │ cloud │ │ * │ │ │ function │ │ * │ ┌─────────┐ │ ┌──────────┐ │ │ │ * │ │ │ │ │ │ │ │ │ * │ result ◀────────│ local │◀───┼───│ response │◀────────│ │ │ * │ │ polling │ │ │ queue │ │ │ │ * │ │ │ │ │ │ │ │ │ * │ └─────────┘ │ └──────────┘ └──────────┘ │ * │ │ │ * └───────────────────────────────────┴──────────────────────────────────────┘ * * ◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷ * returnLatency ◀───────▶ * sendResponseLatency * ``` * * `localStartLatency` and `executionTime` are measured on one machine and are * free of clock skew. `remoteStartLatency` and `returnLatency` are measured as * time differences between machines and are subject to much more uncertainty, * and effects like clock skew. * * All times are in milliseconds. * * @public */ class FunctionStats { constructor() { /** * Statistics for how long invocations stay in the local queue before being * sent to the cloud provider. */ this.localStartLatency = new shared_1.Statistics(); /** * Statistics for how long requests take to start execution after being sent * to the cloud provider. This typically includes remote queueing and cold * start times. Because this measurement requires comparing timestamps from * different machines, it is subject to clock skew and other effects, and * should not be considered highly accurate. It can be useful for detecting * excessively high latency problems. Faast.js attempt to correct for clock * skew heuristically. */ this.remoteStartLatency = new shared_1.Statistics(); /** * Statistics for function execution time in milliseconds. This is measured * as wall clock time inside the cloud function, and does not include the * time taken to send the response to the response queue. Note that most * cloud providers round up to the next 100ms for pricing. */ this.executionTime = new shared_1.Statistics(); /** * Statistics for how long it takes to send the response to the response * queue. */ this.sendResponseLatency = new shared_1.Statistics(); /** * Statistics for how long it takes to return a response from the end of * execution time to the receipt of the response locally. This measurement * requires comparing timestamps from different machines, and is subject to * clock skew and other effects. It should not be considered highly * accurate. It can be useful for detecting excessively high latency * problems. Faast.js attempts to correct for clock skew heuristically. */ this.returnLatency = new shared_1.Statistics(); /** * Statistics for amount of time billed. This is similar to * {@link FunctionStats.executionTime} except each sampled time is rounded * up to the next 100ms. */ this.estimatedBilledTime = new shared_1.Statistics(); /** * The number of invocations attempted. If an invocation is retried, this * only counts the invocation once. */ this.invocations = 0; /** * The number of invocations that were successfully completed. */ this.completed = 0; /** * The number of invocation retries attempted. This counts retries * attempted by faast.js to recover from transient errors, but does not * count retries by the cloud provider. */ this.retries = 0; /** * The number of invocations that resulted in an error. If an invocation is * retried, an error is only counted once, no matter how many retries were * attempted. */ this.errors = 0; } /** * Summarize the function stats as a string. * @returns a string showing the value of completed, retries, errors, and * mean execution time. This string excludes invocations by default because * it is often fixed. */ toString() { return `completed: ${this.completed}, retries: ${this.retries}, errors: ${this.errors}, executionTime.mean: ${this.executionTime.mean}ms`; } /** @internal */ clone() { const rv = Object.assign(Object.create(Object.getPrototypeOf(this)), this); for (const key of (0, shared_1.keysOf)(rv)) { if (typeof rv[key] !== "number") { rv[key] = rv[key].clone(); } } return rv; } } exports.FunctionStats = FunctionStats; class FunctionExecutionMetrics { constructor() { this.secondMetrics = []; } } exports.FunctionExecutionMetrics = FunctionExecutionMetrics; function filterMessages(messages, kind) { return messages.filter((msg) => msg.kind === kind); } exports.filterMessages = filterMessages; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEscUNBQThDO0FBK1pqQyxRQUFBLGNBQWMsR0FBNEI7SUFDbkQsWUFBWSxFQUFFLElBQUk7SUFDbEIsb0JBQW9CLEVBQUUsQ0FBQztJQUN2QixXQUFXLEVBQUUsR0FBRztJQUNoQixXQUFXLEVBQUUsRUFBRTtJQUNmLE9BQU8sRUFBRSxFQUFFO0lBQ1gsT0FBTyxFQUFFLEVBQUU7SUFDWCxJQUFJLEVBQUUsQ0FBQztJQUNQLEdBQUcsRUFBRSxFQUFFO0lBQ1AsRUFBRSxFQUFFLE1BQU07SUFDVixVQUFVLEVBQUUsQ0FBQztJQUNiLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLElBQUksRUFBRSxNQUFNO0lBQ1osV0FBVyxFQUFFLEVBQUU7SUFDZixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLHlCQUF5QixFQUFFLENBQUM7SUFDNUIsT0FBTyxFQUFFLEVBQUU7SUFDWCxjQUFjLEVBQUUsRUFBRTtJQUNsQixxQkFBcUIsRUFBRSxJQUFJO0lBQzNCLFlBQVksRUFBRSxFQUFFO0NBQ25CLENBQUM7QUFnRFcsUUFBQSxxQkFBcUIsR0FBNkI7SUFDM0QsZUFBZSxFQUFFLElBQUk7SUFDckIsWUFBWSxFQUFFLEtBQUs7SUFDbkIsU0FBUyxFQUFFLEVBQUU7Q0FDaEIsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NHO0FBQ0gsTUFBYSxhQUFhO0lBQTFCO1FBQ0k7OztXQUdHO1FBQ0gsc0JBQWlCLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDckM7Ozs7Ozs7O1dBUUc7UUFDSCx1QkFBa0IsR0FBRyxJQUFJLG1CQUFVLEVBQUUsQ0FBQztRQUN0Qzs7Ozs7V0FLRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7OztXQUdHO1FBQ0gsd0JBQW1CLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDdkM7Ozs7Ozs7V0FPRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7Ozs7V0FJRztRQUNILHdCQUFtQixHQUFHLElBQUksbUJBQVUsRUFBRSxDQUFDO1FBQ3ZDOzs7V0FHRztRQUNILGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCOztXQUVHO1FBQ0gsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkOzs7O1dBSUc7UUFDSCxZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ1o7Ozs7V0FJRztRQUNILFdBQU0sR0FBRyxDQUFDLENBQUM7SUFvQmYsQ0FBQztJQW5CRzs7Ozs7T0FLRztJQUNILFFBQVE7UUFDSixPQUFPLGNBQWMsSUFBSSxDQUFDLFNBQVMsY0FBYyxJQUFJLENBQUMsT0FBTyxhQUFhLElBQUksQ0FBQyxNQUFNLHlCQUF5QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzlJLENBQUM7SUFDRCxnQkFBZ0I7SUFDaEIsS0FBSztRQUNELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFBLGVBQU0sRUFBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzNCLElBQUksT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDOUIsQ0FBQztRQUNMLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7Q0FDSjtBQW5GRCxzQ0FtRkM7QUFFRCxNQUFhLHdCQUF3QjtJQUFyQztRQUNJLGtCQUFhLEdBQWlCLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0NBQUE7QUFGRCw0REFFQztBQW9ERCxTQUFnQixjQUFjLENBQWlCLFFBQW1CLEVBQUUsSUFBTztJQUN2RSxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQ2xCLENBQUMsR0FBWSxFQUF3QyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxJQUFJLENBQzVFLENBQUM7QUFDTixDQUFDO0FBSkQsd0NBSUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgd2VicGFjayBmcm9tIFwid2VicGFja1wiO1xuaW1wb3J0IHsgQ29zdFNuYXBzaG90IH0gZnJvbSBcIi4vY29zdFwiO1xuaW1wb3J0IHsga2V5c09mLCBTdGF0aXN0aWNzIH0gZnJvbSBcIi4vc2hhcmVkXCI7XG5pbXBvcnQgeyBDcHVNZWFzdXJlbWVudCwgRnVuY3Rpb25DYWxsIH0gZnJvbSBcIi4vd3JhcHBlclwiO1xuXG4vKipcbiAqIFRoZSB0eXBlIG9mIGFsbCBzdXBwb3J0ZWQgY2xvdWQgcHJvdmlkZXJzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBQcm92aWRlciA9IFwiYXdzXCIgfCBcImxvY2FsXCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIHtAbGluayBDb21tb25PcHRpb25zLmluY2x1ZGV9IG9wdGlvbi5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmNsdWRlT3B0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IG9yIGdsb2IgdG8gYWRkIHRvIHRoZSBjbG91ZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwYXRoOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIHdvcmtpbmcgZGlyZWN0b3J5IGlmIGBwYXRoYCBpcyByZWxhdGl2ZS4gRGVmYXVsdHMgdG8gYHByb2Nlc3MuY3dkKClgLlxuICAgICAqIEZvciBleGFtcGxlLCBpZiBgY3dkYCBpcyBgXCJmb29cImAgYW5kIGBwYXRoYCBpcyBgXCJiYXJcImAsIHRoZW4gdGhlXG4gICAgICogY29udGVudHMgb2YgdGhlIGRpcmVjdG9yeSBgZm9vL2Jhci9gIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHJlbW90ZVxuICAgICAqIGZ1bmN0aW9uIHVuZGVyIHRoZSBwYXRoIGBiYXIvYC5cbiAgICAgKi9cbiAgICBjd2Q/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBjb21tb24gYWNyb3NzIGFsbCBmYWFzdC5qcyBwcm92aWRlcnMuIFVzZWQgYXMgYXJndW1lbnQgdG8ge0BsaW5rIGZhYXN0fS5cbiAqIEByZW1hcmtzXG4gKiBUaGVyZSBhcmUgYWxzbyBtb3JlIHNwZWNpZmljIG9wdGlvbnMgZm9yIGVhY2ggcHJvdmlkZXIuIFNlZVxuICoge0BsaW5rIEF3c09wdGlvbnN9IGFuZCB7QGxpbmsgTG9jYWxPcHRpb25zfS5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21tb25PcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCBjcmVhdGUgYSBjaGlsZCBwcm9jZXNzIHRvIGlzb2xhdGUgdXNlciBjb2RlIGZyb20gZmFhc3RcbiAgICAgKiBzY2FmZm9sZGluZy4gRGVmYXVsdDogdHJ1ZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIElmIGEgY2hpbGQgcHJvY2VzcyBpcyBub3QgY3JlYXRlZCwgZmFhc3QgcnVucyBpbiB0aGUgc2FtZSBub2RlIGluc3RhbmNlXG4gICAgICogYXMgdGhlIHVzZXIgY29kZSBhbmQgbWF5IG5vdCBleGVjdXRlIGluIGEgdGltZWx5IGZhc2hpb24gYmVjYXVzZSB1c2VyXG4gICAgICogY29kZSBtYXlcbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9ub2RlanMub3JnL2VuL2RvY3MvZ3VpZGVzL2RvbnQtYmxvY2stdGhlLWV2ZW50LWxvb3AvIHwgYmxvY2sgdGhlIGV2ZW50IGxvb3B9LlxuICAgICAqIENyZWF0aW5nIGEgY2hpbGQgcHJvY2VzcyBmb3IgdXNlciBjb2RlIGFsbG93cyBmYWFzdC5qcyB0byBjb250aW51ZVxuICAgICAqIGV4ZWN1dGluZyBldmVuIGlmIHVzZXIgY29kZSBuZXZlciB5aWVsZHMuIFRoaXMgcHJvdmlkZXMgYmV0dGVyXG4gICAgICogcmVsaWFiaWxpdHkgYW5kIGZ1bmN0aW9uYWxpdHk6XG4gICAgICpcbiAgICAgKiAtIERldGVjdCB0aW1lb3V0IGVycm9ycyBtb3JlIHJlbGlhYmx5LCBldmVuIGlmIHRoZSBmdW5jdGlvbiBkb2Vzbid0XG4gICAgICogICByZWxpbnF1aXNoIHRoZSBDUFUuIE5vdCBhcHBsaWNhYmxlIHRvIEFXUywgd2hpY2ggc2VuZHMgc2VwYXJhdGUgZmFpbHVyZVxuICAgICAqICAgbWVzc2FnZXMgaW4gY2FzZSBvZiB0aW1lb3V0LiBTZWUge0BsaW5rIENvbW1vbk9wdGlvbnMudGltZW91dH0uXG4gICAgICpcbiAgICAgKiAtIENQVSBtZXRyaWNzIHVzZWQgZm9yIGRldGVjdGluZyBpbnZvY2F0aW9ucyB3aXRoIGhpZ2ggbGF0ZW5jeSwgd2hpY2ggY2FuXG4gICAgICogICBiZSB1c2VkIGZvciBhdXRvbWF0aWNhbGx5IHJldHJ5aW5nIGNhbGxzIHRvIHJlZHVjZSB0YWlsIGxhdGVuY3kuXG4gICAgICpcbiAgICAgKiBUaGUgY29zdCBvZiBjcmVhdGluZyBhIGNoaWxkIHByb2Nlc3MgaXMgbWFpbmx5IGluIHRoZSBtZW1vcnkgb3ZlcmhlYWQgb2ZcbiAgICAgKiBjcmVhdGluZyBhbm90aGVyIG5vZGUgcHJvY2Vzcy5cbiAgICAgKi9cbiAgICBjaGlsZFByb2Nlc3M/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hlbiBjaGlsZFByb2Nlc3MgaXMgdHJ1ZSwgdGhlIGNoaWxkIHByb2Nlc3Mgd2lsbCBiZSBzcGF3bmVkIHdpdGggdGhlXG4gICAgICogdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSBhcyB0aGUgc2V0dGluZyBmb3IgLS1tYXgtb2xkLXNwYWNlLXNpemUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGlzIGlzIHVzZWZ1bCBpZiBhIGZ1bmN0aW9uIHJlcXVpcmVzIHRoZSBub2RlIHByb2Nlc3MgdG8gbGltaXQgaXRzXG4gICAgICogbWVtb3J5IHNvIHRoYXQgYW5vdGhlciBzcGF3bmVkIHByb2Nlc3MgKGUuZy4gYSBicm93c2VyIGluc3RhbmNlKSBjYW4gdXNlXG4gICAgICogdGhlIHJlc3QuXG4gICAgICogQHB1YmxpY1xuICAgICAqL1xuICAgIGNoaWxkUHJvY2Vzc01lbW9yeU1iPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjb25jdXJyZW50IGludm9jYXRpb25zIHRvIGFsbG93LiBEZWZhdWx0OiAxMDAsXG4gICAgICogZXhjZXB0IGZvciB0aGUgYGxvY2FsYCBwcm92aWRlciwgd2hlcmUgdGhlIGRlZmF1bHQgaXMgMTAuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGUgY29uY3VycmVuY3kgbGltaXQgYXBwbGllcyB0byBhbGwgaW52b2NhdGlvbnMgb2YgYWxsIG9mIHRoZSBmYWFzdFxuICAgICAqIGZ1bmN0aW9ucyBzdW1tZWQgdG9nZXRoZXIuIEl0IGlzIG5vdCBhIHBlci1mdW5jdGlvbiBsaW1pdC4gVG8gYXBwbHkgYVxuICAgICAqIHBlci1mdW5jdGlvbiBsaW1pdCwgdXNlIHtAbGluayB0aHJvdHRsZX0uIEEgdmFsdWUgb2YgMCBpcyBlcXVpdmFsZW50IHRvXG4gICAgICogSW5maW5pdHkuIEEgdmFsdWUgb2YgMSBlbnN1cmVzIG11dHVhbGx5IGV4Y2x1c2l2ZSBpbnZvY2F0aW9ucy5cbiAgICAgKi9cbiAgICBjb25jdXJyZW5jeT86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBBIHVzZXItc3VwcGxpZWQgZGVzY3JpcHRpb24gZm9yIHRoaXMgZnVuY3Rpb24sIHdoaWNoIG1heSBtYWtlIGl0IGVhc2llclxuICAgICAqIHRvIHRyYWNrIGRpZmZlcmVudCBmdW5jdGlvbnMgd2hlbiBtdWx0aXBsZSBmdW5jdGlvbnMgYXJlIGNyZWF0ZWQuXG4gICAgICovXG4gICAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogRXhjbHVkZSBhIHN1YnNldCBvZiBmaWxlcyBpbmNsdWRlZCBieSB7QGxpbmsgQ29tbW9uT3B0aW9ucy5pbmNsdWRlfS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFRoZSBleGNsdXNpb24gY2FuIGJlIGEgZGlyZWN0b3J5IG9yIGdsb2IuIEV4Y2x1c2lvbnMgYXBwbHkgdG8gYWxsIGluY2x1ZGVkXG4gICAgICogZW50cmllcy5cbiAgICAgKi9cbiAgICBleGNsdWRlPzogc3RyaW5nW107XG4gICAgLyoqXG4gICAgICogUmF0ZSBsaW1pdCBpbnZvY2F0aW9ucyAoaW52b2NhdGlvbnMvc2VjKS4gRGVmYXVsdDogbm8gcmF0ZSBsaW1pdC5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFNvbWUgc2VydmljZXMgY2Fubm90IGhhbmRsZSBtb3JlIHRoYW4gYSBjZXJ0YWluIG51bWJlciBvZiByZXF1ZXN0cyBwZXJcbiAgICAgKiBzZWNvbmQsIGFuZCBpdCBpcyBlYXN5IHRvIG92ZXJ3aGVsbSB0aGVtIHdpdGggYSBsYXJnZSBudW1iZXIgb2YgY2xvdWRcbiAgICAgKiBmdW5jdGlvbnMuIFNwZWNpZnkgYSByYXRlIGxpbWl0IGluIGludm9jYXRpb24vc2Vjb25kIHRvIHJlc3RyaWN0IGhvd1xuICAgICAqIGZhYXN0LmpzIGlzc3VlcyByZXF1ZXN0cy5cbiAgICAgKi9cbiAgICByYXRlPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIEVudmlyb25tZW50IHZhcmlhYmxlcyBhdmFpbGFibGUgZHVyaW5nIHNlcnZlcmxlc3MgZnVuY3Rpb24gZXhlY3V0aW9uLlxuICAgICAqIERlZmF1bHQ6IFxce1xcfS5cbiAgICAgKi9cbiAgICBlbnY/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuICAgIC8qKlxuICAgICAqIEdhcmJhZ2UgY29sbGVjdG9yIG1vZGUuIERlZmF1bHQ6IGBcImF1dG9cImAuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gZGVsZXRlcyByZXNvdXJjZXMgdGhhdCB3ZXJlIGNyZWF0ZWQgYnkgcHJldmlvdXNcbiAgICAgKiBpbnN0YW50aWF0aW9ucyBvZiBmYWFzdCB0aGF0IHdlcmUgbm90IGNsZWFuZWQgdXAgYnlcbiAgICAgKiB7QGxpbmsgRmFhc3RNb2R1bGUuY2xlYW51cH0sIGVpdGhlciBiZWNhdXNlIGl0IHdhcyBub3QgY2FsbGVkIG9yIGJlY2F1c2VcbiAgICAgKiB0aGUgcHJvY2VzcyB0ZXJtaW5hdGVkIGFuZCBkaWQgbm90IGV4ZWN1dGUgdGhpcyBjbGVhbnVwIHN0ZXAuIEluIGBcImF1dG9cImBcbiAgICAgKiBtb2RlLCBnYXJiYWdlIGNvbGxlY3Rpb24gbWF5IGJlIHRocm90dGxlZCB0byBydW4gdXAgdG8gb25jZSBwZXIgaG91ciBub1xuICAgICAqIG1hdHRlciBob3cgbWFueSBmYWFzdC5qcyBpbnN0YW5jZXMgYXJlIGNyZWF0ZWQuIEluIGBcImZvcmNlXCJgIG1vZGUsXG4gICAgICogZ2FyYmFnZSBjb2xsZWN0aW9uIGlzIHJ1biB3aXRob3V0IHJlZ2FyZCB0byB3aGV0aGVyIGFub3RoZXIgZ2MgaGFzXG4gICAgICogYWxyZWFkeSBiZWVuIHBlcmZvcm1lZCByZWNlbnRseS4gSW4gYFwib2ZmXCJgIG1vZGUsIGdhcmJhZ2UgY29sbGVjdGlvbiBpc1xuICAgICAqIHNraXBwZWQgZW50aXJlbHkuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGVyZm9ybWFuY2Utc2Vuc2l0aXZlIHRlc3RzLCBvclxuICAgICAqIGZvciBtb3JlIGNvbnRyb2wgb3ZlciB3aGVuIGdjIGlzIHBlcmZvcm1lZC5cbiAgICAgKlxuICAgICAqIEdhcmJhZ2UgY29sbGVjdGlvbiBpcyBjbG91ZC1zcGVjaWZpYywgYnV0IGluIGdlbmVyYWwgZ2FyYmFnZSBjb2xsZWN0aW9uXG4gICAgICogc2hvdWxkIG5vdCBpbnRlcmZlcmUgd2l0aCB0aGUgYmVoYXZpb3Igb3IgcGVyZm9ybWFuY2Ugb2YgZmFhc3QgY2xvdWRcbiAgICAgKiBmdW5jdGlvbnMuIFdoZW4ge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9IHJ1bnMsIGl0IHdhaXRzIGZvciBnYXJiYWdlXG4gICAgICogY29sbGVjdGlvbiB0byBjb21wbGV0ZS4gVGhlcmVmb3JlIHRoZSBjbGVhbnVwIHN0ZXAgY2FuIGluIHNvbWVcbiAgICAgKiBjaXJjdW1zdGFuY2VzIHRha2UgYSBzaWduaWZpY2FudCBhbW91bnQgb2YgdGltZSBldmVuIGFmdGVyIGFsbFxuICAgICAqIGludm9jYXRpb25zIGhhdmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBJdCBpcyBnZW5lcmFsbHkgcmVjb21tZW5kZWQgdG8gbGVhdmUgZ2FyYmFnZSBjb2xsZWN0aW9uIGluIGBcImF1dG9cImAgbW9kZSxcbiAgICAgKiBvdGhlcndpc2UgZ2FyYmFnZSByZXNvdXJjZXMgbWF5IGFjY3VtdWxhdGUgb3ZlciB0aW1lIGFuZCB5b3Ugd2lsbFxuICAgICAqIGV2ZW50dWFsbHkgaGl0IHJlc291cmNlIGxpbWl0cyBvbiB5b3VyIGFjY291bnQuXG4gICAgICpcbiAgICAgKiBBbHNvIHNlZSB7QGxpbmsgQ29tbW9uT3B0aW9ucy5yZXRlbnRpb25JbkRheXN9LlxuICAgICAqL1xuICAgIGdjPzogXCJhdXRvXCIgfCBcImZvcmNlXCIgfCBcIm9mZlwiO1xuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgZmlsZXMgdG8gbWFrZSBhdmFpbGFibGUgaW4gdGhlIHJlbW90ZSBmdW5jdGlvbi4gU2VlXG4gICAgICoge0BsaW5rIEluY2x1ZGVPcHRpb259LlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRWFjaCBpbmNsdWRlIGVudHJ5IGlzIGEgZGlyZWN0b3J5IG9yIGdsb2IgcGF0dGVybi4gUGF0aHMgY2FuIGJlIHNwZWNpZmllZFxuICAgICAqIGFzIHJlbGF0aXZlIG9yIGFic29sdXRlIHBhdGhzLiBSZWxhdGl2ZSBwYXRocyBhcmUgcmVzb2x2ZWQgcmVsYXRpdmUgdG9cbiAgICAgKiB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwgb3IgcmVsYXRpdmUgdG8gdGhlIGBjd2RgIG9wdGlvbi5cbiAgICAgKlxuICAgICAqIElmIHRoZSBpbmNsdWRlIGVudHJ5IGlzIGEgZGlyZWN0b3J5IGBcImZvby9iYXJcImAsIHRoZSBkaXJlY3RvcnlcbiAgICAgKiBgXCIuL2Zvby9iYXJcImAgd2lsbCBiZSBhdmFpbGFibGUgaW4gdGhlIGNsb3VkIGZ1bmN0aW9uLiBEaXJlY3RvcmllcyBhcmVcbiAgICAgKiByZWN1cnNpdmVseSBhZGRlZC5cbiAgICAgKlxuICAgICAqIEdsb2IgcGF0dGVybnMgdXNlIHRoZSBzeW50YXggb2ZcbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2lzYWFjcy9ub2RlLWdsb2IgfCBub2RlIGdsb2J9LlxuICAgICAqXG4gICAgICogQWxzbyBzZWUge0BsaW5rIENvbW1vbk9wdGlvbnMuZXhjbHVkZX0gZm9yIGZpbGUgZXhjbHVzaW9ucy5cbiAgICAgKi9cbiAgICBpbmNsdWRlPzogKHN0cmluZyB8IEluY2x1ZGVPcHRpb24pW107XG4gICAgLyoqXG4gICAgICogTWF4aW11bSBudW1iZXIgb2YgdGltZXMgdGhhdCBmYWFzdCB3aWxsIHJldHJ5IGVhY2ggaW52b2NhdGlvbi4gRGVmYXVsdDogMlxuICAgICAqIChpbnZvY2F0aW9ucyBjYW4gdGhlcmVmb3JlIGJlIGF0dGVtcGVkIDMgdGltZXMgaW4gdG90YWwpLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogUmV0cmllcyBhcmUgYXV0b21hdGljYWxseSBhdHRlbXB0ZWQgZm9yIHRyYW5zaWVudCBpbmZyYXN0cnVjdHVyZS1sZXZlbFxuICAgICAqIGZhaWx1cmVzIHN1Y2ggYXMgcmF0ZSBsaW1pdHMgb3IgbmV0b3dyayBmYWlsdXJlcy4gVXNlci1sZXZlbCBleGNlcHRpb25zXG4gICAgICogYXJlIG5vdCByZXRyaWVkIGF1dG9tYXRpY2FsbHkuIEluIGFkZGl0aW9uIHRvIHJldHJpZXMgcGVyZm9ybWVkIGJ5IGZhYXN0LFxuICAgICAqIHNvbWUgcHJvdmlkZXJzIGF1dG9tYXRpY2FsbHkgYXR0ZW1wdCByZXRyaWVzLiBUaGVzZSBhcmUgbm90IGNvbnRyb2xsYWJsZVxuICAgICAqIGJ5IGZhYXN0LiBCdXQgYXMgYSByZXN1bHQsIHlvdXIgZnVuY3Rpb24gbWF5IGJlIHJldHJpZWQgbWFueSBtb3JlIHRpbWVzXG4gICAgICogdGhhbiB0aGlzIHNldHRpbmcgc3VnZ2VzdHMuXG4gICAgICovXG4gICAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBNZW1vcnkgbGltaXQgZm9yIGVhY2ggZnVuY3Rpb24gaW4gTUIuIFRoaXMgc2V0dGluZyBoYXMgYW4gZWZmZWN0IG9uXG4gICAgICogcHJpY2luZy4gRGVmYXVsdCB2YXJpZXMgYnkgcHJvdmlkZXIuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBFYWNoIHByb3ZpZGVyIGhhcyBkaWZmZXJlbnQgc2V0dGluZ3MgZm9yIG1lbW9yeSBzaXplLCBhbmQgcGVyZm9ybWFuY2VcbiAgICAgKiB2YXJpZXMgZGVwZW5kaW5nIG9uIHRoZSBzZXR0aW5nLiBCeSBkZWZhdWx0IGZhYXN0IHBpY2tzIGEgbGlrZWx5IG9wdGltYWxcbiAgICAgKiB2YWx1ZSBmb3IgZWFjaCBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIC0gYXdzOiAxNzI4TUJcbiAgICAgKlxuICAgICAqIC0gbG9jYWw6IDUxMk1CIChob3dldmVyLCBtZW1vcnkgc2l6ZSBsaW1pdHMgYXJlbid0IHJlbGlhYmxlIGluIGxvY2FsIG1vZGUuKVxuICAgICAqL1xuICAgIG1lbW9yeVNpemU/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBpbnZvY2F0aW9uIG1vZGUuIERlZmF1bHQ6IGBcImF1dG9cImAuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBNb2RlcyBzcGVjaWZ5IGhvdyBpbnZvY2F0aW9ucyBhcmUgdHJpZ2dlcmVkLiBJbiBodHRwcyBtb2RlLCB0aGUgZnVuY3Rpb25zXG4gICAgICogYXJlIGludm9rZWQgdGhyb3VnaCBhbiBodHRwcyByZXF1ZXN0IG9yIHRoZSBwcm92aWRlcidzIEFQSS4gSW4gcXVldWVcbiAgICAgKiBtb2RlLCBhIHByb3ZpZGVyLXNwZWNpZmljIHF1ZXVlIGlzIHVzZWQgdG8gaW52b2tlIGZ1bmN0aW9ucy4gUXVldWUgbW9kZVxuICAgICAqIGFkZHMgYWRkaXRpb25hbCBsYXRlbmN5IGFuZCAodXN1YWxseSBuZWdsaWdpYmxlKSBjb3N0LCBidXQgbWF5IHNjYWxlXG4gICAgICogYmV0dGVyIGZvciBzb21lIHByb3ZpZGVycy4gSW4gYXV0byBtb2RlIHRoZSBiZXN0IGRlZmF1bHQgaXMgY2hvc2VuIGZvclxuICAgICAqIGVhY2ggcHJvdmlkZXIgZGVwZW5kaW5nIG9uIGl0cyBwYXJ0aWN1bGFyIHBlcmZvcm1hbmNlIGNoYXJhY3RlcmlzdGljcy5cbiAgICAgKlxuICAgICAqIFRoZSBkZWZhdWx0cyBhcmU6XG4gICAgICpcbiAgICAgKiAtIGF3czogYFwiYXV0b1wiYCBpcyBgXCJodHRwc1wiYC4gSW4gaHR0cHMgbW9kZSwgdGhlIEFXUyBTREsgYXBpXG4gICAgICogICBpcyB1c2VkIHRvIGludm9rZSBmdW5jdGlvbnMuIEluIHF1ZXVlIG1vZGUsIGFuIEFXUyBTTlMgdG9waWMgaXMgY3JlYXRlZFxuICAgICAqICAgYW5kIHRyaWdnZXJzIGludm9jYXRpb25zLiBUaGUgQVdTIEFQSSBHYXRld2F5IHNlcnZpY2UgaXMgbmV2ZXIgdXNlZCBieVxuICAgICAqICAgZmFhc3QsIGFzIGl0IGluY3VycyBhIGhpZ2hlciBjb3N0IGFuZCBpcyBub3QgbmVlZGVkIHRvIHRyaWdnZXJcbiAgICAgKiAgIGludm9jYXRpb25zLlxuICAgICAqXG4gICAgICogLSBsb2NhbDogVGhlIGxvY2FsIHByb3ZpZGVyIGlnbm9yZXMgdGhlIG1vZGUgc2V0dGluZyBhbmQgYWx3YXlzIHVzZXMgYW5cbiAgICAgKiAgIGludGVybmFsIGFzeW5jaHJvbm91cyBxdWV1ZSB0byBzY2hlZHVsZSBjYWxscy5cbiAgICAgKlxuICAgICAqIFNpemUgbGltaXRzIGFyZSBhZmZlY3RlZCBieSB0aGUgY2hvaWNlIG9mIG1vZGUuIE9uIEFXUyB0aGUgbGltaXQgaXMgMjU2a2JcbiAgICAgKiBmb3IgYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIGluIGBcInF1ZXVlXCJgIG1vZGUsIGFuZCA2TUIgZm9yIGBcImh0dHBzXCJgXG4gICAgICogbW9kZS5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCBubyBtYXR0ZXIgd2hpY2ggbW9kZSBpcyBzZWxlY3RlZCwgZmFhc3QuanMgYWx3YXlzIGNyZWF0ZXMgYVxuICAgICAqIHF1ZXVlIGZvciBzZW5kaW5nIGJhY2sgaW50ZXJtZWRpYXRlIHJlc3VsdHMgZm9yIGJvb2tlZXBpbmcgYW5kXG4gICAgICogcGVyZm9ybWFuY2UgbW9uaXRvcmluZy5cbiAgICAgKi9cbiAgICBtb2RlPzogXCJodHRwc1wiIHwgXCJxdWV1ZVwiIHwgXCJhdXRvXCI7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBhIHBhY2thZ2UuanNvbiBmaWxlIHRvIGluY2x1ZGUgd2l0aCB0aGUgY29kZSBwYWNrYWdlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogQnkgZGVmYXVsdCwgZmFhc3QuanMgd2lsbCB1c2Ugd2VicGFjayB0byBidW5kbGUgZGVwZW5kZW5jaWVzIHlvdXIgcmVtb3RlXG4gICAgICogbW9kdWxlIGltcG9ydHMuIEluIG5vcm1hbCB1c2FnZSB0aGVyZSBpcyBubyBuZWVkIHRvIHNwZWNpZnkgYSBzZXBhcmF0ZVxuICAgICAqIHBhY2thZ2UuanNvbiwgYXMgd2VicGFjayB3aWxsIHN0YXRpY2FsbHkgYW5hbHl6ZSB5b3VyIGltcG9ydHMgYW5kXG4gICAgICogZGV0ZXJtaW5lIHdoaWNoIGZpbGVzIHRvIGJ1bmRsZS5cbiAgICAgKlxuICAgICAqIEhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lIHVzZSBjYXNlcyB3aGVyZSB0aGlzIGlzIG5vdCBlbm91Z2guIEZvciBleGFtcGxlLFxuICAgICAqIHNvbWUgZGVwZW5kZW5jaWVzIGNvbnRhaW4gbmF0aXZlIGNvZGUgY29tcGlsZWQgZHVyaW5nIGluc3RhbGxhdGlvbiwgYW5kXG4gICAgICogd2VicGFjayBjYW5ub3QgYnVuZGxlIHRoZXNlIG5hdGl2ZSBtb2R1bGVzLiBzdWNoIGFzIGRlcGVuZGVuY2llcyB3aXRoXG4gICAgICogbmF0aXZlIGNvZGUuICBvciBhcmUgc3BlY2lmaWNhbGx5IG5vdCBkZXNpZ25lZCB0byB3b3JrIHdpdGggd2VicGFjay4gSW5cbiAgICAgKiB0aGVzZSBjYXNlcywgeW91IGNhbiBjcmVhdGUgYSBzZXBhcmF0ZSBgcGFja2FnZS5qc29uYCBmb3IgdGhlc2VcbiAgICAgKiBkZXBlbmRlbmNpZXMgYW5kIHBhc3MgdGhlIGZpbGVuYW1lIGFzIHRoZSBgcGFja2FnZUpzb25gIG9wdGlvbi4gSWZcbiAgICAgKiBgcGFja2FnZUpzb25gIGlzIGFuIGBvYmplY3RgLCBpdCBpcyBhc3N1bWVkIHRvIGJlIGEgcGFyc2VkIEpTT04gb2JqZWN0XG4gICAgICogd2l0aCB0aGUgc2FtZSBzdHJ1Y3R1cmUgYXMgYSBwYWNrYWdlLmpzb24gZmlsZSAodXNlZnVsIGZvciBzcGVjaWZ5aW5nIGFcbiAgICAgKiBzeW50aGV0aWMgYHBhY2thZ2UuanNvbmAgZGlyZWN0bHkgaW4gY29kZSkuXG4gICAgICpcbiAgICAgKiBUaGUgd2F5IHRoZSBgcGFja2FnZUpzb25gIGlzIGhhbmRsZWQgdmFyaWVzIGJ5IHByb3ZpZGVyOlxuICAgICAqXG4gICAgICogLSBsb2NhbDogUnVucyBgbnBtIGluc3RhbGxgIGluIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeSBpdCBwcmVwYXJlcyBmb3IgdGhlXG4gICAgICogICBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIC0gYXdzOiBSZWN1cnNpdmVseSBjYWxscyBmYWFzdC5qcyB0byBydW4gYG5wbSBpbnN0YWxsYCBpbnNpZGUgYSBzZXBhcmF0ZVxuICAgICAqICAgbGFtYmRhIGZ1bmN0aW9uIHNwZWNpZmljYWxseSBjcmVhdGVkIGZvciB0aGlzIHB1cnBvc2UuIEZhYXN0LmpzIHVzZXNcbiAgICAgKiAgIGxhbWJkYSB0byBpbnN0YWxsIGRlcGVuZGVuY2llcyB0byBlbnN1cmUgdGhhdCBuYXRpdmUgZGVwZW5kZW5jaWVzIGFyZVxuICAgICAqICAgY29tcGlsZWQgaW4gYW4gZW52aXJvbm1lbnQgdGhhdCBjYW4gcHJvZHVjZSBiaW5hcmllcyBsaW5rZWQgYWdhaW5zdFxuICAgICAqICAgbGFtYmRhJ3NcbiAgICAgKiAgIHtAbGluayBodHRwczovL2F3cy5hbWF6b24uY29tL2Jsb2dzL2NvbXB1dGUvcnVubmluZy1leGVjdXRhYmxlcy1pbi1hd3MtbGFtYmRhLyB8IGV4ZWN1dGlvbiBlbnZpcm9ubWVudH0uXG4gICAgICogICBQYWNrYWdlcyBhcmUgc2F2ZWQgaW4gYSBMYW1iZGEgTGF5ZXIuXG4gICAgICpcbiAgICAgKiBGb3IgQVdTLCBpZiB7QGxpbmsgQ29tbW9uT3B0aW9ucy51c2VEZXBlbmRlbmN5Q2FjaGluZ30gaXMgYHRydWVgICh3aGljaFxuICAgICAqIGlzIHRoZSBkZWZhdWx0KSwgdGhlbiB0aGUgTGFtYmRhIExheWVyIGNyZWF0ZWQgd2lsbCBiZSByZXVzZWQgaW4gZnV0dXJlXG4gICAgICogZnVuY3Rpb24gY3JlYXRpb24gcmVxdWVzdHMgaWYgdGhlIGNvbnRlbnRzIG9mIGBwYWNrYWdlSnNvbmAgYXJlIHRoZSBzYW1lLlxuICAgICAqXG4gICAgICogVGhlIGBGQUFTVF9QQUNLQUdFX0RJUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgY2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nXG4gICAgICogYHBhY2thZ2VKc29uYCBpc3N1ZXMuXG4gICAgICovXG4gICAgcGFja2FnZUpzb24/OiBzdHJpbmcgfCBvYmplY3Q7XG4gICAgLyoqXG4gICAgICogQ2FjaGUgaW5zdGFsbGVkIGRlcGVuZGVuY2llcyBmcm9tIHtAbGluayBDb21tb25PcHRpb25zLnBhY2thZ2VKc29ufS4gT25seVxuICAgICAqIGFwcGxpZXMgdG8gQVdTLiBEZWZhdWx0OiB0cnVlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogSWYgYHVzZURlcGVuZGVuY3lDYWNoaW5nYCBpcyBgdHJ1ZWAsIFRoZSByZXN1bHRpbmcgYG5vZGVfbW9kdWxlc2AgZm9sZGVyXG4gICAgICogaXMgY2FjaGVkIGluIGEgTGFtYmRhIExheWVyIHdpdGggdGhlIG5hbWUgYGZhYXN0LSR7a2V5fWAsIHdoZXJlIGBrZXlgIGlzXG4gICAgICogdGhlIFNIQTEgaGFzaCBvZiB0aGUgYHBhY2thZ2VKc29uYCBjb250ZW50cy4gVGhlc2UgY2FjaGUgZW50cmllcyBhcmVcbiAgICAgKiByZW1vdmVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbiwgYnkgZGVmYXVsdCBhZnRlciAyNGguIFVzaW5nIGNhY2hpbmdcbiAgICAgKiByZWR1Y2VzIHRoZSBuZWVkIHRvIGluc3RhbGwgYW5kIHVwbG9hZCBkZXBlbmRlbmNpZXMgZXZlcnkgdGltZSBhIGZ1bmN0aW9uXG4gICAgICogaXMgY3JlYXRlZC4gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIEFXUyBiZWNhdXNlIGl0IGNyZWF0ZXMgYW4gZW50aXJlbHlcbiAgICAgKiBzZXBhcmF0ZSBsYW1iZGEgZnVuY3Rpb24gdG8gaW5zdGFsbCBkZXBlbmRlbmNpZXMgcmVtb3RlbHksIHdoaWNoIGNhblxuICAgICAqIHN1YnN0YW50aWFsbHkgaW5jcmVhc2UgZnVuY3Rpb24gZGVwbG95bWVudCB0aW1lLlxuICAgICAqXG4gICAgICogSWYgYHVzZURlcGVuZGVuY3lDYWNoaW5nYCBpcyBmYWxzZSwgdGhlIGxhbWJkYSBsYXllciBpcyBjcmVhdGVkIHdpdGggdGhlXG4gICAgICogc2FtZSBuYW1lIGFzIHRoZSBsYW1iZGEgZnVuY3Rpb24sIGFuZCB0aGVuIGlzIGRlbGV0ZWQgd2hlbiBjbGVhbnVwIGlzXG4gICAgICogcnVuLlxuICAgICAqL1xuICAgIHVzZURlcGVuZGVuY3lDYWNoaW5nPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGhvdyBtYW55IGRheXMgdG8gd2FpdCBiZWZvcmUgcmVjbGFpbWluZyBjbG91ZCBnYXJiYWdlLiBEZWZhdWx0OlxuICAgICAqIDEuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gb25seSBkZWxldGVzIHJlc291cmNlcyBhZnRlciB0aGV5IGFnZSBiZXlvbmQgYSBjZXJ0YWluXG4gICAgICogbnVtYmVyIG9mIGRheXMuIFRoaXMgb3B0aW9uIHNwZWNpZmllcyBob3cgbWFueSBkYXlzIG9sZCBhIHJlc291cmNlIG5lZWRzXG4gICAgICogdG8gYmUgYmVmb3JlIGJlaW5nIGNvbnNpZGVyZWQgZ2FyYmFnZSBieSB0aGUgY29sbGVjdG9yLiBOb3RlIHRoYXQgdGhpc1xuICAgICAqIHNldHRpbmcgaXMgbm90IHJlY29yZGVkIHdoZW4gdGhlIHJlc291cmNlcyBhcmUgY3JlYXRlZC4gRm9yIGV4YW1wbGUsXG4gICAgICogc3VwcG9zZSB0aGlzIGlzIHRoZSBzZXF1ZW5jZSBvZiBldmVudHM6XG4gICAgICpcbiAgICAgKiAtIERheSAwOiBgZmFhc3QoKWAgaXMgY2FsbGVkIHdpdGggYHJldGVudGlvbkluRGF5c2Agc2V0IHRvIDUuIFRoZW4sIHRoZVxuICAgICAqICAgZnVuY3Rpb24gY3Jhc2hlcyAob3Igb21pdHMgdGhlIGNhbGwgdG8ge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9KS5cbiAgICAgKlxuICAgICAqIC0gRGF5IDE6IGBmYWFzdCgpYCBpcyBjYWxsZWQgd2l0aCBgcmV0ZW50aW9uSW5EYXlzYCBzZXQgdG8gMS5cbiAgICAgKlxuICAgICAqIEluIHRoaXMgc2VxdWVuY2Ugb2YgZXZlbnRzLCBvbiBEYXkgMCB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgcnVucyBhbmRcbiAgICAgKiByZW1vdmVzIHJlc291cmNlcyB3aXRoIGFnZSBvbGRlciB0aGFuIDUgZGF5cy4gVGhlbiB0aGUgZnVuY3Rpb24gbGVhdmVzXG4gICAgICogbmV3IGdhcmJhZ2UgYmVoaW5kIGJlY2F1c2UgaXQgY3Jhc2hlZCBvciBkaWQgbm90IGNvbXBsZXRlIGNsZWFudXAuIE9uIERheVxuICAgICAqIDEsIHRoZSBnYXJiYWdlIGNvbGxlY3RvciBydW5zIGFuZCBkZWxldGVzIHJlc291cmNlcyBhdCBsZWFzdCAxIGRheSBvbGQsXG4gICAgICogd2hpY2ggaW5jbHVkZXMgZ2FyYmFnZSBsZWZ0IGJlaGluZCBmcm9tIERheSAwIChiYXNlZCBvbiB0aGUgY3JlYXRpb25cbiAgICAgKiB0aW1lc3RhbXAgb2YgdGhlIHJlc291cmNlcykuIFRoaXMgZGVsZXRpb24gb2NjdXJzIGV2ZW4gdGhvdWdoIHJldGVudGlvblxuICAgICAqIHdhcyBzZXQgdG8gNSBkYXlzIHdoZW4gcmVzb3VyY2VzIHdlcmUgY3JlYXRlZCBvbiBEYXkgMC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCBpZiBgcmV0ZW50aW9uSW5EYXlzYCBpcyBzZXQgdG8gMCwgZ2FyYmFnZSBjb2xsZWN0aW9uIHdpbGxcbiAgICAgKiByZW1vdmUgYWxsIHJlc291cmNlcywgZXZlbiBvbmVzIHRoYXQgbWF5IGJlIGluIHVzZSBieSBvdGhlciBydW5uaW5nIGZhYXN0XG4gICAgICogaW5zdGFuY2VzLiBOb3QgcmVjb21tZW5kZWQuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIENvbW1vbk9wdGlvbnMuZ2N9LlxuICAgICAqL1xuICAgIHJldGVudGlvbkluRGF5cz86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBSZWR1Y2UgdGFpbCBsYXRlbmN5IGJ5IHJldHJ5aW5nIGludm9jYXRpb25zIHRoYXQgdGFrZSBzdWJzdGFudGlhbGx5XG4gICAgICogbG9uZ2VyIHRoYW4gb3RoZXIgaW52b2NhdGlvbnMgb2YgdGhlIHNhbWUgZnVuY3Rpb24uIERlZmF1bHQ6IDMuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBmYWFzdC5qcyBhdXRvbWF0aWNhbGx5IG1lYXN1cmVzIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gKM+DKSBvZlxuICAgICAqIHRoZSB0aW1lIHRha2VuIGJ5IGludm9jYXRpb25zIG9mIGVhY2ggZnVuY3Rpb24uIFJldHJpZXMgYXJlIGF0dGVtcHRlZFxuICAgICAqIHdoZW4gdGhlIHRpbWUgZm9yIGFuIGludm9jYXRpb24gZXhjZWVkcyB0aGUgbWVhbiB0aW1lIGJ5IGEgY2VydGFpblxuICAgICAqIHRocmVzaG9sZC4gYHNwZWN1bGF0aXZlUmV0cnlUaHJlc2hvbGRgIHNwZWNpZmllcyBob3cgbWFueSBtdWx0aXBsZXMgb2Ygz4NcbiAgICAgKiBhbiBpbnZvY2F0aW9uIG5lZWRzIHRvIGV4Y2VlZCB0aGUgbWVhbiBmb3IgYSBnaXZlbiBmdW5jdGlvbiBiZWZvcmUgcmV0cnlcbiAgICAgKiBpcyBhdHRlbXB0ZWQuXG4gICAgICpcbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBvZiDPgyBpcyAzLiBUaGlzIG1lYW5zIGEgY2FsbCB0byBhIGZ1bmN0aW9uIGlzIHJldHJpZWRcbiAgICAgKiB3aGVuIHRoZSB0aW1lIHRvIGV4ZWN1dGUgZXhjZWVkcyB0aHJlZSBzdGFuZGFyZCBkZXZpYXRpb25zIGZyb20gdGhlIG1lYW5cbiAgICAgKiBvZiBhbGwgcHJpb3IgZXhlY3V0aW9ucyBvZiB0aGUgc2FtZSBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgZmVhdHVyZSBpcyBleHBlcmltZW50YWwuXG4gICAgICogQGJldGFcbiAgICAgKi9cbiAgICBzcGVjdWxhdGl2ZVJldHJ5VGhyZXNob2xkPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIEV4ZWN1dGlvbiB0aW1lIGxpbWl0IGZvciBlYWNoIGludm9jYXRpb24sIGluIHNlY29uZHMuIERlZmF1bHQ6IDYwLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRWFjaCBwcm92aWRlciBoYXMgYSBtYXhpbXVtIHRpbWUgbGltaXQgZm9yIGhvdyBsb25nIGludm9jYXRpb25zIGNhbiBydW5cbiAgICAgKiBiZWZvcmUgYmVpbmcgYXV0b21hdGljYWxseSB0ZXJtaW5hdGVkIChvciBmcm96ZW4pLiBUaGUgZm9sbG93aW5nIGFyZSB0aGVcbiAgICAgKiBtYXhpbXVtIHRpbWUgbGltaXRzIGFzIG9mIEZlYnJ1YXJ5IDIwMTk6XG4gICAgICpcbiAgICAgKiAtIGF3czpcbiAgICAgKiAgIHtAbGluayBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9saW1pdHMuaHRtbCB8IDE1IG1pbnV0ZXN9XG4gICAgICpcbiAgICAgKiAtIGxvY2FsOiB1bmxpbWl0ZWRcbiAgICAgKlxuICAgICAqIEZhYXN0LmpzIGhhcyBhIHByb2FjdGl2ZSB0aW1lb3V0IGRldGVjdGlvbiBmZWF0dXJlLiBJdCBhdXRvbWF0aWNhbGx5XG4gICAgICogYXR0ZW1wdHMgdG8gZGV0ZWN0IHdoZW4gdGhlIHRpbWUgbGltaXQgaXMgYWJvdXQgdG8gYmUgcmVhY2hlZCBhbmRcbiAgICAgKiBwcm9hY3RpdmVseSBzZW5kcyBhIHRpbWVvdXQgZXhjZXB0aW9uLiBGYWFzdCBkb2VzIHRoaXMgYmVjYXVzZSBub3QgYWxsXG4gICAgICogcHJvdmlkZXJzIHJlbGlhYmx5IHNlbmQgdGltZWx5IGZlZWRiYWNrIHdoZW4gdGltZW91dHMgb2NjdXIsIGxlYXZpbmdcbiAgICAgKiBkZXZlbG9wZXJzIHRvIGxvb2sgdGhyb3VnaCBjbG91ZCBsb2dzLiBJbiBnZW5lcmFsIGZhYXN0LmpzJyB0aW1lb3V0IHdpbGxcbiAgICAgKiBiZSB1cCB0byA1cyBlYXJsaWVyIHRoYW4gdGhlIHRpbWVvdXQgc3BlY2lmaWVkLCBpbiBvcmRlciB0byBnaXZlIHRpbWUgdG9cbiAgICAgKiBhbGxvdyBmYWFzdC5qcyB0byBzZW5kIGEgdGltZW91dCBtZXNzYWdlLiBQcm9hY3RpdmUgdGltZW91dCBkZXRlY3Rpb25cbiAgICAgKiBvbmx5IHdvcmtzIHdpdGgge0BsaW5rIENvbW1vbk9wdGlvbnMuY2hpbGRQcm9jZXNzfSBzZXQgdG8gYHRydWVgICh0aGVcbiAgICAgKiBkZWZhdWx0KS5cbiAgICAgKi9cbiAgICB0aW1lb3V0PzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIEV4dHJhIHdlYnBhY2sgb3B0aW9ucyB0byB1c2UgdG8gYnVuZGxlIHRoZSBjb2RlIHBhY2thZ2UuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBCeSBkZWZhdWx0LCBmYWFzdC5qcyB1c2VzIHdlYnBhY2sgdG8gYnVuZGxlIHRoZSBjb2RlIHBhY2thZ2UuIFdlYnBhY2tcbiAgICAgKiBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgZmluZGluZyBhbmQgYnVuZGxpbmcgZGVwZW5kZW5jaWVzLCBhZGRpbmcgc291cmNlXG4gICAgICogbWFwcGluZ3MsIGV0Yy4gSWYgeW91IG5lZWQgc3BlY2lhbGl6ZWQgYnVuZGxpbmcsIHVzZSB0aGlzIG9wdGlvbiB0byBhZGRcbiAgICAgKiBvciBvdmVycmlkZSB0aGUgZGVmYXVsdCB3ZWJwYWNrIGNvbmZpZ3VyYXRpb24uIFRoZSBsaWJyYXJ5XG4gICAgICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9zdXJ2aXZlanMvd2VicGFjay1tZXJnZSB8IHdlYnBhY2stbWVyZ2V9IGlzXG4gICAgICogdXNlZCB0byBjb21iaW5lIGNvbmZpZ3VyYXRpb25zLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGNvbmZpZzogd2VicGFjay5Db25maWd1cmF0aW9uID0gbWVyZ2Uoe1xuICAgICAqICAgICBlbnRyeSxcbiAgICAgKiAgICAgbW9kZTogXCJkZXZlbG9wbWVudFwiLFxuICAgICAqICAgICBvdXRwdXQ6IHtcbiAgICAgKiAgICAgICAgIHBhdGg6IFwiL1wiLFxuICAgICAqICAgICAgICAgZmlsZW5hbWU6IG91dHB1dEZpbGVuYW1lLFxuICAgICAqICAgICAgICAgbGlicmFyeVRhcmdldDogXCJjb21tb25qczJcIlxuICAgICAqICAgICB9LFxuICAgICAqICAgICB0YXJnZXQ6IFwibm9kZVwiLFxuICAgICAqICAgICByZXNvbHZlTG9hZGVyOiB7IG1vZHVsZXM6IFtfX2Rpcm5hbWUsIGAke19fZGlybmFtZX0vZGlzdGBdIH0sXG4gICAgICogICAgIG5vZGU6IHsgZ2xvYmFsOiB0cnVlLCBfX2Rpcm5hbWU6IGZhbHNlLCBfX2ZpbGVuYW1lOiBmYWxzZSB9XG4gICAgICogICB9LFxuICAgICAqICAgd2VicGFja09wdGlvbnMpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGFrZSBjYXJlIHdoZW4gc2V0dGluZyB0aGUgdmFsdWVzIG9mIGBlbnRyeWAsIGBvdXRwdXRgLCBvclxuICAgICAqIGByZXNvbHZlTG9hZGVyYC4gSWYgdGhlc2Ugb3B0aW9ucyBhcmUgb3ZlcndyaXR0ZW4sIGZhYXN0LmpzIG1heSBmYWlsIHRvXG4gICAgICogYnVuZGxlIHlvdXIgY29kZS4gSW4gcGFydGljdWxhciwgc2V0dGluZyBgZW50cnlgIHRvIGFuIGFycmF5IHZhbHVlIHdpbGxcbiAgICAgKiBoZWxwIGB3ZWJwYWNrLW1lcmdlYCB0byBjb25jYXRlbmF0ZSBpdHMgdmFsdWUgaW5zdGVhZCBvZiByZXBsYWNpbmcgdGhlXG4gICAgICogdmFsdWUgdGhhdCBmYWFzdC5qcyBpbnNlcnRzIGZvciB5b3UuXG4gICAgICpcbiAgICAgKiBEZWZhdWx0OlxuICAgICAqXG4gICAgICogLSBhd3M6IGB7IGV4dGVybmFsczogW25ldyBSZWdFeHAoXCJeYXdzLXNkay8/XCIpXSB9YC4gSW4gdGhlIGxhbWJkYVxuICAgICAqICAgZW52aXJvbm1lbnQgYFwiYXdzLXNka1wiYCBpcyBhdmFpbGFibGUgaW4gdGhlIGFtYmllbnQgZW52aXJvbm1lbnQgYW5kXG4gICAgICogICBkb2VzIG5vdCBuZWVkIHRvIGJlIGJ1bmRsZWQuXG4gICAgICpcbiAgICAgKiAtIG90aGVyIHByb3ZpZGVyczogYHt9YFxuICAgICAqXG4gICAgICogVGhlIGBGQUFTVF9QQUNLQUdFX0RJUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgY2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nXG4gICAgICogd2VicGFjayBpc3N1ZXMuXG4gICAgICovXG4gICAgd2VicGFja09wdGlvbnM/OiB3ZWJwYWNrLkNvbmZpZ3VyYXRpb247XG4gICAgLyoqXG4gICAgICogQ2hlY2sgYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIGZyb20gY2xvdWQgZnVuY3Rpb25zIGFyZSBzZXJpYWxpemFibGVcbiAgICAgKiB3aXRob3V0IGxvc2luZyBpbmZvcm1hdGlvbi4gRGVmYXVsdDogdHJ1ZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEFyZ3VtZW50cyB0byBjbG91ZCBmdW5jdGlvbnMgYXJlIGF1dG9tYXRpY2FsbHkgc2VyaWFsaXplZCB3aXRoXG4gICAgICogYEpTT04uc3RyaW5naWZ5YCB3aXRoIGEgY3VzdG9tIHJlcGxhY2VyIHRoYXQgaGFuZGxlcyBidWlsdC1pbiBKYXZhU2NyaXB0XG4gICAgICogdHlwZXMgc3VjaCBhcyBgRGF0ZWAgYW5kIGBCdWZmZXJgLiBSZXR1cm4gdmFsdWVzIGdvIHRocm91Z2ggdGhlIHNhbWVcbiAgICAgKiBwcm9jZXNzLiBTb21lIEphdmFTY3JpcHQgb2JqZWN0cyBjYW5ub3QgYmUgc2VyaWFsaXplZC4gQnkgZGVmYXVsdFxuICAgICAqIGB2YWxpZGF0ZVNlcmlhbGl6YXRpb25gIHdpbGwgdmVyaWZ5IHRoYXQgZXZlcnkgYXJndW1lbnQgYW5kIHJldHVybiB2YWx1ZVxuICAgICAqIGNhbiBiZSBzZXJpYWxpemVkIGFuZCBkZXNlcmlhbGl6ZWQgd2l0aG91dCBsb3NpbmcgaW5mb3JtYXRpb24uIEFcbiAgICAgKiBgRmFhc3RFcnJvcmAgd2lsbCBiZSB0aHJvd24gaWYgZmFhc3QuanMgZGV0ZWN0cyBhIHByb2JsZW0gYWNjb3JkaW5nIHRvXG4gICAgICogdGhlIGZvbGxvd2luZyBwcm9jZWR1cmU6XG4gICAgICpcbiAgICAgKiAxLiBTZXJpYWxpemUgYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIHdpdGggYEpTT04uc3RyaW5naWZ5YCB1c2luZyBhXG4gICAgICogICAgc3BlY2lhbCBgcmVwbGFjZXJgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogMi4gRGVzZXJpYWxpemUgdGhlIHZhbHVlcyB3aXRoIGBKU09OLnBhcnNlYCB3aXRoIGEgc3BlY2lhbCBgcmV2aXZlcmBcbiAgICAgKiAgICBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIDMuIFVzZVxuICAgICAqICAgIHtAbGluayBodHRwczovL25vZGVqcy5vcmcvYXBpL2Fzc2VydC5odG1sI2Fzc2VydF9hc3NlcnRfZGVlcHN0cmljdGVxdWFsX2FjdHVhbF9leHBlY3RlZF9tZXNzYWdlIHwgYXNzZXJ0LmRlZXBTdHJpbmdFcXVhbH1cbiAgICAgKiAgICB0byBjb21wYXJlIHRoZSBvcmlnaW5hbCBvYmplY3Qgd2l0aCB0aGUgZGVzZXJpYWxpemVkIG9iamVjdCBmcm9tIHN0ZXBcbiAgICAgKiAgICAyLlxuICAgICAqXG4gICAgICogVGhlcmUgaXMgc29tZSBvdmVyaGVhZCB0byB0aGlzIHByb2Nlc3MgYmVjYXVzZSBlYWNoIGFyZ3VtZW50IGlzXG4gICAgICogc2VyaWFsaXplZCBhbmQgZGVzZXJpYWxpemVkLCB3aGljaCBjYW4gYmUgY29zdGx5IGlmIGFyZ3VtZW50cyBvciByZXR1cm5cbiAgICAgKiB2YWx1ZXMgYXJlIGxhcmdlLlxuICAgICAqL1xuICAgIHZhbGlkYXRlU2VyaWFsaXphdGlvbj86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogRGVidWdnaW5nIG91dHB1dCBvcHRpb25zLlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGRlYnVnT3B0aW9ucz86IHsgW2tleTogc3RyaW5nXTogYm9vbGVhbiB9O1xufVxuXG5leHBvcnQgY29uc3QgY29tbW9uRGVmYXVsdHM6IFJlcXVpcmVkPENvbW1vbk9wdGlvbnM+ID0ge1xuICAgIGNoaWxkUHJvY2VzczogdHJ1ZSxcbiAgICBjaGlsZFByb2Nlc3NNZW1vcnlNYjogMCxcbiAgICBjb25jdXJyZW5jeTogMTAwLFxuICAgIGRlc2NyaXB0aW9uOiBcIlwiLFxuICAgIGV4Y2x1ZGU6IFtdLFxuICAgIGluY2x1ZGU6IFtdLFxuICAgIHJhdGU6IDAsXG4gICAgZW52OiB7fSxcbiAgICBnYzogXCJhdXRvXCIsXG4gICAgbWF4UmV0cmllczogMixcbiAgICBtZW1vcnlTaXplOiAxMDI0LFxuICAgIG1vZGU6IFwiYXV0b1wiLFxuICAgIHBhY2thZ2VKc29uOiBcIlwiLFxuICAgIHVzZURlcGVuZGVuY3lDYWNoaW5nOiB0cnVlLFxuICAgIHJldGVudGlvbkluRGF5czogMSxcbiAgICBzcGVjdWxhdGl2ZVJldHJ5VGhyZXNob2xkOiAzLFxuICAgIHRpbWVvdXQ6IDYwLFxuICAgIHdlYnBhY2tPcHRpb25zOiB7fSxcbiAgICB2YWxpZGF0ZVNlcmlhbGl6YXRpb246IHRydWUsXG4gICAgZGVidWdPcHRpb25zOiB7fVxufTtcblxuLyoqXG4gKiBPcHRpb25zIHRoYXQgYXBwbHkgdG8gdGhlIHtAbGluayBGYWFzdE1vZHVsZS5jbGVhbnVwfSBtZXRob2QuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2xlYW51cE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIElmIHRydWUsIGRlbGV0ZSBwcm92aWRlciBjbG91ZCByZXNvdXJjZXMuIERlZmF1bHQ6IHRydWUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGUgY2xlYW51cCBvcGVyYXRpb24gaGFzIHR3byBmdW5jdGlvbnM6IHN0b3BwaW5nIHRoZSBmYWFzdC5qcyBydW50aW1lXG4gICAgICogYW5kIGRlbGV0aW5nIGNsb3VkIHJlc291cmNlcyB0aGF0IHdlcmUgaW5zdGFudGlhdGVkLiBJZiBgZGVsZXRlUmVzb3VyY2VzYFxuICAgICAqIGlzIGZhbHNlLCB0aGVuIG9ubHkgdGhlIHJ1bnRpbWUgaXMgc3RvcHBlZCBhbmQgbm8gY2xvdWQgcmVzb3VyY2VzIGFyZVxuICAgICAqIGRlbGV0ZWQuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nIGFuZCBleGFtaW5pbmcgdGhlIHN0YXRlIG9mXG4gICAgICogcmVzb3VyY2VzIGNyZWF0ZWQgYnkgZmFhc3QuanMuXG4gICAgICpcbiAgICAgKiBJdCBpcyBzdXBwb3J0ZWQgdG8gY2FsbCB7QGxpbmsgRmFhc3RNb2R1bGUuY2xlYW51cH0gdHdpY2U6IG9uY2Ugd2l0aFxuICAgICAqIGBkZWxldGVSZXNvdXJjZXNgIHNldCB0byBgZmFsc2VgLCB3aGljaCBvbmx5IHN0b3BzIHRoZSBydW50aW1lLCBhbmQgdGhlblxuICAgICAqIGFnYWluIHNldCB0byBgdHJ1ZWAgdG8gZGVsZXRlIHJlc291cmNlcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciB0ZXN0aW5nLlxuICAgICAqL1xuICAgIGRlbGV0ZVJlc291cmNlcz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCBkZWxldGUgY2FjaGVkIHJlc291cmNlcy4gRGVmYXVsdDogZmFsc2UuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBTb21lIHJlc291cmNlcyBhcmUgY2FjaGVkIHBlcnNpc3RlbnRseSBiZXR3ZWVuIGNhbGxzIGZvciBwZXJmb3JtYW5jZVxuICAgICAqIHJlYXNvbnMuIElmIHRoaXMgb3B0aW9uIGlzIHNldCB0byB0cnVlLCB0aGVzZSBjYWNoZWQgcmVzb3VyY2VzIGFyZVxuICAgICAqIGRlbGV0ZWQgd2hlbiBjbGVhbnVwIG9jY3VycywgaW5zdGVhZCBvZiBiZWluZyBsZWZ0IGJlaGluZCBmb3IgZnV0dXJlIHVzZS5cbiAgICAgKiBGb3IgZXhhbXBsZSwgb24gQVdTIHRoaXMgaW5jbHVkZXMgdGhlIExhbWJkYSBMYXllcnMgdGhhdCBhcmUgY3JlYXRlZCBmb3JcbiAgICAgKiB7QGxpbmsgQ29tbW9uT3B0aW9ucy5wYWNrYWdlSnNvbn0gZGVwZW5kZW5jaWVzLiBOb3RlIHRoYXQgb25seSB0aGUgY2FjaGVkXG4gICAgICogcmVzb3VyY2VzIGNyZWF0ZWQgYnkgdGhpcyBpbnN0YW5jZSBvZiBGYWFzdE1vZHVsZSBhcmUgZGVsZXRlZCwgbm90IGNhY2hlZFxuICAgICAqIHJlc291cmNlcyBmcm9tIG90aGVyIEZhYXN0TW9kdWxlcy4gVGhpcyBpcyBzaW1pbGFyIHRvIHNldHRpbmdcbiAgICAgKiBgdXNlQ2FjaGVkRGVwZW5kZW5jaWVzYCB0byBgZmFsc2VgIGR1cmluZyBmdW5jdGlvbiBjb25zdHJ1Y3Rpb24sIGV4Y2VwdFxuICAgICAqIGBkZWxldGVDYWNoZXNgIGNhbiBiZSBzZXQgYXQgZnVuY3Rpb24gY2xlYW51cCB0aW1lLCBhbmQgYW55IG90aGVyXG4gICAgICogRmFhc3RNb2R1bGVzIGNyZWF0ZWQgYmVmb3JlIGNsZWFudXAgbWF5IHVzZSB0aGUgY2FjaGVkIExheWVycy5cbiAgICAgKi9cbiAgICBkZWxldGVDYWNoZXM/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIHNlY29uZHMgdG8gd2FpdCBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLiBEZWZhdWx0OiAxMC5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEdhcmJhZ2UgY29sbGVjdGlvbiBjYW4gc3RpbGwgYmUgb3BlcmF0aW5nIHdoZW4gY2xlYW51cCBpcyBjYWxsZWQ7IHRoaXNcbiAgICAgKiBvcHRpb24gbGltaXRzIHRoZSBhbW91bnQgb2YgdGltZSBmYWFzdCB3YWl0cyBmb3IgdGhlIGdhcmJhZ2UgY29sbGVjdG9yLlxuICAgICAqIElmIHNldCB0byAwLCB0aGUgd2FpdCBpcyB1bmxpbWl0ZWQuXG4gICAgICovXG4gICAgZ2NUaW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgQ2xlYW51cE9wdGlvbkRlZmF1bHRzOiBSZXF1aXJlZDxDbGVhbnVwT3B0aW9ucz4gPSB7XG4gICAgZGVsZXRlUmVzb3VyY2VzOiB0cnVlLFxuICAgIGRlbGV0ZUNhY2hlczogZmFsc2UsXG4gICAgZ2NUaW1lb3V0OiAxMFxufTtcblxuLyoqXG4gKiBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGZ1bmN0aW9uIGludm9jYXRpb25zLlxuICogQHJlbWFya3NcbiAqIGBgYFxuICogICAgICAgICAgICAgICBsb2NhbFN0YXJ0TGF0ZW5jeSAgICAgIHJlbW90ZVN0YXJ0TGF0ZW5jeSAgICAgIGV4ZWN1dGlvblRpbWVcbiAqICAgICAgICAgICAgIOKXgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKWtuKXgSDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pa34peA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pa2XG4gKlxuICog4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSs4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQXG4gKiDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICBMb2NhbCAgICAgICAgICAgICAgIOKUgiAgICAgICAgICAgIENsb3VkIFByb3ZpZGVyICAgICAgICAgICAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAgICDilIIgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICDilIIgICAg4pSCICAg4pSCICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgIGxvY2FsICDilIIgICAg4pSCICAg4pSCIHJlcXVlc3QgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgaW52b2tlICDilIDilIDilIDilIDilIDilIDilIDilIDilrbilIIgIHF1ZXVlICDilILilIDilIDilIDilIDilLzilIDilIDilrbilIIgIHF1ZXVlICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pa24pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICDilIIgICDilIIgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCAgICDilIIgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggICAgICAgICDilIIgIGNsb3VkICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAg4pSCIGZ1bmN0aW9uIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAgICDilIIgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgIOKUgiAgIOKUgiAgICAgICAgICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgIHJlc3VsdCAg4peA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSCICBsb2NhbCAg4pSC4peA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSCIHJlc3BvbnNlIOKUguKXgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgcG9sbGluZyDilIIgICAg4pSCICAg4pSCICBxdWV1ZSAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICDilIIgICAg4pSCICAg4pSCICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggICAg4pSCICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAqIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuICpcbiAqICAgICAgICAgICAgIOKXgSDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKWt1xuICogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuTGF0ZW5jeSAgICAgICAgICAgICAgICAgIOKXgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKWtlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRSZXNwb25zZUxhdGVuY3lcbiAqIGBgYFxuICpcbiAqIGBsb2NhbFN0YXJ0TGF0ZW5jeWAgYW5kIGBleGVjdXRpb25UaW1lYCBhcmUgbWVhc3VyZWQgb24gb25lIG1hY2hpbmUgYW5kIGFyZVxuICogZnJlZSBvZiBjbG9jayBza2V3LiBgcmVtb3RlU3RhcnRMYXRlbmN5YCBhbmQgYHJldHVybkxhdGVuY3lgIGFyZSBtZWFzdXJlZCBhc1xuICogdGltZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1hY2hpbmVzIGFuZCBhcmUgc3ViamVjdCB0byBtdWNoIG1vcmUgdW5jZXJ0YWludHksXG4gKiBhbmQgZWZmZWN0cyBsaWtlIGNsb2NrIHNrZXcuXG4gKlxuICogQWxsIHRpbWVzIGFyZSBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25TdGF0cyB7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgaG93IGxvbmcgaW52b2NhdGlvbnMgc3RheSBpbiB0aGUgbG9jYWwgcXVldWUgYmVmb3JlIGJlaW5nXG4gICAgICogc2VudCB0byB0aGUgY2xvdWQgcHJvdmlkZXIuXG4gICAgICovXG4gICAgbG9jYWxTdGFydExhdGVuY3kgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGhvdyBsb25nIHJlcXVlc3RzIHRha2UgdG8gc3RhcnQgZXhlY3V0aW9uIGFmdGVyIGJlaW5nIHNlbnRcbiAgICAgKiB0byB0aGUgY2xvdWQgcHJvdmlkZXIuIFRoaXMgdHlwaWNhbGx5IGluY2x1ZGVzIHJlbW90ZSBxdWV1ZWluZyBhbmQgY29sZFxuICAgICAqIHN0YXJ0IHRpbWVzLiBCZWNhdXNlIHRoaXMgbWVhc3VyZW1lbnQgcmVxdWlyZXMgY29tcGFyaW5nIHRpbWVzdGFtcHMgZnJvbVxuICAgICAqIGRpZmZlcmVudCBtYWNoaW5lcywgaXQgaXMgc3ViamVjdCB0byBjbG9jayBza2V3IGFuZCBvdGhlciBlZmZlY3RzLCBhbmRcbiAgICAgKiBzaG91bGQgbm90IGJlIGNvbnNpZGVyZWQgaGlnaGx5IGFjY3VyYXRlLiBJdCBjYW4gYmUgdXNlZnVsIGZvciBkZXRlY3RpbmdcbiAgICAgKiBleGNlc3NpdmVseSBoaWdoIGxhdGVuY3kgcHJvYmxlbXMuIEZhYXN0LmpzIGF0dGVtcHQgdG8gY29ycmVjdCBmb3IgY2xvY2tcbiAgICAgKiBza2V3IGhldXJpc3RpY2FsbHkuXG4gICAgICovXG4gICAgcmVtb3RlU3RhcnRMYXRlbmN5ID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBmdW5jdGlvbiBleGVjdXRpb24gdGltZSBpbiBtaWxsaXNlY29uZHMuICBUaGlzIGlzIG1lYXN1cmVkXG4gICAgICogYXMgd2FsbCBjbG9jayB0aW1lIGluc2lkZSB0aGUgY2xvdWQgZnVuY3Rpb24sIGFuZCBkb2VzIG5vdCBpbmNsdWRlIHRoZVxuICAgICAqIHRpbWUgdGFrZW4gdG8gc2VuZCB0aGUgcmVzcG9uc2UgdG8gdGhlIHJlc3BvbnNlIHF1ZXVlLiBOb3RlIHRoYXQgbW9zdFxuICAgICAqIGNsb3VkIHByb3ZpZGVycyByb3VuZCB1cCB0byB0aGUgbmV4dCAxMDBtcyBmb3IgcHJpY2luZy5cbiAgICAgKi9cbiAgICBleGVjdXRpb25UaW1lID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBob3cgbG9uZyBpdCB0YWtlcyB0byBzZW5kIHRoZSByZXNwb25zZSB0byB0aGUgcmVzcG9uc2VcbiAgICAgKiBxdWV1ZS5cbiAgICAgKi9cbiAgICBzZW5kUmVzcG9uc2VMYXRlbmN5ID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBob3cgbG9uZyBpdCB0YWtlcyB0byByZXR1cm4gYSByZXNwb25zZSBmcm9tIHRoZSBlbmQgb2ZcbiAgICAgKiBleGVjdXRpb24gdGltZSB0byB0aGUgcmVjZWlwdCBvZiB0aGUgcmVzcG9uc2UgbG9jYWxseS4gVGhpcyBtZWFzdXJlbWVudFxuICAgICAqIHJlcXVpcmVzIGNvbXBhcmluZyB0aW1lc3RhbXBzIGZyb20gZGlmZmVyZW50IG1hY2hpbmVzLCBhbmQgaXMgc3ViamVjdCB0b1xuICAgICAqIGNsb2NrIHNrZXcgYW5kIG90aGVyIGVmZmVjdHMuIEl0IHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCBoaWdobHlcbiAgICAgKiBhY2N1cmF0ZS4gSXQgY2FuIGJlIHVzZWZ1bCBmb3IgZGV0ZWN0aW5nIGV4Y2Vzc2l2ZWx5IGhpZ2ggbGF0ZW5jeVxuICAgICAqIHByb2JsZW1zLiBGYWFzdC5qcyBhdHRlbXB0cyB0byBjb3JyZWN0IGZvciBjbG9jayBza2V3IGhldXJpc3RpY2FsbHkuXG4gICAgICovXG4gICAgcmV0dXJuTGF0ZW5jeSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgYW1vdW50IG9mIHRpbWUgYmlsbGVkLiBUaGlzIGlzIHNpbWlsYXIgdG9cbiAgICAgKiB7QGxpbmsgRnVuY3Rpb25TdGF0cy5leGVjdXRpb25UaW1lfSBleGNlcHQgZWFjaCBzYW1wbGVkIHRpbWUgaXMgcm91bmRlZFxuICAgICAqIHVwIHRvIHRoZSBuZXh0IDEwMG1zLlxuICAgICAqL1xuICAgIGVzdGltYXRlZEJpbGxlZFRpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW52b2NhdGlvbnMgYXR0ZW1wdGVkLiBJZiBhbiBpbnZvY2F0aW9uIGlzIHJldHJpZWQsIHRoaXNcbiAgICAgKiBvbmx5IGNvdW50cyB0aGUgaW52b2NhdGlvbiBvbmNlLlxuICAgICAqL1xuICAgIGludm9jYXRpb25zID0gMDtcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGludm9jYXRpb25zIHRoYXQgd2VyZSBzdWNjZXNzZnVsbHkgY29tcGxldGVkLlxuICAgICAqL1xuICAgIGNvbXBsZXRlZCA9IDA7XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpbnZvY2F0aW9uIHJldHJpZXMgYXR0ZW1wdGVkLiBUaGlzIGNvdW50cyByZXRyaWVzXG4gICAgICogYXR0ZW1wdGVkIGJ5IGZhYXN0LmpzIHRvIHJlY292ZXIgZnJvbSB0cmFuc2llbnQgZXJyb3JzLCBidXQgZG9lcyBub3RcbiAgICAgKiBjb3VudCByZXRyaWVzIGJ5IHRoZSBjbG91ZCBwcm92aWRlci5cbiAgICAgKi9cbiAgICByZXRyaWVzID0gMDtcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGludm9jYXRpb25zIHRoYXQgcmVzdWx0ZWQgaW4gYW4gZXJyb3IuIElmIGFuIGludm9jYXRpb24gaXNcbiAgICAgKiByZXRyaWVkLCBhbiBlcnJvciBpcyBvbmx5IGNvdW50ZWQgb25jZSwgbm8gbWF0dGVyIGhvdyBtYW55IHJldHJpZXMgd2VyZVxuICAgICAqIGF0dGVtcHRlZC5cbiAgICAgKi9cbiAgICBlcnJvcnMgPSAwO1xuICAgIC8qKlxuICAgICAqIFN1bW1hcml6ZSB0aGUgZnVuY3Rpb24gc3RhdHMgYXMgYSBzdHJpbmcuXG4gICAgICogQHJldHVybnMgYSBzdHJpbmcgc2hvd2luZyB0aGUgdmFsdWUgb2YgY29tcGxldGVkLCByZXRyaWVzLCBlcnJvcnMsIGFuZFxuICAgICAqIG1lYW4gZXhlY3V0aW9uIHRpbWUuIFRoaXMgc3RyaW5nIGV4Y2x1ZGVzIGludm9jYXRpb25zIGJ5IGRlZmF1bHQgYmVjYXVzZVxuICAgICAqIGl0IGlzIG9mdGVuIGZpeGVkLlxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYGNvbXBsZXRlZDogJHt0aGlzLmNvbXBsZXRlZH0sIHJldHJpZXM6ICR7dGhpcy5yZXRyaWVzfSwgZXJyb3JzOiAke3RoaXMuZXJyb3JzfSwgZXhlY3V0aW9uVGltZS5tZWFuOiAke3RoaXMuZXhlY3V0aW9uVGltZS5tZWFufW1zYDtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIGNsb25lKCk6IEZ1bmN0aW9uU3RhdHMge1xuICAgICAgICBjb25zdCBydiA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmNyZWF0ZShPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpLCB0aGlzKTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Yga2V5c09mKHJ2KSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBydltrZXldICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgcnZba2V5XSA9IHJ2W2tleV0uY2xvbmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcnY7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25FeGVjdXRpb25NZXRyaWNzIHtcbiAgICBzZWNvbmRNZXRyaWNzOiBTdGF0aXN0aWNzW10gPSBbXTtcbn1cblxuZXhwb3J0IHR5cGUgQ2FsbElkID0gc3RyaW5nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlc3BvbnNlQ29udGV4dCB7XG4gICAgdHlwZTogXCJmdWxmaWxsXCIgfCBcInJlamVjdFwiO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgY2FsbElkOiBDYWxsSWQ7XG4gICAgaXNFcnJvck9iamVjdD86IGJvb2xlYW47XG4gICAgcmVtb3RlRXhlY3V0aW9uU3RhcnRUaW1lPzogbnVtYmVyO1xuICAgIHJlbW90ZUV4ZWN1dGlvbkVuZFRpbWU/OiBudW1iZXI7XG4gICAgbG9nVXJsPzogc3RyaW5nO1xuICAgIGluc3RhbmNlSWQ/OiBzdHJpbmc7XG4gICAgZXhlY3V0aW9uSWQ/OiBzdHJpbmc7XG4gICAgbWVtb3J5VXNhZ2U/OiBOb2RlSlMuTWVtb3J5VXNhZ2U7XG4gICAgdGltZXN0YW1wPzogbnVtYmVyOyAvLyB0aW1lc3RhbXAgd2hlbiByZXNwb25zZSBtZXNzYWdlIHdhcyBzZW50IGFjY29yZGluZyB0byBjbG91ZCBzZXJ2aWNlLCB0aGlzIGlzIG9wdGlvbmFsIGFuZCB1c2VkIHRvIHByb3ZpZGUgbW9yZSBhY2N1cmF0ZSBtZXRyaWNzLlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb21pc2VSZXNwb25zZU1lc3NhZ2UgZXh0ZW5kcyBSZXNwb25zZUNvbnRleHQge1xuICAgIGtpbmQ6IFwicHJvbWlzZVwiO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEl0ZXJhdG9yUmVzcG9uc2VNZXNzYWdlIGV4dGVuZHMgUmVzcG9uc2VDb250ZXh0IHtcbiAgICBraW5kOiBcIml0ZXJhdG9yXCI7XG4gICAgc2VxdWVuY2U6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGdW5jdGlvblN0YXJ0ZWRNZXNzYWdlIHtcbiAgICBraW5kOiBcImZ1bmN0aW9uc3RhcnRlZFwiO1xuICAgIGNhbGxJZDogQ2FsbElkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENwdU1ldHJpY3NNZXNzYWdlIHtcbiAgICBraW