UNPKG

projen

Version:

CDK for software projects

149 lines • 24.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileBase = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const fs_1 = require("fs"); const path = require("path"); const _resolve_1 = require("./_resolve"); const common_1 = require("./common"); const component_1 = require("./component"); const projenrc_1 = require("./projenrc"); const util_1 = require("./util"); const constructs_1 = require("./util/constructs"); const diff_1 = require("./util/diff"); class FileBase extends component_1.Component { /** * The projen marker, used to identify files as projen-generated. * * Value is undefined if the project is being ejected. */ get marker() { if (this.project.ejected || !this.shouldAddMarker) { return undefined; } // `marker` is empty if project is being ejected or if explicitly disabled const projenrc = projenrc_1.ProjenrcFile.of(this.project)?.filePath ?? common_1.DEFAULT_PROJEN_RC_JS_FILENAME; return `${common_1.PROJEN_MARKER}. To modify, edit ${projenrc} and run "${this.project.projenCommand}".`; } constructor(scope, filePath, options = {}) { const project = (0, constructs_1.findClosestProject)(scope, new.target.name); const root = project.root; const normalizedPath = path.normalize(filePath); const projectPath = (0, util_1.normalizePersistedPath)(normalizedPath); const absolutePath = path.resolve(project.outdir, projectPath); const relativeProjectPath = path.relative(root.outdir, absolutePath); const rootProjectPath = (0, util_1.normalizePersistedPath)(relativeProjectPath); const autoId = `${new.target.name}@${projectPath}`; // Before actually creating the file, ensure the file path is unique within the full project tree // This is required because projects can create files inside their subprojects if (root.tryFindFile(absolutePath) || scope.node.tryFindChild(autoId)) { throw new Error(`There is already a file under ${rootProjectPath}`); } super(scope, autoId); this.node.addMetadata("type", "file"); this.node.addMetadata("path", rootProjectPath); this.readonly = !project.ejected && (options.readonly ?? true); this.executable = options.executable ?? false; this.path = projectPath; this.absolutePath = absolutePath; this.shouldAddMarker = options.marker ?? true; const globPattern = `/${this.path}`; const committed = options.committed ?? project.commitGenerated ?? true; if (committed && filePath !== ".gitattributes") { project.annotateGenerated(`/${filePath}`); } const editGitignore = options.editGitignore ?? true; if (editGitignore) { this.project.addGitIgnore(`${committed ? "!" : ""}${globPattern}`); } else { if (options.committed != null) { throw new Error('"gitignore" is disabled, so it does not make sense to specify "committed"'); } } } /** * Writes the file to the project's output directory */ synthesize() { const outdir = this.project.outdir; const filePath = path.join(outdir, this.path); const resolver = { resolve: (obj, options) => (0, _resolve_1.resolve)(obj, options), }; const content = this.synthesizeContent(resolver); if (content === undefined) { // remove file (if exists) and skip rest of synthesis (0, fs_1.rmSync)(filePath, { force: true, recursive: true }); return; } // check if the file was changed. const prev = (0, util_1.tryReadFileSync)(filePath); this._previousContent = prev; this._newContent = content; const prevReadonly = !(0, util_1.isWritable)(filePath); const successfulExecutableAssertion = (0, util_1.assertExecutablePermissions)(filePath, this.executable); if (prev !== undefined && content === prev && prevReadonly === this.readonly && successfulExecutableAssertion) { this.project.logger.verbose(`no change in ${filePath}`); this._changed = false; return; } (0, util_1.writeFile)(filePath, content, { readonly: this.readonly, executable: this.executable, }); this.checkForProjenMarker(); this._changed = true; } /** * For debugging, check whether a file was incorrectly generated with * or without the projen marker. The projen marker does not *need* to be * included on projen-generated files, but it's recommended since it signals * that it probably should not be edited directly. */ checkForProjenMarker() { const filePath = path.join(this.project.outdir, this.path); const contents = (0, util_1.tryReadFileSync)(filePath); const containsMarker = contents?.includes(common_1.PROJEN_MARKER); if (this.marker && !containsMarker) { this.project.logger.debug(`note: expected ${this.path} to contain marker but found none.`); } else if (!this.marker && containsMarker) { this.project.logger.debug(`note: expected ${this.path} to not contain marker but found one anyway.`); } } /** * Indicates if the file has been changed during synthesis. This property is * only available in `postSynthesize()` hooks. If this is `undefined`, the * file has not been synthesized yet. */ get changed() { return this._changed; } /** * Returns a unified diff of the old and new file contents with context lines * and hunk headers. Only available after synthesis. * * This is an expensive operation and should only be used on non time-critical * code paths, like debug output. * * @param colorize Whether to colorize the diff output. @default false * @param contextLines Number of context lines around changes. @default 3 * @returns the diff as an array of lines, or `undefined` if the file was * not changed or has not been synthesized yet. */ diff(colorize = false, contextLines = 3) { if (!this._changed) { return undefined; } return (0, diff_1.unifiedDiff)(this._previousContent ?? "", this._newContent ?? "", colorize, contextLines); } } exports.FileBase = FileBase; _a = JSII_RTTI_SYMBOL_1; FileBase[_a] = { fqn: "projen.FileBase", version: "0.99.51" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsMkJBQTRCO0FBQzVCLDZCQUE2QjtBQUU3Qix5Q0FBcUM7QUFDckMscUNBQXdFO0FBQ3hFLDJDQUF3QztBQUN4Qyx5Q0FBMEM7QUFDMUMsaUNBTWdCO0FBQ2hCLGtEQUF1RDtBQUN2RCxzQ0FBMEM7QUF3QzFDLE1BQXNCLFFBQVMsU0FBUSxxQkFBUztJQTBCOUM7Ozs7T0FJRztJQUNILElBQVcsTUFBTTtRQUNmLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDbEQsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELDBFQUEwRTtRQUMxRSxNQUFNLFFBQVEsR0FDWix1QkFBWSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxJQUFJLHNDQUE2QixDQUFDO1FBQzNFLE9BQU8sR0FBRyxzQkFBYSxxQkFBcUIsUUFBUSxhQUFhLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFJLENBQUM7SUFDbEcsQ0FBQztJQUVELFlBQ0UsS0FBaUIsRUFDakIsUUFBZ0IsRUFDaEIsVUFBMkIsRUFBRTtRQUU3QixNQUFNLE9BQU8sR0FBRyxJQUFBLCtCQUFrQixFQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDMUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLFdBQVcsR0FBRyxJQUFBLDZCQUFzQixFQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0s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Q0FBQyxDQUFDO1FBQzNELE1BQU0sUUFBUSxHQUFHLElBQUEsc0JBQWUsRUFBQyxRQUFRLENBQUMsQ0FBQztRQUMzQyxNQUFNLGNBQWMsR0FBRyxRQUFRLEVBQUUsUUFBUSxDQUFDLHNCQUFhLENBQUMsQ0FBQztRQUN6RCxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3ZCLGtCQUFrQixJQUFJLENBQUMsSUFBSSxvQ0FBb0MsQ0FDaEUsQ0FBQztRQUNKLENBQUM7YUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3ZCLGtCQUFrQixJQUFJLENBQUMsSUFBSSw4Q0FBOEMsQ0FDMUUsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQVcsT0FBTztRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLEVBQUUsWUFBWSxHQUFHLENBQUM7UUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNuQixPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBRUQsT0FBTyxJQUFBLGtCQUFXLEVBQ2hCLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxFQUFFLEVBQzNCLElBQUksQ0FBQyxXQUFXLElBQUksRUFBRSxFQUN0QixRQUFRLEVBQ1IsWUFBWSxDQUNiLENBQUM7SUFDSixDQUFDOztBQXJNSCw0QkFzTUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBybVN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB0eXBlIHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIi4vX3Jlc29sdmVcIjtcbmltcG9ydCB7IFBST0pFTl9NQVJLRVIsIERFRkFVTFRfUFJPSkVOX1JDX0pTX0ZJTEVOQU1FIH0gZnJvbSBcIi4vY29tbW9uXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IFByb2plbnJjRmlsZSB9IGZyb20gXCIuL3Byb2plbnJjXCI7XG5pbXBvcnQge1xuICBhc3NlcnRFeGVjdXRhYmxlUGVybWlzc2lvbnMsXG4gIGlzV3JpdGFibGUsXG4gIG5vcm1hbGl6ZVBlcnNpc3RlZFBhdGgsXG4gIHRyeVJlYWRGaWxlU3luYyxcbiAgd3JpdGVGaWxlLFxufSBmcm9tIFwiLi91dGlsXCI7XG5pbXBvcnQgeyBmaW5kQ2xvc2VzdFByb2plY3QgfSBmcm9tIFwiLi91dGlsL2NvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHVuaWZpZWREaWZmIH0gZnJvbSBcIi4vdXRpbC9kaWZmXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUJhc2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgZmlsZSBzaG91bGQgYmUgY29tbWl0dGVkIHRvIGdpdCBvciBpZ25vcmVkLiBCeVxuICAgKiBkZWZhdWx0LCBhbGwgZ2VuZXJhdGVkIGZpbGVzIGFyZSBjb21taXR0ZWQgYW5kIGFudGktdGFtcGVyIGlzIHVzZWQgdG9cbiAgICogcHJvdGVjdCBhZ2FpbnN0IG1hbnVhbCBtb2RpZmljYXRpb25zLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjb21taXR0ZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIHByb2plY3QncyAuZ2l0aWdub3JlIGZpbGVcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgZWRpdEdpdGlnbm9yZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGdlbmVyYXRlZCBmaWxlIHNob3VsZCBiZSByZWFkb25seS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZG9ubHk/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBnZW5lcmF0ZWQgZmlsZSBzaG91bGQgYmUgbWFya2VkIGFzIGV4ZWN1dGFibGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBleGVjdXRhYmxlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWRkcyB0aGUgcHJvamVuIG1hcmtlciB0byB0aGUgZmlsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBtYXJrZXIgd2lsbCBiZSBpbmNsdWRlZCBhcyBsb25nIGFzIHRoZSBwcm9qZWN0IGlzIG5vdCBlamVjdGVkXG4gICAqL1xuICByZWFkb25seSBtYXJrZXI/OiBib29sZWFuO1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRmlsZUJhc2UgZXh0ZW5kcyBDb21wb25lbnQge1xuICAvKipcbiAgICogVGhlIGZpbGUgcGF0aCwgcmVsYXRpdmUgdG8gdGhlIHByb2plY3QncyBvdXRkaXIuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGZpbGUgc2hvdWxkIGJlIHJlYWQtb25seSBvciByZWFkLXdyaXRlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGZpbGUgc2hvdWxkIGJlIG1hcmtlZCBhcyBleGVjdXRhYmxlXG4gICAqL1xuICBwdWJsaWMgZXhlY3V0YWJsZTogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGFic29sdXRlIHBhdGggb2YgdGhpcyBmaWxlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFic29sdXRlUGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgX2NoYW5nZWQ/OiBib29sZWFuO1xuICBwcml2YXRlIF9wcmV2aW91c0NvbnRlbnQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgX25ld0NvbnRlbnQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgc2hvdWxkQWRkTWFya2VyOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvamVuIG1hcmtlciwgdXNlZCB0byBpZGVudGlmeSBmaWxlcyBhcyBwcm9qZW4tZ2VuZXJhdGVkLlxuICAgKlxuICAgKiBWYWx1ZSBpcyB1bmRlZmluZWQgaWYgdGhlIHByb2plY3QgaXMgYmVpbmcgZWplY3RlZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgbWFya2VyKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMucHJvamVjdC5lamVjdGVkIHx8ICF0aGlzLnNob3VsZEFkZE1hcmtlcikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBgbWFya2VyYCBpcyBlbXB0eSBpZiBwcm9qZWN0IGlzIGJlaW5nIGVqZWN0ZWQgb3IgaWYgZXhwbGljaXRseSBkaXNhYmxlZFxuICAgIGNvbnN0IHByb2plbnJjID1cbiAgICAgIFByb2plbnJjRmlsZS5vZih0aGlzLnByb2plY3QpPy5maWxlUGF0aCA/PyBERUZBVUxUX1BST0pFTl9SQ19KU19GSUxFTkFNRTtcbiAgICByZXR1cm4gYCR7UFJPSkVOX01BUktFUn0uIFRvIG1vZGlmeSwgZWRpdCAke3Byb2plbnJjfSBhbmQgcnVuIFwiJHt0aGlzLnByb2plY3QucHJvamVuQ29tbWFuZH1cIi5gO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IElDb25zdHJ1Y3QsXG4gICAgZmlsZVBhdGg6IHN0cmluZyxcbiAgICBvcHRpb25zOiBGaWxlQmFzZU9wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgY29uc3QgcHJvamVjdCA9IGZpbmRDbG9zZXN0UHJvamVjdChzY29wZSwgbmV3LnRhcmdldC5uYW1lKTtcbiAgICBjb25zdCByb290ID0gcHJvamVjdC5yb290O1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gcGF0aC5ub3JtYWxpemUoZmlsZVBhdGgpO1xuICAgIGNvbnN0IHByb2plY3RQYXRoID0gbm9ybWFsaXplUGVyc2lzdGVkUGF0aChub3JtYWxpemVkUGF0aCk7XG4gICAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlKHByb2plY3Qub3V0ZGlyLCBwcm9qZWN0UGF0aCk7XG4gICAgY29uc3QgcmVsYXRpdmVQcm9qZWN0UGF0aCA9IHBhdGgucmVsYXRpdmUocm9vdC5vdXRkaXIsIGFic29sdXRlUGF0aCk7XG4gICAgY29uc3Qgcm9vdFByb2plY3RQYXRoID0gbm9ybWFsaXplUGVyc2lzdGVkUGF0aChyZWxhdGl2ZVByb2plY3RQYXRoKTtcbiAgICBjb25zdCBhdXRvSWQgPSBgJHtuZXcudGFyZ2V0Lm5hbWV9QCR7cHJvamVjdFBhdGh9YDtcblxuICAgIC8vIEJlZm9yZSBhY3R1YWxseSBjcmVhdGluZyB0aGUgZmlsZSwgZW5zdXJlIHRoZSBmaWxlIHBhdGggaXMgdW5pcXVlIHdpdGhpbiB0aGUgZnVsbCBwcm9qZWN0IHRyZWVcbiAgICAvLyBUaGlzIGlzIHJlcXVpcmVkIGJlY2F1c2UgcHJvamVjdHMgY2FuIGNyZWF0ZSBmaWxlcyBpbnNpZGUgdGhlaXIgc3VicHJvamVjdHNcbiAgICBpZiAocm9vdC50cnlGaW5kRmlsZShhYnNvbHV0ZVBhdGgpIHx8IHNjb3BlLm5vZGUudHJ5RmluZENoaWxkKGF1dG9JZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlcmUgaXMgYWxyZWFkeSBhIGZpbGUgdW5kZXIgJHtyb290UHJvamVjdFBhdGh9YCk7XG4gICAgfVxuXG4gICAgc3VwZXIoc2NvcGUsIGF1dG9JZCk7XG4gICAgdGhpcy5ub2RlLmFkZE1ldGFkYXRhKFwidHlwZVwiLCBcImZpbGVcIik7XG4gICAgdGhpcy5ub2RlLmFkZE1ldGFkYXRhKFwicGF0aFwiLCByb290UHJvamVjdFBhdGgpO1xuXG4gICAgdGhpcy5yZWFkb25seSA9ICFwcm9qZWN0LmVqZWN0ZWQgJiYgKG9wdGlvbnMucmVhZG9ubHkgPz8gdHJ1ZSk7XG4gICAgdGhpcy5leGVjdXRhYmxlID0gb3B0aW9ucy5leGVjdXRhYmxlID8/IGZhbHNlO1xuICAgIHRoaXMucGF0aCA9IHByb2plY3RQYXRoO1xuICAgIHRoaXMuYWJzb2x1dGVQYXRoID0gYWJzb2x1dGVQYXRoO1xuICAgIHRoaXMuc2hvdWxkQWRkTWFya2VyID0gb3B0aW9ucy5tYXJrZXIgPz8gdHJ1ZTtcblxuICAgIGNvbnN0IGdsb2JQYXR0ZXJuID0gYC8ke3RoaXMucGF0aH1gO1xuICAgIGNvbnN0IGNvbW1pdHRlZCA9IG9wdGlvbnMuY29tbWl0dGVkID8/IHByb2plY3QuY29tbWl0R2VuZXJhdGVkID8/IHRydWU7XG4gICAgaWYgKGNvbW1pdHRlZCAmJiBmaWxlUGF0aCAhPT0gXCIuZ2l0YXR0cmlidXRlc1wiKSB7XG4gICAgICBwcm9qZWN0LmFubm90YXRlR2VuZXJhdGVkKGAvJHtmaWxlUGF0aH1gKTtcbiAgICB9XG4gICAgY29uc3QgZWRpdEdpdGlnbm9yZSA9IG9wdGlvbnMuZWRpdEdpdGlnbm9yZSA/PyB0cnVlO1xuICAgIGlmIChlZGl0R2l0aWdub3JlKSB7XG4gICAgICB0aGlzLnByb2plY3QuYWRkR2l0SWdub3JlKGAke2NvbW1pdHRlZCA/IFwiIVwiIDogXCJcIn0ke2dsb2JQYXR0ZXJufWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAob3B0aW9ucy5jb21taXR0ZWQgIT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1wiZ2l0aWdub3JlXCIgaXMgZGlzYWJsZWQsIHNvIGl0IGRvZXMgbm90IG1ha2Ugc2Vuc2UgdG8gc3BlY2lmeSBcImNvbW1pdHRlZFwiJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjbGFzc2VzIGFuZCByZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSB0b1xuICAgKiBlbWl0LlxuICAgKiBAcGFyYW0gcmVzb2x2ZXIgQ2FsbCBgcmVzb2x2ZXIucmVzb2x2ZShvYmopYCBvbiBhbnkgb2JqZWN0cyBpbiBvcmRlciB0b1xuICAgKiByZXNvbHZlIHRva2VuIGZ1bmN0aW9ucy5cbiAgICogQHJldHVybnMgdGhlIGNvbnRlbnQgdG8gc3ludGhlc2l6ZSBvciB1bmRlZmluZWQgdG8gc2tpcCB0aGUgZmlsZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHN5bnRoZXNpemVDb250ZW50KHJlc29sdmVyOiBJUmVzb2x2ZXIpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdyaXRlcyB0aGUgZmlsZSB0byB0aGUgcHJvamVjdCdzIG91dHB1dCBkaXJlY3RvcnlcbiAgICovXG4gIHB1YmxpYyBzeW50aGVzaXplKCkge1xuICAgIGNvbnN0IG91dGRpciA9IHRoaXMucHJvamVjdC5vdXRkaXI7XG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4ob3V0ZGlyLCB0aGlzLnBhdGgpO1xuICAgIGNvbnN0IHJlc29sdmVyOiBJUmVzb2x2ZXIgPSB7XG4gICAgICByZXNvbHZlOiAob2JqLCBvcHRpb25zKSA9PiByZXNvbHZlKG9iaiwgb3B0aW9ucyksXG4gICAgfTtcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5zeW50aGVzaXplQ29udGVudChyZXNvbHZlcik7XG4gICAgaWYgKGNvbnRlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gcmVtb3ZlIGZpbGUgKGlmIGV4aXN0cykgYW5kIHNraXAgcmVzdCBvZiBzeW50aGVzaXNcbiAgICAgIHJtU3luYyhmaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIHRoZSBmaWxlIHdhcyBjaGFuZ2VkLlxuICAgIGNvbnN0IHByZXYgPSB0cnlSZWFkRmlsZVN5bmMoZmlsZVBhdGgpO1xuICAgIHRoaXMuX3ByZXZpb3VzQ29udGVudCA9IHByZXY7XG4gICAgdGhpcy5fbmV3Q29udGVudCA9IGNvbnRlbnQ7XG4gICAgY29uc3QgcHJldlJlYWRvbmx5ID0gIWlzV3JpdGFibGUoZmlsZVBhdGgpO1xuICAgIGNvbnN0IHN1Y2Nlc3NmdWxFeGVjdXRhYmxlQXNzZXJ0aW9uID0gYXNzZXJ0RXhlY3V0YWJsZVBlcm1pc3Npb25zKFxuICAgICAgZmlsZVBhdGgsXG4gICAgICB0aGlzLmV4ZWN1dGFibGUsXG4gICAgKTtcbiAgICBpZiAoXG4gICAgICBwcmV2ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGNvbnRlbnQgPT09IHByZXYgJiZcbiAgICAgIHByZXZSZWFkb25seSA9PT0gdGhpcy5yZWFkb25seSAmJlxuICAgICAgc3VjY2Vzc2Z1bEV4ZWN1dGFibGVBc3NlcnRpb25cbiAgICApIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIudmVyYm9zZShgbm8gY2hhbmdlIGluICR7ZmlsZVBhdGh9YCk7XG4gICAgICB0aGlzLl9jaGFuZ2VkID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd3JpdGVGaWxlKGZpbGVQYXRoLCBjb250ZW50LCB7XG4gICAgICByZWFkb25seTogdGhpcy5yZWFkb25seSxcbiAgICAgIGV4ZWN1dGFibGU6IHRoaXMuZXhlY3V0YWJsZSxcbiAgICB9KTtcblxuICAgIHRoaXMuY2hlY2tGb3JQcm9qZW5NYXJrZXIoKTtcblxuICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvciBkZWJ1Z2dpbmcsIGNoZWNrIHdoZXRoZXIgYSBmaWxlIHdhcyBpbmNvcnJlY3RseSBnZW5lcmF0ZWQgd2l0aFxuICAgKiBvciB3aXRob3V0IHRoZSBwcm9qZW4gbWFya2VyLiBUaGUgcHJvamVuIG1hcmtlciBkb2VzIG5vdCAqbmVlZCogdG8gYmVcbiAgICogaW5jbHVkZWQgb24gcHJvamVuLWdlbmVyYXRlZCBmaWxlcywgYnV0IGl0J3MgcmVjb21tZW5kZWQgc2luY2UgaXQgc2lnbmFsc1xuICAgKiB0aGF0IGl0IHByb2JhYmx5IHNob3VsZCBub3QgYmUgZWRpdGVkIGRpcmVjdGx5LlxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja0ZvclByb2plbk1hcmtlcigpIHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbih0aGlzLnByb2plY3Qub3V0ZGlyLCB0aGlzLnBhdGgpO1xuICAgIGNvbnN0IGNvbnRlbnRzID0gdHJ5UmVhZEZpbGVTeW5jKGZpbGVQYXRoKTtcbiAgICBjb25zdCBjb250YWluc01hcmtlciA9IGNvbnRlbnRzPy5pbmNsdWRlcyhQUk9KRU5fTUFSS0VSKTtcbiAgICBpZiAodGhpcy5tYXJrZXIgJiYgIWNvbnRhaW5zTWFya2VyKSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgbm90ZTogZXhwZWN0ZWQgJHt0aGlzLnBhdGh9IHRvIGNvbnRhaW4gbWFya2VyIGJ1dCBmb3VuZCBub25lLmAsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMubWFya2VyICYmIGNvbnRhaW5zTWFya2VyKSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgbm90ZTogZXhwZWN0ZWQgJHt0aGlzLnBhdGh9IHRvIG5vdCBjb250YWluIG1hcmtlciBidXQgZm91bmQgb25lIGFueXdheS5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIGlmIHRoZSBmaWxlIGhhcyBiZWVuIGNoYW5nZWQgZHVyaW5nIHN5bnRoZXNpcy4gVGhpcyBwcm9wZXJ0eSBpc1xuICAgKiBvbmx5IGF2YWlsYWJsZSBpbiBgcG9zdFN5bnRoZXNpemUoKWAgaG9va3MuIElmIHRoaXMgaXMgYHVuZGVmaW5lZGAsIHRoZVxuICAgKiBmaWxlIGhhcyBub3QgYmVlbiBzeW50aGVzaXplZCB5ZXQuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNoYW5nZWQoKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2NoYW5nZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHVuaWZpZWQgZGlmZiBvZiB0aGUgb2xkIGFuZCBuZXcgZmlsZSBjb250ZW50cyB3aXRoIGNvbnRleHQgbGluZXNcbiAgICogYW5kIGh1bmsgaGVhZGVycy4gT25seSBhdmFpbGFibGUgYWZ0ZXIgc3ludGhlc2lzLlxuICAgKlxuICAgKiBUaGlzIGlzIGFuIGV4cGVuc2l2ZSBvcGVyYXRpb24gYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgb24gbm9uIHRpbWUtY3JpdGljYWxcbiAgICogY29kZSBwYXRocywgbGlrZSBkZWJ1ZyBvdXRwdXQuXG4gICAqXG4gICAqIEBwYXJhbSBjb2xvcml6ZSBXaGV0aGVyIHRvIGNvbG9yaXplIHRoZSBkaWZmIG91dHB1dC4gQGRlZmF1bHQgZmFsc2VcbiAgICogQHBhcmFtIGNvbnRleHRMaW5lcyBOdW1iZXIgb2YgY29udGV4dCBsaW5lcyBhcm91bmQgY2hhbmdlcy4gQGRlZmF1bHQgM1xuICAgKiBAcmV0dXJucyB0aGUgZGlmZiBhcyBhbiBhcnJheSBvZiBsaW5lcywgb3IgYHVuZGVmaW5lZGAgaWYgdGhlIGZpbGUgd2FzXG4gICAqIG5vdCBjaGFuZ2VkIG9yIGhhcyBub3QgYmVlbiBzeW50aGVzaXplZCB5ZXQuXG4gICAqL1xuICBwdWJsaWMgZGlmZihjb2xvcml6ZSA9IGZhbHNlLCBjb250ZXh0TGluZXMgPSAzKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5fY2hhbmdlZCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pZmllZERpZmYoXG4gICAgICB0aGlzLl9wcmV2aW91c0NvbnRlbnQgPz8gXCJcIixcbiAgICAgIHRoaXMuX25ld0NvbnRlbnQgPz8gXCJcIixcbiAgICAgIGNvbG9yaXplLFxuICAgICAgY29udGV4dExpbmVzLFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBBUEkgZm9yIHJlc29sdmluZyB0b2tlbnMgd2hlbiBzeW50aGVzaXppbmcgZmlsZSBjb250ZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElSZXNvbHZlciB7XG4gIC8qKlxuICAgKiBHaXZlbiBhIHZhbHVlIChvYmplY3Qvc3RyaW5nL2FycmF5L3doYXRldmVyLCBsb29rcyB1cCBhbnkgZnVuY3Rpb25zIGluc2lkZVxuICAgKiB0aGUgb2JqZWN0IGFuZCByZXR1cm5zIGFuIG9iamVjdCB3aGVyZSBhbGwgZnVuY3Rpb25zIGFyZSBjYWxsZWQuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmVzb2x2ZVxuICAgKiBAcGFja2FnZSBvcHRpb25zIFJlc29sdmUgb3B0aW9uc1xuICAgKi9cbiAgcmVzb2x2ZSh2YWx1ZTogYW55LCBvcHRpb25zPzogUmVzb2x2ZU9wdGlvbnMpOiBhbnk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBvcHRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVPcHRpb25zIHtcbiAgLyoqXG4gICAqIE9taXRzIGVtcHR5IGFycmF5cyBhbmQgb2JqZWN0cy5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IG9taXRFbXB0eT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENvbnRleHQgYXJndW1lbnRzLlxuICAgKiBAZGVmYXVsdCBbXVxuICAgKi9cbiAgcmVhZG9ubHkgYXJncz86IGFueVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElSZXNvbHZhYmxlIHtcbiAgLyoqXG4gICAqIFJlc29sdmVzIGFuZCByZXR1cm5zIGNvbnRlbnQuXG4gICAqL1xuICB0b0pTT04oKTogYW55O1xufVxuIl19