projen
Version:
CDK for software projects
216 lines • 23.1 kB
JavaScript
;
var _a;
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 {
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;
_a = JSII_RTTI_SYMBOL_1;
ObjectFile[_a] = { fqn: "projen.ObjectFile", version: "0.99.51" };
/**
* 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LWZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvb2JqZWN0LWZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxpQ0FBa0M7QUFDbEMsNkNBQXlDO0FBQ3pDLGlDQUFtQztBQTJCbkM7O0dBRUc7QUFDSCxNQUFzQixVQUFXLFNBQVEsZUFBUTtJQXNCL0MsWUFBWSxLQUFpQixFQUFFLFFBQWdCLEVBQUUsT0FBMEI7UUFDekUsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFaEMsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDO1FBQzVDLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BaUNHO0lBQ0ksV0FBVyxDQUFDLElBQVksRUFBRSxLQUFVO1FBQ3pDLE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLElBQUksR0FBUSxJQUFJLENBQUMsWUFBWSxDQUFDO1FBRWxDLE9BQU8sS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFHLENBQUM7WUFFM0IsOERBQThEO1lBQzlELHNDQUFzQztZQUN0QyxNQUFNLFFBQVEsR0FDWixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSTtnQkFDakIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUTtnQkFDN0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENB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UyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3JFLENBQUM7O0FBek5ILGdDQTBOQzs7O0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGNBQWMsQ0FBQyxDQUFTO0lBQy9CLCtFQUErRTtJQUMvRSxvREFBb0Q7SUFDcEQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNqQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNuQixDQUFDLEVBQUUsQ0FBQztRQUNOLENBQUM7YUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN4QixHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xCLENBQUM7YUFBTSxDQUFDO1lBQ04sR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQztJQUVELEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNkLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgdHlwZSB7IEZpbGVCYXNlT3B0aW9ucywgSVJlc29sdmVyIH0gZnJvbSBcIi4vZmlsZVwiO1xuaW1wb3J0IHsgRmlsZUJhc2UgfSBmcm9tIFwiLi9maWxlXCI7XG5pbXBvcnQgeyBKc29uUGF0Y2ggfSBmcm9tIFwiLi9qc29uLXBhdGNoXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UgfSBmcm9tIFwiLi91dGlsXCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYE9iamVjdEZpbGVgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9iamVjdEZpbGVPcHRpb25zIGV4dGVuZHMgRmlsZUJhc2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBvYmplY3QgdGhhdCB3aWxsIGJlIHNlcmlhbGl6ZWQuIFlvdSBjYW4gbW9kaWZ5IHRoZSBvYmplY3QncyBjb250ZW50c1xuICAgKiBiZWZvcmUgc3ludGhlc2lzLlxuICAgKlxuICAgKiBTZXJpYWxpemF0aW9uIG9mIHRoZSBvYmplY3QgaXMgc2ltaWxhciB0byBKU09OLnN0cmluZ2lmeSB3aXRoIGZldyBlbmhhbmNlbWVudHM6XG4gICAqIC0gdmFsdWVzIHRoYXQgYXJlIGZ1bmN0aW9ucyB3aWxsIGJlIGNhbGxlZCBkdXJpbmcgc3ludGhlc2lzIGFuZCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VyaWFsaXplZCAtIHRoaXMgYWxsb3cgdG8gaGF2ZSBsYXp5IHZhbHVlcy5cbiAgICogLSBgU2V0YCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhcnJheVxuICAgKiAtIGBNYXBgIHdpbGwgYmUgY29udmVydGVkIHRvIGEgcGxhaW4gb2JqZWN0ICh7IGtleTogdmFsdWUsIC4uLiB9fSlcbiAgICogLSBgUmVnRXhwYCB3aXRob3V0IGZsYWdzIHdpbGwgYmUgY29udmVydGVkIHRvIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgc291cmNlXG4gICAqXG4gICAqICBAZGVmYXVsdCB7fSBhbiBlbXB0eSBvYmplY3QgKHVzZSBgZmlsZS5vYmpgIHRvIG11dGF0ZSkuXG4gICAqL1xuICByZWFkb25seSBvYmo/OiBhbnk7XG5cbiAgLyoqXG4gICAqIE9taXRzIGVtcHR5IG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IG9taXRFbXB0eT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBPYmplY3QgZmlsZS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE9iamVjdEZpbGUgZXh0ZW5kcyBGaWxlQmFzZSB7XG4gIC8qKlxuICAgKiBUaGUgb3V0cHV0IG9iamVjdC4gVGhpcyBvYmplY3QgY2FuIGJlIG11dGF0ZWQgdW50aWwgdGhlIHByb2plY3QgaXNcbiAgICogc3ludGhlc2l6ZWQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG9iajogb2JqZWN0O1xuXG4gIC8qKlxuICAgKiBBbiBvYmplY3QgdG8gYmUgbWVyZ2VkIG9uIHRvcCBvZiBgb2JqYCBhZnRlciB0aGUgcmVzb2x2ZXIgaXMgY2FsbGVkXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJhd092ZXJyaWRlczogb2JqZWN0O1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgZW1wdHkgb2JqZWN0cyBhbmQgYXJyYXlzIGFyZSBvbWl0dGVkIGZyb20gdGhlIG91dHB1dCBvYmplY3QuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb21pdEVtcHR5OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBwYXRjaGVzIHRvIGJlIGFwcGxpZWQgdG8gYG9iamAgYWZ0ZXIgdGhlIHJlc29sdmVyIGlzIGNhbGxlZFxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwYXRjaE9wZXJhdGlvbnM6IEFycmF5PEpzb25QYXRjaFtdPjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgZmlsZVBhdGg6IHN0cmluZywgb3B0aW9uczogT2JqZWN0RmlsZU9wdGlvbnMpIHtcbiAgICBzdXBlcihzY29wZSwgZmlsZVBhdGgsIG9wdGlvbnMpO1xuXG4gICAgdGhpcy5vYmogPSBvcHRpb25zLm9iaiA/PyB7fTtcbiAgICB0aGlzLm9taXRFbXB0eSA9IG9wdGlvbnMub21pdEVtcHR5ID8/IGZhbHNlO1xuICAgIHRoaXMucmF3T3ZlcnJpZGVzID0ge307XG4gICAgdGhpcy5wYXRjaE9wZXJhdGlvbnMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIG92ZXJyaWRlIHRvIHRoZSBzeW50aGVzaXplZCBvYmplY3QgZmlsZS5cbiAgICpcbiAgICogSWYgdGhlIG92ZXJyaWRlIGlzIG5lc3RlZCwgc2VwYXJhdGUgZWFjaCBuZXN0ZWQgbGV2ZWwgdXNpbmcgYSBkb3QgKC4pIGluIHRoZSBwYXRoIHBhcmFtZXRlci5cbiAgICogSWYgdGhlcmUgaXMgYW4gYXJyYXkgYXMgcGFydCBvZiB0aGUgbmVzdGluZywgc3BlY2lmeSB0aGUgaW5kZXggaW4gdGhlIHBhdGguXG4gICAqXG4gICAqIFRvIGluY2x1ZGUgYSBsaXRlcmFsIGAuYCBpbiB0aGUgcHJvcGVydHkgbmFtZSwgcHJlZml4IHdpdGggYSBgXFxgLiBJbiBtb3N0XG4gICAqIHByb2dyYW1taW5nIGxhbmd1YWdlcyB5b3Ugd2lsbCBuZWVkIHRvIHdyaXRlIHRoaXMgYXMgYFwiXFxcXC5cImAgYmVjYXVzZSB0aGVcbiAgICogYFxcYCBpdHNlbGYgd2lsbCBuZWVkIHRvIGJlIGVzY2FwZWQuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLFxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIHByb2plY3QudHNjb25maWcuZmlsZS5hZGRPdmVycmlkZSgnY29tcGlsZXJPcHRpb25zLmFsd2F5c1N0cmljdCcsIHRydWUpO1xuICAgKiBwcm9qZWN0LnRzY29uZmlnLmZpbGUuYWRkT3ZlcnJpZGUoJ2NvbXBpbGVyT3B0aW9ucy5saWInLCBbJ2RvbScsICdkb20uaXRlcmFibGUnLCAnZXNuZXh0J10pO1xuICAgKiBgYGBcbiAgICogd291bGQgYWRkIHRoZSBvdmVycmlkZXNcbiAgICogYGBganNvblxuICAgKiBcImNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAqICAgXCJhbHdheXNTdHJpY3RcIjogdHJ1ZSxcbiAgICogICBcImxpYlwiOiBbXG4gICAqICAgICBcImRvbVwiLFxuICAgKiAgICAgXCJkb20uaXRlcmFibGVcIixcbiAgICogICAgIFwiZXNuZXh0XCJcbiAgICogICBdXG4gICAqICAgLi4uXG4gICAqIH1cbiAgICogLi4uXG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSwgeW91IGNhbiB1c2UgZG90IG5vdGF0aW9uIHRvXG4gICAqICAgICAgICBvdmVycmlkZSB2YWx1ZXMgaW4gY29tcGxleCB0eXBlcy4gQW55IGludGVybWVkaWF0ZSBrZXlzXG4gICAqICAgICAgICB3aWxsIGJlIGNyZWF0ZWQgYXMgbmVlZGVkLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUuIENvdWxkIGJlIHByaW1pdGl2ZSBvciBjb21wbGV4LlxuICAgKi9cbiAgcHVibGljIGFkZE92ZXJyaWRlKHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGNvbnN0IHBhcnRzID0gc3BsaXRPblBlcmlvZHMocGF0aCk7XG4gICAgbGV0IGN1cnI6IGFueSA9IHRoaXMucmF3T3ZlcnJpZGVzO1xuXG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGNvbnN0IGtleSA9IHBhcnRzLnNoaWZ0KCkhO1xuXG4gICAgICAvLyBpZiB3ZSBjYW4ndCByZWN1cnNlIGZ1cnRoZXIgb3IgdGhlIHByZXZpb3VzIHZhbHVlIGlzIG5vdCBhblxuICAgICAgLy8gb2JqZWN0IG92ZXJ3cml0ZSBpdCB3aXRoIGFuIG9iamVjdC5cbiAgICAgIGNvbnN0IGlzT2JqZWN0ID1cbiAgICAgICAgY3VycltrZXldICE9IG51bGwgJiZcbiAgICAgICAgdHlwZW9mIGN1cnJba2V5XSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAhQXJyYXkuaXNBcnJheShjdXJyW2tleV0pO1xuICAgICAgaWYgKCFpc09iamVjdCkge1xuICAgICAgICBjdXJyW2tleV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgY3VyciA9IGN1cnJba2V5XTtcbiAgICB9XG5cbiAgICBjb25zdCBsYXN0S2V5ID0gcGFydHMuc2hpZnQoKSE7XG4gICAgY3VycltsYXN0S2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgdG8gYW4gYXJyYXkgaW4gdGhlIHN5bnRoZXNpemVkIG9iamVjdCBmaWxlLlxuICAgKlxuICAgKiBJZiB0aGUgYXJyYXkgaXMgbmVzdGVkLCBzZXBhcmF0ZSBlYWNoIG5lc3RlZCBsZXZlbCB1c2luZyBhIGRvdCAoLikgaW4gdGhlIHBhdGggcGFyYW1ldGVyLlxuICAgKiBJZiB0aGVyZSBpcyBhbiBhcnJheSBhcyBwYXJ0IG9mIHRoZSBuZXN0aW5nLCBzcGVjaWZ5IHRoZSBpbmRleCBpbiB0aGUgcGF0aC5cbiAgICpcbiAgICogVG8gaW5jbHVkZSBhIGxpdGVyYWwgYC5gIGluIHRoZSBwcm9wZXJ0eSBuYW1lLCBwcmVmaXggd2l0aCBhIGBcXGAuIEluIG1vc3RcbiAgICogcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIHlvdSB3aWxsIG5lZWQgdG8gd3JpdGUgdGhpcyBhcyBgXCJcXFxcLlwiYCBiZWNhdXNlIHRoZVxuICAgKiBgXFxgIGl0c2VsZiB3aWxsIG5lZWQgdG8gYmUgZXNjYXBlZC5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIHdpdGggdGhlIGZvbGxvd2luZyBvYmplY3QgZmlsZVxuICAgKiBgYGBqc29uXG4gICAqIFwiY29tcGlsZXJPcHRpb25zXCI6IHtcbiAgICogICBcImV4Y2x1ZGVcIjogW1wibm9kZV9tb2R1bGVzXCJdLFxuICAgKiAgIFwibGliXCI6IFtcImVzMjAyMFwiXVxuICAgKiAgIC4uLlxuICAgKiB9XG4gICAqIC4uLlxuICAgKiBgYGBcbiAgICpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBwcm9qZWN0LnRzY29uZmlnLmZpbGUuYWRkVG9BcnJheSgnY29tcGlsZXJPcHRpb25zLmV4Y2x1ZGUnLCAnY292ZXJhZ2UnKTtcbiAgICogcHJvamVjdC50c2NvbmZpZy5maWxlLmFkZFRvQXJyYXkoJ2NvbXBpbGVyT3B0aW9ucy5saWInLCAnZG9tJywgJ2RvbS5pdGVyYWJsZScsICdlc25leHQnKTtcbiAgICogYGBgXG4gICAqIHdvdWxkIHJlc3VsdCBpbiB0aGUgZm9sbG93aW5nIG9iamVjdCBmaWxlXG4gICAqIGBgYGpzb25cbiAgICogXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgKiAgIFwiZXhjbHVkZVwiOiBbXCJub2RlX21vZHVsZXNcIiwgXCJjb3ZlcmFnZVwiXSxcbiAgICogICBcImxpYlwiOiBbXCJlczIwMjBcIiwgXCJkb21cIiwgXCJkb20uaXRlcmFibGVcIiwgXCJlc25leHRcIl1cbiAgICogICAuLi5cbiAgICogfVxuICAgKiAuLi5cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5LCB5b3UgY2FuIHVzZSBkb3Qgbm90YXRpb24gdG9cbiAgICogICAgICAgIGF0dCB0byBhcnJheXMgaW4gY29tcGxleCB0eXBlcy4gQW55IGludGVybWVkaWF0ZSBrZXlzXG4gICAqICAgICAgICB3aWxsIGJlIGNyZWF0ZWQgYXMgbmVlZGVkLlxuICAgKiBAcGFyYW0gdmFsdWVzIC0gVGhlIHZhbHVlcyB0byBhZGQuIENvdWxkIGJlIHByaW1pdGl2ZSBvciBjb21wbGV4LlxuICAgKi9cbiAgcHVibGljIGFkZFRvQXJyYXkocGF0aDogc3RyaW5nLCAuLi52YWx1ZXM6IGFueSkge1xuICAgIGNvbnN0IHBhcnRzID0gc3BsaXRPblBlcmlvZHMocGF0aCk7XG4gICAgbGV0IGN1cnI6IGFueSA9IHRoaXMucmF3T3ZlcnJpZGVzO1xuXG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGNvbnN0IGtleSA9IHBhcnRzLnNoaWZ0KCkhO1xuXG4gICAgICAvLyBpZiB3ZSBjYW4ndCByZWN1cnNlIGZ1cnRoZXIgb3IgdGhlIHByZXZpb3VzIHZhbHVlIGlzIG5vdCBhblxuICAgICAgLy8gb2JqZWN0IG92ZXJ3cml0ZSBpdCB3aXRoIGFuIG9iamVjdC5cbiAgICAgIGNvbnN0IGlzT2JqZWN0ID1cbiAgICAgICAgY3VycltrZXldICE9IG51bGwgJiZcbiAgICAgICAgdHlwZW9mIGN1cnJba2V5XSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAhQXJyYXkuaXNBcnJheShjdXJyW2tleV0pO1xuICAgICAgaWYgKCFpc09iamVjdCkge1xuICAgICAgICBjdXJyW2tleV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgY3VyciA9IGN1cnJba2V5XTtcbiAgICB9XG5cbiAgICBjb25zdCBsYXN0S2V5ID0gcGFydHMuc2hpZnQoKSE7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY3VycltsYXN0S2V5XSkpIHtcbiAgICAgIGN1cnJbbGFzdEtleV0ucHVzaCguLi52YWx1ZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyW2xhc3RLZXldID0ge1xuICAgICAgICBfXyRBUFBFTkQ6IFsuLi4oY3VycltsYXN0S2V5XT8uX18kQVBQRU5EID8/IFtdKSwgLi4udmFsdWVzXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYW4gUkZDIDY5MDIgSlNPTi1wYXRjaCB0byB0aGUgc3ludGhlc2l6ZWQgb2JqZWN0IGZpbGUuXG4gICAqIFNlZSBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzY5MDIgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCB3aXRoIHRoZSBmb2xsb3dpbmcgb2JqZWN0IGZpbGVcbiAgICogYGBganNvblxuICAgKiBcImNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAqICAgXCJleGNsdWRlXCI6IFtcIm5vZGVfbW9kdWxlc1wiXSxcbiAgICogICBcImxpYlwiOiBbXCJlczIwMjBcIl1cbiAgICogICAuLi5cbiAgICogfVxuICAgKiAuLi5cbiAgICogYGBgXG4gICAqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogcHJvamVjdC50c2NvbmZpZy5maWxlLnBhdGNoKEpzb25QYXRjaC5hZGQoXCIvY29tcGlsZXJPcHRpb25zL2V4Y2x1ZGUvLVwiLCBcImNvdmVyYWdlXCIpKTtcbiAgICogcHJvamVjdC50c2NvbmZpZy5maWxlLnBhdGNoKEpzb25QYXRjaC5yZXBsYWNlKFwiL2NvbXBpbGVyT3B0aW9ucy9saWJcIiwgW1wiZG9tXCIsIFwiZG9tLml0ZXJhYmxlXCIsIFwiZXNuZXh0XCJdKSk7XG4gICAqIGBgYFxuICAgKiB3b3VsZCByZXN1bHQgaW4gdGhlIGZvbGxvd2luZyBvYmplY3QgZmlsZVxuICAgKiBgYGBqc29uXG4gICAqIFwiY29tcGlsZXJPcHRpb25zXCI6IHtcbiAgICogICBcImV4Y2x1ZGVcIjogW1wibm9kZV9tb2R1bGVzXCIsIFwiY292ZXJhZ2VcIl0sXG4gICAqICAgXCJsaWJcIjogW1wiZG9tXCIsIFwiZG9tLml0ZXJhYmxlXCIsIFwiZXNuZXh0XCJdXG4gICAqICAgLi4uXG4gICAqIH1cbiAgICogLi4uXG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gcGF0Y2hlcyAtIFRoZSBwYXRjaCBvcGVyYXRpb25zIHRvIGFwcGx5XG4gICAqL1xuICBwdWJsaWMgcGF0Y2goLi4ucGF0Y2hlczogSnNvblBhdGNoW10pIHtcbiAgICB0aGlzLnBhdGNoT3BlcmF0aW9ucy5wdXNoKHBhdGNoZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bnRhY3RpYyBzdWdhciBmb3IgYGFkZE92ZXJyaWRlKHBhdGgsIHVuZGVmaW5lZClgLlxuICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgdmFsdWUgdG8gZGVsZXRlXG4gICAqL1xuICBwdWJsaWMgYWRkRGVsZXRpb25PdmVycmlkZShwYXRoOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFkZE92ZXJyaWRlKHBhdGgsIHVuZGVmaW5lZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3ludGhlc2l6ZUNvbnRlbnQocmVzb2x2ZXI6IElSZXNvbHZlcik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy5vYmo7XG5cbiAgICBjb25zdCByZXNvbHZlZCA9XG4gICAgICByZXNvbHZlci5yZXNvbHZlKG9iaiwge1xuICAgICAgICBvbWl0RW1wdHk6IHRoaXMub21pdEVtcHR5LFxuICAgICAgfSkgPz8gdW5kZWZpbmVkO1xuXG4gICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICBkZWVwTWVyZ2UoW3Jlc29sdmVkLCB0aGlzLnJhd092ZXJyaWRlc10sIHsgZGVzdHJ1Y3RpdmU6IHRydWUgfSk7XG4gICAgfVxuXG4gICAgbGV0IHBhdGNoZWQgPSByZXNvbHZlZDtcbiAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiB0aGlzLnBhdGNoT3BlcmF0aW9ucykge1xuICAgICAgcGF0Y2hlZCA9IEpzb25QYXRjaC5hcHBseShwYXRjaGVkLCAuLi5vcGVyYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gcGF0Y2hlZCA/IEpTT04uc3RyaW5naWZ5KHBhdGNoZWQsIHVuZGVmaW5lZCwgMikgOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBTcGxpdCBvbiBwZXJpb2RzIHdoaWxlIHByb2Nlc3NpbmcgZXNjYXBlIGNoYXJhY3RlcnMgXFxcbiAqL1xuZnVuY3Rpb24gc3BsaXRPblBlcmlvZHMoeDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAvLyBCdWlsZCB0aGlzIGxpc3QgaW4gcmV2ZXJzZSBiZWNhdXNlIGl0J3MgbW9yZSBjb252ZW5pZW50IHRvIGdldCB0aGUgXCJjdXJyZW50XCJcbiAgLy8gaXRlbSBieSBkb2luZyByZXRbMF0gdGhhbiBieSByZXRbcmV0Lmxlbmd0aCAtIDFdLlxuICBjb25zdCByZXQgPSBbXCJcIl07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIGlmICh4W2ldID09PSBcIlxcXFxcIiAmJiBpICsgMSA8IHgubGVuZ3RoKSB7XG4gICAgICByZXRbMF0gKz0geFtpICsgMV07XG4gICAgICBpKys7XG4gICAgfSBlbHNlIGlmICh4W2ldID09PSBcIi5cIikge1xuICAgICAgcmV0LnVuc2hpZnQoXCJcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldFswXSArPSB4W2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldC5yZXZlcnNlKCk7XG4gIHJldHVybiByZXQ7XG59XG4iXX0=