projen
Version:
CDK for software projects
231 lines • 23.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectFile = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const file_1 = require("./file");
const json_patch_1 = require("./json-patch");
const util_1 = require("./util");
/**
* Represents an Object file.
*/
class ObjectFile extends file_1.FileBase {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.ObjectFile", version: "0.103.12" };
/**
* The output object. This object can be mutated until the project is
* synthesized.
*/
obj;
/**
* An object to be merged on top of `obj` after the resolver is called
*/
rawOverrides;
/**
* Indicates if empty objects and arrays are omitted from the output object.
*/
omitEmpty;
/**
* patches to be applied to `obj` after the resolver is called
*/
patchOperations;
constructor(scope, filePath, options) {
super(scope, filePath, options);
this.obj = options.obj ?? {};
this.omitEmpty = options.omitEmpty ?? false;
this.rawOverrides = {};
this.patchOperations = [];
}
/**
* Adds an override to the synthesized object file.
*
* If the override is nested, separate each nested level using a dot (.) in the path parameter.
* If there is an array as part of the nesting, specify the index in the path.
*
* To include a literal `.` in the property name, prefix with a `\`. In most
* programming languages you will need to write this as `"\\."` because the
* `\` itself will need to be escaped.
*
* For example,
* ```typescript
* project.tsconfig.file.addOverride('compilerOptions.alwaysStrict', true);
* project.tsconfig.file.addOverride('compilerOptions.lib', ['dom', 'dom.iterable', 'esnext']);
* ```
* would add the overrides
* ```json
* "compilerOptions": {
* "alwaysStrict": true,
* "lib": [
* "dom",
* "dom.iterable",
* "esnext"
* ]
* ...
* }
* ...
* ```
*
* @param path - The path of the property, you can use dot notation to
* override values in complex types. Any intermediate keys
* will be created as needed.
* @param value - The value. Could be primitive or complex.
*/
addOverride(path, value) {
const parts = splitOnPeriods(path);
let curr = this.rawOverrides;
while (parts.length > 1) {
const key = parts.shift();
// if we can't recurse further or the previous value is not an
// object overwrite it with an object.
const isObject = curr[key] != null &&
typeof curr[key] === "object" &&
!Array.isArray(curr[key]);
if (!isObject) {
curr[key] = {};
}
curr = curr[key];
}
const lastKey = parts.shift();
curr[lastKey] = value;
}
/**
* Adds to an array in the synthesized object file.
*
* If the array is nested, separate each nested level using a dot (.) in the path parameter.
* If there is an array as part of the nesting, specify the index in the path.
*
* To include a literal `.` in the property name, prefix with a `\`. In most
* programming languages you will need to write this as `"\\."` because the
* `\` itself will need to be escaped.
*
* For example, with the following object file
* ```json
* "compilerOptions": {
* "exclude": ["node_modules"],
* "lib": ["es2020"]
* ...
* }
* ...
* ```
*
* ```typescript
* project.tsconfig.file.addToArray('compilerOptions.exclude', 'coverage');
* project.tsconfig.file.addToArray('compilerOptions.lib', 'dom', 'dom.iterable', 'esnext');
* ```
* would result in the following object file
* ```json
* "compilerOptions": {
* "exclude": ["node_modules", "coverage"],
* "lib": ["es2020", "dom", "dom.iterable", "esnext"]
* ...
* }
* ...
* ```
*
* @param path - The path of the property, you can use dot notation to
* att to arrays in complex types. Any intermediate keys
* will be created as needed.
* @param values - The values to add. Could be primitive or complex.
*/
addToArray(path, ...values) {
const parts = splitOnPeriods(path);
let curr = this.rawOverrides;
while (parts.length > 1) {
const key = parts.shift();
// if we can't recurse further or the previous value is not an
// object overwrite it with an object.
const isObject = curr[key] != null &&
typeof curr[key] === "object" &&
!Array.isArray(curr[key]);
if (!isObject) {
curr[key] = {};
}
curr = curr[key];
}
const lastKey = parts.shift();
if (Array.isArray(curr[lastKey])) {
curr[lastKey].push(...values);
}
else {
curr[lastKey] = {
__$APPEND: [...(curr[lastKey]?.__$APPEND ?? []), ...values],
};
}
}
/**
* Applies an RFC 6902 JSON-patch to the synthesized object file.
* See https://datatracker.ietf.org/doc/html/rfc6902 for more information.
*
* For example, with the following object file
* ```json
* "compilerOptions": {
* "exclude": ["node_modules"],
* "lib": ["es2020"]
* ...
* }
* ...
* ```
*
* ```typescript
* project.tsconfig.file.patch(JsonPatch.add("/compilerOptions/exclude/-", "coverage"));
* project.tsconfig.file.patch(JsonPatch.replace("/compilerOptions/lib", ["dom", "dom.iterable", "esnext"]));
* ```
* would result in the following object file
* ```json
* "compilerOptions": {
* "exclude": ["node_modules", "coverage"],
* "lib": ["dom", "dom.iterable", "esnext"]
* ...
* }
* ...
* ```
*
* @param patches - The patch operations to apply
*/
patch(...patches) {
this.patchOperations.push(patches);
}
/**
* Syntactic sugar for `addOverride(path, undefined)`.
* @param path The path of the value to delete
*/
addDeletionOverride(path) {
this.addOverride(path, undefined);
}
synthesizeContent(resolver) {
const obj = this.obj;
const resolved = resolver.resolve(obj, {
omitEmpty: this.omitEmpty,
}) ?? undefined;
if (resolved) {
(0, util_1.deepMerge)([resolved, this.rawOverrides], { destructive: true });
}
let patched = resolved;
for (const operation of this.patchOperations) {
patched = json_patch_1.JsonPatch.apply(patched, ...operation);
}
return patched ? JSON.stringify(patched, undefined, 2) : undefined;
}
}
exports.ObjectFile = ObjectFile;
/**
* Split on periods while processing escape characters \
*/
function splitOnPeriods(x) {
// Build this list in reverse because it's more convenient to get the "current"
// item by doing ret[0] than by ret[ret.length - 1].
const ret = [""];
for (let i = 0; i < x.length; i++) {
if (x[i] === "\\" && i + 1 < x.length) {
ret[0] += x[i + 1];
i++;
}
else if (x[i] === ".") {
ret.unshift("");
}
else {
ret[0] += x[i];
}
}
ret.reverse();
return ret;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LWZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvb2JqZWN0LWZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUVBLGlDQUFrQztBQUNsQyw2Q0FBeUM7QUFDekMsaUNBQW1DO0FBMkJuQzs7R0FFRztBQUNILE1BQXNCLFVBQVcsU0FBUSxlQUFROztJQUMvQzs7O09BR0c7SUFDYyxHQUFHLENBQVM7SUFFN0I7O09BRUc7SUFDYyxZQUFZLENBQVM7SUFFdEM7O09BRUc7SUFDYSxTQUFTLENBQVU7SUFFbkM7O09BRUc7SUFDYyxlQUFlLENBQXFCO0lBRXJELFlBQVksS0FBaUIsRUFBRSxRQUFnQixFQUFFLE9BQTBCO1FBQ3pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRWhDLElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQztRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWlDRztJQUNJLFdBQVcsQ0FBQyxJQUFZLEVBQUUsS0FBVTtRQUN6QyxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLEdBQVEsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUVsQyxPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRyxDQUFDO1lBRTNCLDhEQUE4RDtZQUM5RCxzQ0FBc0M7WUFDdEMsTUFBTSxRQUFRLEdBQ1osSUFBSSxDQUFDLEdB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TyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB0eXBlIHsgRmlsZUJhc2VPcHRpb25zLCBJUmVzb2x2ZXIgfSBmcm9tIFwiLi9maWxlXCI7XG5pbXBvcnQgeyBGaWxlQmFzZSB9IGZyb20gXCIuL2ZpbGVcIjtcbmltcG9ydCB7IEpzb25QYXRjaCB9IGZyb20gXCIuL2pzb24tcGF0Y2hcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCIuL3V0aWxcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBgT2JqZWN0RmlsZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0RmlsZU9wdGlvbnMgZXh0ZW5kcyBGaWxlQmFzZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgc2VyaWFsaXplZC4gWW91IGNhbiBtb2RpZnkgdGhlIG9iamVjdCdzIGNvbnRlbnRzXG4gICAqIGJlZm9yZSBzeW50aGVzaXMuXG4gICAqXG4gICAqIFNlcmlhbGl6YXRpb24gb2YgdGhlIG9iamVjdCBpcyBzaW1pbGFyIHRvIEpTT04uc3RyaW5naWZ5IHdpdGggZmV3IGVuaGFuY2VtZW50czpcbiAgICogLSB2YWx1ZXMgdGhhdCBhcmUgZnVuY3Rpb25zIHdpbGwgYmUgY2FsbGVkIGR1cmluZyBzeW50aGVzaXMgYW5kIHRoZSByZXN1bHQgd2lsbCBiZSBzZXJpYWxpemVkIC0gdGhpcyBhbGxvdyB0byBoYXZlIGxhenkgdmFsdWVzLlxuICAgKiAtIGBTZXRgIHdpbGwgYmUgY29udmVydGVkIHRvIGFycmF5XG4gICAqIC0gYE1hcGAgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYSBwbGFpbiBvYmplY3QgKHsga2V5OiB2YWx1ZSwgLi4uIH19KVxuICAgKiAtIGBSZWdFeHBgIHdpdGhvdXQgZmxhZ3Mgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzb3VyY2VcbiAgICpcbiAgICogIEBkZWZhdWx0IHt9IGFuIGVtcHR5IG9iamVjdCAodXNlIGBmaWxlLm9iamAgdG8gbXV0YXRlKS5cbiAgICovXG4gIHJlYWRvbmx5IG9iaj86IGFueTtcblxuICAvKipcbiAgICogT21pdHMgZW1wdHkgb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgb21pdEVtcHR5PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIE9iamVjdCBmaWxlLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgT2JqZWN0RmlsZSBleHRlbmRzIEZpbGVCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgb2JqZWN0LiBUaGlzIG9iamVjdCBjYW4gYmUgbXV0YXRlZCB1bnRpbCB0aGUgcHJvamVjdCBpc1xuICAgKiBzeW50aGVzaXplZC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb2JqOiBvYmplY3Q7XG5cbiAgLyoqXG4gICAqIEFuIG9iamVjdCB0byBiZSBtZXJnZWQgb24gdG9wIG9mIGBvYmpgIGFmdGVyIHRoZSByZXNvbHZlciBpcyBjYWxsZWRcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcmF3T3ZlcnJpZGVzOiBvYmplY3Q7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiBlbXB0eSBvYmplY3RzIGFuZCBhcnJheXMgYXJlIG9taXR0ZWQgZnJvbSB0aGUgb3V0cHV0IG9iamVjdC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBvbWl0RW1wdHk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIHBhdGNoZXMgdG8gYmUgYXBwbGllZCB0byBgb2JqYCBhZnRlciB0aGUgcmVzb2x2ZXIgaXMgY2FsbGVkXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHBhdGNoT3BlcmF0aW9uczogQXJyYXk8SnNvblBhdGNoW10+O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBmaWxlUGF0aDogc3RyaW5nLCBvcHRpb25zOiBPYmplY3RGaWxlT3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlLCBmaWxlUGF0aCwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLm9iaiA9IG9wdGlvbnMub2JqID8/IHt9O1xuICAgIHRoaXMub21pdEVtcHR5ID0gb3B0aW9ucy5vbWl0RW1wdHkgPz8gZmFsc2U7XG4gICAgdGhpcy5yYXdPdmVycmlkZXMgPSB7fTtcbiAgICB0aGlzLnBhdGNoT3BlcmF0aW9ucyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gb3ZlcnJpZGUgdG8gdGhlIHN5bnRoZXNpemVkIG9iamVjdCBmaWxlLlxuICAgKlxuICAgKiBJZiB0aGUgb3ZlcnJpZGUgaXMgbmVzdGVkLCBzZXBhcmF0ZSBlYWNoIG5lc3RlZCBsZXZlbCB1c2luZyBhIGRvdCAoLikgaW4gdGhlIHBhdGggcGFyYW1ldGVyLlxuICAgKiBJZiB0aGVyZSBpcyBhbiBhcnJheSBhcyBwYXJ0IG9mIHRoZSBuZXN0aW5nLCBzcGVjaWZ5IHRoZSBpbmRleCBpbiB0aGUgcGF0aC5cbiAgICpcbiAgICogVG8gaW5jbHVkZSBhIGxpdGVyYWwgYC5gIGluIHRoZSBwcm9wZXJ0eSBuYW1lLCBwcmVmaXggd2l0aCBhIGBcXGAuIEluIG1vc3RcbiAgICogcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIHlvdSB3aWxsIG5lZWQgdG8gd3JpdGUgdGhpcyBhcyBgXCJcXFxcLlwiYCBiZWNhdXNlIHRoZVxuICAgKiBgXFxgIGl0c2VsZiB3aWxsIG5lZWQgdG8gYmUgZXNjYXBlZC5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogcHJvamVjdC50c2NvbmZpZy5maWxlLmFkZE92ZXJyaWRlKCdjb21waWxlck9wdGlvbnMuYWx3YXlzU3RyaWN0JywgdHJ1ZSk7XG4gICAqIHByb2plY3QudHNjb25maWcuZmlsZS5hZGRPdmVycmlkZSgnY29tcGlsZXJPcHRpb25zLmxpYicsIFsnZG9tJywgJ2RvbS5pdGVyYWJsZScsICdlc25leHQnXSk7XG4gICAqIGBgYFxuICAgKiB3b3VsZCBhZGQgdGhlIG92ZXJyaWRlc1xuICAgKiBgYGBqc29uXG4gICAqIFwiY29tcGlsZXJPcHRpb25zXCI6IHtcbiAgICogICBcImFsd2F5c1N0cmljdFwiOiB0cnVlLFxuICAgKiAgIFwibGliXCI6IFtcbiAgICogICAgIFwiZG9tXCIsXG4gICAqICAgICBcImRvbS5pdGVyYWJsZVwiLFxuICAgKiAgICAgXCJlc25leHRcIlxuICAgKiAgIF1cbiAgICogICAuLi5cbiAgICogfVxuICAgKiAuLi5cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5LCB5b3UgY2FuIHVzZSBkb3Qgbm90YXRpb24gdG9cbiAgICogICAgICAgIG92ZXJyaWRlIHZhbHVlcyBpbiBjb21wbGV4IHR5cGVzLiBBbnkgaW50ZXJtZWRpYXRlIGtleXNcbiAgICogICAgICAgIHdpbGwgYmUgY3JlYXRlZCBhcyBuZWVkZWQuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZS4gQ291bGQgYmUgcHJpbWl0aXZlIG9yIGNvbXBsZXguXG4gICAqL1xuICBwdWJsaWMgYWRkT3ZlcnJpZGUocGF0aDogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgY29uc3QgcGFydHMgPSBzcGxpdE9uUGVyaW9kcyhwYXRoKTtcbiAgICBsZXQgY3VycjogYW55ID0gdGhpcy5yYXdPdmVycmlkZXM7XG5cbiAgICB3aGlsZSAocGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgY29uc3Qga2V5ID0gcGFydHMuc2hpZnQoKSE7XG5cbiAgICAgIC8vIGlmIHdlIGNhbid0IHJlY3Vyc2UgZnVydGhlciBvciB0aGUgcHJldmlvdXMgdmFsdWUgaXMgbm90IGFuXG4gICAgICAvLyBvYmplY3Qgb3ZlcndyaXRlIGl0IHdpdGggYW4gb2JqZWN0LlxuICAgICAgY29uc3QgaXNPYmplY3QgPVxuICAgICAgICBjdXJyW2tleV0gIT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2YgY3VycltrZXldID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KGN1cnJba2V5XSk7XG4gICAgICBpZiAoIWlzT2JqZWN0KSB7XG4gICAgICAgIGN1cnJba2V5XSA9IHt9O1xuICAgICAgfVxuXG4gICAgICBjdXJyID0gY3VycltrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IGxhc3RLZXkgPSBwYXJ0cy5zaGlmdCgpITtcbiAgICBjdXJyW2xhc3RLZXldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyB0byBhbiBhcnJheSBpbiB0aGUgc3ludGhlc2l6ZWQgb2JqZWN0IGZpbGUuXG4gICAqXG4gICAqIElmIHRoZSBhcnJheSBpcyBuZXN0ZWQsIHNlcGFyYXRlIGVhY2ggbmVzdGVkIGxldmVsIHVzaW5nIGEgZG90ICguKSBpbiB0aGUgcGF0aCBwYXJhbWV0ZXIuXG4gICAqIElmIHRoZXJlIGlzIGFuIGFycmF5IGFzIHBhcnQgb2YgdGhlIG5lc3RpbmcsIHNwZWNpZnkgdGhlIGluZGV4IGluIHRoZSBwYXRoLlxuICAgKlxuICAgKiBUbyBpbmNsdWRlIGEgbGl0ZXJhbCBgLmAgaW4gdGhlIHByb3BlcnR5IG5hbWUsIHByZWZpeCB3aXRoIGEgYFxcYC4gSW4gbW9zdFxuICAgKiBwcm9ncmFtbWluZyBsYW5ndWFnZXMgeW91IHdpbGwgbmVlZCB0byB3cml0ZSB0aGlzIGFzIGBcIlxcXFwuXCJgIGJlY2F1c2UgdGhlXG4gICAqIGBcXGAgaXRzZWxmIHdpbGwgbmVlZCB0byBiZSBlc2NhcGVkLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSwgd2l0aCB0aGUgZm9sbG93aW5nIG9iamVjdCBmaWxlXG4gICAqIGBgYGpzb25cbiAgICogXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgKiAgIFwiZXhjbHVkZVwiOiBbXCJub2RlX21vZHVsZXNcIl0sXG4gICAqICAgXCJsaWJcIjogW1wiZXMyMDIwXCJdXG4gICAqICAgLi4uXG4gICAqIH1cbiAgICogLi4uXG4gICAqIGBgYFxuICAgKlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIHByb2plY3QudHNjb25maWcuZmlsZS5hZGRUb0FycmF5KCdjb21waWxlck9wdGlvbnMuZXhjbHVkZScsICdjb3ZlcmFnZScpO1xuICAgKiBwcm9qZWN0LnRzY29uZmlnLmZpbGUuYWRkVG9BcnJheSgnY29tcGlsZXJPcHRpb25zLmxpYicsICdkb20nLCAnZG9tLml0ZXJhYmxlJywgJ2VzbmV4dCcpO1xuICAgKiBgYGBcbiAgICogd291bGQgcmVzdWx0IGluIHRoZSBmb2xsb3dpbmcgb2JqZWN0IGZpbGVcbiAgICogYGBganNvblxuICAgKiBcImNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAqICAgXCJleGNsdWRlXCI6IFtcIm5vZGVfbW9kdWxlc1wiLCBcImNvdmVyYWdlXCJdLFxuICAgKiAgIFwibGliXCI6IFtcImVzMjAyMFwiLCBcImRvbVwiLCBcImRvbS5pdGVyYWJsZVwiLCBcImVzbmV4dFwiXVxuICAgKiAgIC4uLlxuICAgKiB9XG4gICAqIC4uLlxuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHksIHlvdSBjYW4gdXNlIGRvdCBub3RhdGlvbiB0b1xuICAgKiAgICAgICAgYXR0IHRvIGFycmF5cyBpbiBjb21wbGV4IHR5cGVzLiBBbnkgaW50ZXJtZWRpYXRlIGtleXNcbiAgICogICAgICAgIHdpbGwgYmUgY3JlYXRlZCBhcyBuZWVkZWQuXG4gICAqIEBwYXJhbSB2YWx1ZXMgLSBUaGUgdmFsdWVzIHRvIGFkZC4gQ291bGQgYmUgcHJpbWl0aXZlIG9yIGNvbXBsZXguXG4gICAqL1xuICBwdWJsaWMgYWRkVG9BcnJheShwYXRoOiBzdHJpbmcsIC4uLnZhbHVlczogYW55KSB7XG4gICAgY29uc3QgcGFydHMgPSBzcGxpdE9uUGVyaW9kcyhwYXRoKTtcbiAgICBsZXQgY3VycjogYW55ID0gdGhpcy5yYXdPdmVycmlkZXM7XG5cbiAgICB3aGlsZSAocGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgY29uc3Qga2V5ID0gcGFydHMuc2hpZnQoKSE7XG5cbiAgICAgIC8vIGlmIHdlIGNhbid0IHJlY3Vyc2UgZnVydGhlciBvciB0aGUgcHJldmlvdXMgdmFsdWUgaXMgbm90IGFuXG4gICAgICAvLyBvYmplY3Qgb3ZlcndyaXRlIGl0IHdpdGggYW4gb2JqZWN0LlxuICAgICAgY29uc3QgaXNPYmplY3QgPVxuICAgICAgICBjdXJyW2tleV0gIT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2YgY3VycltrZXldID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KGN1cnJba2V5XSk7XG4gICAgICBpZiAoIWlzT2JqZWN0KSB7XG4gICAgICAgIGN1cnJba2V5XSA9IHt9O1xuICAgICAgfVxuXG4gICAgICBjdXJyID0gY3VycltrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IGxhc3RLZXkgPSBwYXJ0cy5zaGlmdCgpITtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyW2xhc3RLZXldKSkge1xuICAgICAgY3VycltsYXN0S2V5XS5wdXNoKC4uLnZhbHVlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJbbGFzdEtleV0gPSB7XG4gICAgICAgIF9fJEFQUEVORDogWy4uLihjdXJyW2xhc3RLZXldPy5fXyRBUFBFTkQgPz8gW10pLCAuLi52YWx1ZXNdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBhbiBSRkMgNjkwMiBKU09OLXBhdGNoIHRvIHRoZSBzeW50aGVzaXplZCBvYmplY3QgZmlsZS5cbiAgICogU2VlIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjNjkwMiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIHdpdGggdGhlIGZvbGxvd2luZyBvYmplY3QgZmlsZVxuICAgKiBgYGBqc29uXG4gICAqIFwiY29tcGlsZXJPcHRpb25zXCI6IHtcbiAgICogICBcImV4Y2x1ZGVcIjogW1wibm9kZV9tb2R1bGVzXCJdLFxuICAgKiAgIFwibGliXCI6IFtcImVzMjAyMFwiXVxuICAgKiAgIC4uLlxuICAgKiB9XG4gICAqIC4uLlxuICAgKiBgYGBcbiAgICpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBwcm9qZWN0LnRzY29uZmlnLmZpbGUucGF0Y2goSnNvblBhdGNoLmFkZChcIi9jb21waWxlck9wdGlvbnMvZXhjbHVkZS8tXCIsIFwiY292ZXJhZ2VcIikpO1xuICAgKiBwcm9qZWN0LnRzY29uZmlnLmZpbGUucGF0Y2goSnNvblBhdGNoLnJlcGxhY2UoXCIvY29tcGlsZXJPcHRpb25zL2xpYlwiLCBbXCJkb21cIiwgXCJkb20uaXRlcmFibGVcIiwgXCJlc25leHRcIl0pKTtcbiAgICogYGBgXG4gICAqIHdvdWxkIHJlc3VsdCBpbiB0aGUgZm9sbG93aW5nIG9iamVjdCBmaWxlXG4gICAqIGBgYGpzb25cbiAgICogXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgKiAgIFwiZXhjbHVkZVwiOiBbXCJub2RlX21vZHVsZXNcIiwgXCJjb3ZlcmFnZVwiXSxcbiAgICogICBcImxpYlwiOiBbXCJkb21cIiwgXCJkb20uaXRlcmFibGVcIiwgXCJlc25leHRcIl1cbiAgICogICAuLi5cbiAgICogfVxuICAgKiAuLi5cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwYXRjaGVzIC0gVGhlIHBhdGNoIG9wZXJhdGlvbnMgdG8gYXBwbHlcbiAgICovXG4gIHB1YmxpYyBwYXRjaCguLi5wYXRjaGVzOiBKc29uUGF0Y2hbXSkge1xuICAgIHRoaXMucGF0Y2hPcGVyYXRpb25zLnB1c2gocGF0Y2hlcyk7XG4gIH1cblxuICAvKipcbiAgICogU3ludGFjdGljIHN1Z2FyIGZvciBgYWRkT3ZlcnJpZGUocGF0aCwgdW5kZWZpbmVkKWAuXG4gICAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIG9mIHRoZSB2YWx1ZSB0byBkZWxldGVcbiAgICovXG4gIHB1YmxpYyBhZGREZWxldGlvbk92ZXJyaWRlKHBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuYWRkT3ZlcnJpZGUocGF0aCwgdW5kZWZpbmVkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzeW50aGVzaXplQ29udGVudChyZXNvbHZlcjogSVJlc29sdmVyKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvYmogPSB0aGlzLm9iajtcblxuICAgIGNvbnN0IHJlc29sdmVkID1cbiAgICAgIHJlc29sdmVyLnJlc29sdmUob2JqLCB7XG4gICAgICAgIG9taXRFbXB0eTogdGhpcy5vbWl0RW1wdHksXG4gICAgICB9KSA/PyB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzb2x2ZWQpIHtcbiAgICAgIGRlZXBNZXJnZShbcmVzb2x2ZWQsIHRoaXMucmF3T3ZlcnJpZGVzXSwgeyBkZXN0cnVjdGl2ZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBsZXQgcGF0Y2hlZCA9IHJlc29sdmVkO1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHRoaXMucGF0Y2hPcGVyYXRpb25zKSB7XG4gICAgICBwYXRjaGVkID0gSnNvblBhdGNoLmFwcGx5KHBhdGNoZWQsIC4uLm9wZXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBwYXRjaGVkID8gSlNPTi5zdHJpbmdpZnkocGF0Y2hlZCwgdW5kZWZpbmVkLCAyKSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFNwbGl0IG9uIHBlcmlvZHMgd2hpbGUgcHJvY2Vzc2luZyBlc2NhcGUgY2hhcmFjdGVycyBcXFxuICovXG5mdW5jdGlvbiBzcGxpdE9uUGVyaW9kcyh4OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIC8vIEJ1aWxkIHRoaXMgbGlzdCBpbiByZXZlcnNlIGJlY2F1c2UgaXQncyBtb3JlIGNvbnZlbmllbnQgdG8gZ2V0IHRoZSBcImN1cnJlbnRcIlxuICAvLyBpdGVtIGJ5IGRvaW5nIHJldFswXSB0aGFuIGJ5IHJldFtyZXQubGVuZ3RoIC0gMV0uXG4gIGNvbnN0IHJldCA9IFtcIlwiXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHhbaV0gPT09IFwiXFxcXFwiICYmIGkgKyAxIDwgeC5sZW5ndGgpIHtcbiAgICAgIHJldFswXSArPSB4W2kgKyAxXTtcbiAgICAgIGkrKztcbiAgICB9IGVsc2UgaWYgKHhbaV0gPT09IFwiLlwiKSB7XG4gICAgICByZXQudW5zaGlmdChcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0WzBdICs9IHhbaV07XG4gICAgfVxuICB9XG5cbiAgcmV0LnJldmVyc2UoKTtcbiAgcmV0dXJuIHJldDtcbn1cbiJdfQ==