482 lines
64 KiB
JavaScript
482 lines
64 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.partial = exports.Nested = exports.MergeIntersect = exports.deepPartial = exports.PartialStruct = exports.allowMissing = exports.optional = exports.exact = exports.subtype = exports.Struct = exports.allowsOptional = exports.allowsMissing = exports.keyType = exports.dict = exports.Dict = exports.OptionalKey = exports.MissingKey = void 0;
|
|
const result_1 = require("../result");
|
|
const type_1 = require("../type");
|
|
/*
|
|
* MissingKey is a marker type that indicates that the key in a struct that holds an MissingKey is
|
|
* optional. However, if the key is present, the value must typecheck T; it can't be left undefined.
|
|
* This can be useful for verification but it's not equivalent to TypeScript's optional fields,
|
|
* which can be left undefined even when present.
|
|
*/
|
|
class MissingKey {
|
|
constructor(type) {
|
|
this.type = type;
|
|
}
|
|
}
|
|
exports.MissingKey = MissingKey;
|
|
/*
|
|
* OptionalKey mimics TypeScript's ?: optional field syntax in types/interfaces: it allows the key
|
|
* to be missing, or set to undefined.
|
|
*/
|
|
class OptionalKey {
|
|
constructor(type) {
|
|
this.type = type;
|
|
}
|
|
}
|
|
exports.OptionalKey = OptionalKey;
|
|
class MergeableType extends type_1.CustomCommutativeAndType {
|
|
and(type) {
|
|
if (type instanceof MergeableType) {
|
|
// @ts-ignore
|
|
return new MergeIntersect(this, type);
|
|
}
|
|
else if (type instanceof type_1.Either) {
|
|
return new type_1.Either(this.and(type.l), this.and(type.r));
|
|
}
|
|
else if (type instanceof type_1.DefaultIntersect) {
|
|
return new type_1.DefaultIntersect(this.and(type.l), this.and(type.r));
|
|
}
|
|
else if (type instanceof type_1.Comment) {
|
|
return new type_1.Comment(type.commentStr, this.and(type.wrapped));
|
|
}
|
|
return super.and(type);
|
|
}
|
|
}
|
|
// Dicts and structs merge together in TypeScript, so we put both in the struct file
|
|
class Dict extends MergeableType {
|
|
constructor(v, namedKey = "key") {
|
|
super();
|
|
this.namedKey = namedKey;
|
|
this.valueType = v;
|
|
}
|
|
keyName(key) {
|
|
return new Dict(this.valueType, key);
|
|
}
|
|
check(val) {
|
|
const err = basicDictErrs(val);
|
|
if (err)
|
|
return err;
|
|
for (const prop in val) {
|
|
const result = this.valueType.check(val[prop]);
|
|
if (result instanceof result_1.Err)
|
|
return new result_1.Err(`[${prop}]: ${result.message}`);
|
|
}
|
|
return val;
|
|
}
|
|
sliceResult(val) {
|
|
const err = basicDictErrs(val);
|
|
if (err)
|
|
return err;
|
|
const result = {};
|
|
for (const prop in val) {
|
|
const sliced = this.valueType.sliceResult(val[prop]);
|
|
if (sliced instanceof result_1.Err)
|
|
return new result_1.Err(`[${prop}]: ${result.message}`);
|
|
result[prop] = sliced;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
exports.Dict = Dict;
|
|
function basicDictErrs(val) {
|
|
if (typeof val !== 'object')
|
|
return new result_1.Err(`${val} is not an object`);
|
|
if (Array.isArray(val))
|
|
return new result_1.Err(`${val} is an array`);
|
|
if (val === null)
|
|
return new result_1.Err(`${val} is null`);
|
|
return null;
|
|
}
|
|
function dict(v) {
|
|
return new Dict(v);
|
|
}
|
|
exports.dict = dict;
|
|
function keyType(box) {
|
|
if (box instanceof MissingKey || box instanceof OptionalKey) {
|
|
return box.type;
|
|
}
|
|
return box;
|
|
}
|
|
exports.keyType = keyType;
|
|
function allowsMissing(box) {
|
|
return (box instanceof MissingKey);
|
|
}
|
|
exports.allowsMissing = allowsMissing;
|
|
function allowsOptional(box) {
|
|
return (box instanceof OptionalKey);
|
|
}
|
|
exports.allowsOptional = allowsOptional;
|
|
class Struct extends MergeableType {
|
|
constructor(definition, exact) {
|
|
super();
|
|
this.definition = definition;
|
|
this.exact = exact;
|
|
}
|
|
check(val) {
|
|
const typeErr = this.checkType(val);
|
|
if (typeErr)
|
|
return typeErr;
|
|
const errs = this.checkFields(val, (t, val) => t.check(val));
|
|
if (errs.length === 0)
|
|
return val;
|
|
return new result_1.Err(`${val} failed the following checks:\n${errs.join('\n')}`);
|
|
}
|
|
sliceResult(val) {
|
|
const typeErr = this.checkType(val);
|
|
if (typeErr)
|
|
return typeErr;
|
|
const sliced = {};
|
|
const errs = this.checkFields(val, (t, val) => t.sliceResult(val), (key, val) => {
|
|
sliced[key] = val;
|
|
});
|
|
if (errs.length === 0)
|
|
return sliced;
|
|
return new result_1.Err(`${val} failed the following checks:\n${errs.join('\n')}`);
|
|
}
|
|
checkType(val) {
|
|
if (typeof val !== 'object')
|
|
return new result_1.Err(`${val} is not an object`);
|
|
if (Array.isArray(val))
|
|
return new result_1.Err(`${val} is an array`);
|
|
if (val === null)
|
|
return new result_1.Err(`${val} is null`);
|
|
return undefined;
|
|
}
|
|
checkFields(val, checkFn, collect) {
|
|
const errs = [];
|
|
for (const prop in this.definition) {
|
|
const field = this.definition[prop];
|
|
if (!(prop in val)) {
|
|
if (allowsMissing(field))
|
|
continue;
|
|
if (allowsOptional(field))
|
|
continue;
|
|
errs.push(`missing key '${prop}'`);
|
|
continue;
|
|
}
|
|
const valField = val[prop];
|
|
if (valField === undefined && allowsOptional(field)) {
|
|
if (collect)
|
|
collect(prop, undefined);
|
|
continue;
|
|
}
|
|
const result = checkFn(keyType(field), valField);
|
|
if (result instanceof result_1.Err)
|
|
errs.push(result.message);
|
|
if (collect)
|
|
collect(prop, result);
|
|
}
|
|
if (this.exact && typeof val === 'object') {
|
|
for (const prop in val) {
|
|
if (!(prop in this.definition)) {
|
|
errs.push(`unknown key ${prop}`);
|
|
}
|
|
}
|
|
}
|
|
return errs;
|
|
}
|
|
}
|
|
exports.Struct = Struct;
|
|
function subtype(def) {
|
|
return new Struct(def, false);
|
|
}
|
|
exports.subtype = subtype;
|
|
function exact(def) {
|
|
return new Struct(def, true);
|
|
}
|
|
exports.exact = exact;
|
|
function optional(check) {
|
|
return new OptionalKey(check);
|
|
}
|
|
exports.optional = optional;
|
|
function allowMissing(check) {
|
|
return new MissingKey(check);
|
|
}
|
|
exports.allowMissing = allowMissing;
|
|
class PartialStruct extends MergeableType {
|
|
constructor(struct) {
|
|
super();
|
|
this.struct = struct;
|
|
const partialDef = {};
|
|
for (const k in struct.definition) {
|
|
const v = struct.definition[k];
|
|
if (v instanceof MissingKey) {
|
|
//@ts-ignore
|
|
partialDef[k] = optional(v.type);
|
|
}
|
|
else if (v instanceof OptionalKey) {
|
|
//@ts-ignore
|
|
partialDef[k] = optional(v.type);
|
|
}
|
|
else {
|
|
//@ts-ignore
|
|
partialDef[k] = optional(v);
|
|
}
|
|
}
|
|
this.hiddenTypeStruct = partialDef;
|
|
this.hiddenStruct = new Struct(this.hiddenTypeStruct, struct.exact);
|
|
}
|
|
check(val) {
|
|
return this.hiddenStruct.check(val);
|
|
}
|
|
sliceResult(val) {
|
|
return this.hiddenStruct.sliceResult(val);
|
|
}
|
|
reify() {
|
|
return new Struct(this.hiddenTypeStruct, this.hiddenStruct.exact);
|
|
}
|
|
}
|
|
exports.PartialStruct = PartialStruct;
|
|
function deepPartial(ogstruct) {
|
|
// If the original struct isn't nested, it's just an ordinary partial call. Don't modify the
|
|
// definition, or else when you convert to TypeScript it won't correctly ref out the struct
|
|
if (!hasNested(ogstruct)) {
|
|
// @ts-ignore
|
|
return partial(ogstruct);
|
|
}
|
|
// If we got this far, the struct has nesting, and therefore can't simply be ref-ed out when
|
|
// converting to TypeScript. We must modify it recursively.
|
|
const partialDef = {};
|
|
for (const k in ogstruct.definition) {
|
|
const v = ogstruct.definition[k];
|
|
if (v instanceof MissingKey) {
|
|
//@ts-ignore
|
|
partialDef[k] = new MissingKey(v.type);
|
|
}
|
|
else if (v instanceof OptionalKey) {
|
|
//@ts-ignore
|
|
partialDef[k] = optional(v.type);
|
|
}
|
|
else {
|
|
const deepKind = deepPartialKind(v);
|
|
// @ts-ignore
|
|
partialDef[k] = deepKind;
|
|
}
|
|
}
|
|
const struct = new Struct(partialDef, ogstruct.exact);
|
|
return new PartialStruct(struct);
|
|
}
|
|
exports.deepPartial = deepPartial;
|
|
class MergeIntersect extends MergeableType {
|
|
constructor(l, r) {
|
|
super();
|
|
this.l = l;
|
|
this.r = r;
|
|
this.merged = merge(l, {
|
|
dict: l => this.mergeDictAndMergeable(l, r),
|
|
struct: l => this.mergeStructAndMergeable(l, r),
|
|
partial: l => this.mergeStructAndMergeable(l.reify(), r),
|
|
merge: l => this.mergeIntersectAndMergeable(l, r),
|
|
internal: () => {
|
|
throw `leaked internal dict/struct merge class; structural error`;
|
|
},
|
|
});
|
|
}
|
|
check(val) {
|
|
return this.merged.check(val);
|
|
}
|
|
sliceResult(val) {
|
|
return this.merged.sliceResult(val);
|
|
}
|
|
mergeDictAndMergeable(d, m) {
|
|
return merge(m, {
|
|
dict: (m) => this.mergeDicts(d, m),
|
|
partial: (m) => new InternalDictStructMerge(m.reify(), d),
|
|
struct: (m) => this.mergeDictAndStruct(d, m),
|
|
merge: (m) => this.mergeDictAndMergeable(d, m.merged),
|
|
internal: (m) => this.mergeInternalAndDict(m, d),
|
|
});
|
|
}
|
|
mergeStructAndMergeable(s, m) {
|
|
return merge(m, {
|
|
dict: m => this.mergeDictAndStruct(m, s),
|
|
partial: m => this.mergeStructs(s, m.reify()),
|
|
struct: m => this.mergeStructs(s, m),
|
|
merge: m => this.mergeStructAndMergeable(s, m.merged),
|
|
internal: m => this.mergeInternalAndStruct(m, s),
|
|
});
|
|
}
|
|
mergePartialAndMergeable(p, m) {
|
|
return merge(m, {
|
|
dict: m => new InternalDictStructMerge(p.reify(), m),
|
|
partial: m => this.mergeStructs(p.reify(), m.reify()),
|
|
struct: m => this.mergeStructs(p.reify(), m),
|
|
merge: m => this.mergePartialAndMergeable(p, m.merged),
|
|
internal: m => this.mergeInternalAndStruct(m, p.reify()),
|
|
});
|
|
}
|
|
mergeIntersectAndMergeable(i, m) {
|
|
return merge(m, {
|
|
dict: m => this.mergeDictAndMergeable(m, i.merged),
|
|
partial: m => this.mergePartialAndMergeable(m, i.merged),
|
|
struct: m => this.mergeStructAndMergeable(m, i.merged),
|
|
merge: m => this.mergeIntersectAndMergeable(m, i.merged),
|
|
internal: m => this.mergeInternalAndIntersect(m, i),
|
|
});
|
|
}
|
|
mergeInternalAndDict(l, r) {
|
|
return new InternalDictStructMerge(l.s, this.mergeDicts(l.d, r));
|
|
}
|
|
mergeInternalAndStruct(l, r) {
|
|
return new InternalDictStructMerge(this.mergeStructs(l.s, r), l.d);
|
|
}
|
|
mergeInternalAndIntersect(l, r) {
|
|
return merge(r.merged, {
|
|
dict: merged => this.mergeInternalAndDict(l, merged),
|
|
partial: merged => this.mergeInternalAndStruct(l, merged.reify()),
|
|
struct: merged => this.mergeInternalAndStruct(l, merged),
|
|
merge: () => {
|
|
throw `MergeIntersect can't be a child of a MergeIntersect; structural internal error`;
|
|
},
|
|
internal: merged => this.mergeInternalAndInternal(l, merged),
|
|
});
|
|
}
|
|
mergeInternalAndInternal(l, r) {
|
|
return new InternalDictStructMerge(this.mergeStructs(l.s, r.s), this.mergeDicts(l.d, r.d));
|
|
}
|
|
mergeDicts(l, r) {
|
|
return dict(l.valueType.and(r.valueType));
|
|
}
|
|
mergeDictAndStruct(l, r) {
|
|
return new InternalDictStructMerge(r, l);
|
|
}
|
|
mergeStructs(l, r) {
|
|
const definition = {};
|
|
for (const prop in l.definition) {
|
|
definition[prop] = l.definition[prop];
|
|
}
|
|
for (const prop in r.definition) {
|
|
const existing = definition[prop];
|
|
const merging = r.definition[prop];
|
|
// If it's an additional key, slap it in
|
|
if (existing == null)
|
|
definition[prop] = r.definition[prop];
|
|
// If it's a missing key, handle
|
|
else if (existing instanceof MissingKey) {
|
|
// Missing keys are stricter than optional, so both converge to missing key
|
|
if (merging instanceof MissingKey || merging instanceof OptionalKey) {
|
|
definition[prop] = new MissingKey(existing.type.and(merging.type));
|
|
}
|
|
// The strictest is just a raw type, so unwrap and merge
|
|
else {
|
|
definition[prop] = existing.type.and(merging);
|
|
}
|
|
}
|
|
// If it's an optional key, handle
|
|
else if (existing instanceof OptionalKey) {
|
|
// Missing key is stricter than optional, so it wins
|
|
if (merging instanceof MissingKey) {
|
|
definition[prop] = new MissingKey(existing.type.and(merging.type));
|
|
}
|
|
// Two optionals merge into an optional
|
|
else if (merging instanceof OptionalKey) {
|
|
definition[prop] = new OptionalKey(existing.type.and(merging.type));
|
|
}
|
|
// A raw type is stricter than optional, so it unwraps the optionality
|
|
else {
|
|
definition[prop] = existing.type.and(merging);
|
|
}
|
|
}
|
|
else {
|
|
// Raw types are stricter than missing or optional types
|
|
if (merging instanceof MissingKey || merging instanceof OptionalKey) {
|
|
definition[prop] = existing.and(merging.type);
|
|
}
|
|
// Finally, merging two raw types
|
|
else {
|
|
definition[prop] = existing.and(merging);
|
|
}
|
|
}
|
|
}
|
|
return new Struct(definition, l.exact && r.exact);
|
|
}
|
|
}
|
|
exports.MergeIntersect = MergeIntersect;
|
|
function merge(i, handlers) {
|
|
if (i instanceof Dict)
|
|
return handlers.dict(i);
|
|
if (i instanceof PartialStruct)
|
|
return handlers.partial(i);
|
|
if (i instanceof Struct)
|
|
return handlers.struct(i);
|
|
if (i instanceof MergeIntersect)
|
|
return handlers.merge(i);
|
|
if (i instanceof InternalDictStructMerge)
|
|
return handlers.internal(i);
|
|
throw `Unknown type ${i}`;
|
|
}
|
|
class InternalDictStructMerge extends type_1.Type {
|
|
constructor(s, d) {
|
|
super();
|
|
this.d = d;
|
|
this.s = new Struct(s.definition, false);
|
|
}
|
|
check(val) {
|
|
const dResult = this.d.check(val);
|
|
if (dResult instanceof result_1.Err)
|
|
return dResult;
|
|
const sResult = this.s.check(val);
|
|
if (sResult instanceof result_1.Err)
|
|
return sResult;
|
|
return val;
|
|
}
|
|
sliceResult(val) {
|
|
const dResult = this.d.sliceResult(val);
|
|
if (dResult instanceof result_1.Err)
|
|
return dResult;
|
|
const sResult = this.s.sliceResult(val);
|
|
return Object.assign({}, dResult, sResult);
|
|
}
|
|
}
|
|
exports.Nested = [
|
|
Struct,
|
|
PartialStruct,
|
|
Dict,
|
|
type_1.Either,
|
|
type_1.DefaultIntersect,
|
|
MergeIntersect,
|
|
type_1.Comment,
|
|
];
|
|
function deepPartialKind(kind) {
|
|
if (isNested(kind))
|
|
return handleNested(kind);
|
|
return kind;
|
|
}
|
|
function handleNested(kind) {
|
|
if (kind instanceof Struct) {
|
|
if (hasNested(kind))
|
|
return deepPartial(kind);
|
|
return new PartialStruct(kind);
|
|
}
|
|
if (kind instanceof PartialStruct)
|
|
return deepPartial(kind.struct);
|
|
if (kind instanceof type_1.Comment)
|
|
return new type_1.Comment(kind.commentStr, deepPartialKind(kind.wrapped));
|
|
if (kind instanceof Dict)
|
|
return new Dict(deepPartialKind(kind.valueType), kind.namedKey);
|
|
if (kind instanceof type_1.Either)
|
|
return new type_1.Either(deepPartialKind(kind.l), deepPartialKind(kind.r));
|
|
if (kind instanceof MergeIntersect)
|
|
return new type_1.DefaultIntersect(deepPartialKind(kind.l), deepPartialKind(kind.r));
|
|
return new type_1.DefaultIntersect(deepPartialKind(kind.l), deepPartialKind(kind.r));
|
|
}
|
|
function isNested(kind) {
|
|
for (const t of exports.Nested) {
|
|
if (kind instanceof t)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function hasNested(struct) {
|
|
for (const k in struct.definition) {
|
|
if (isNested(struct.definition[k]))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function partial(struct) {
|
|
return new PartialStruct(struct);
|
|
}
|
|
exports.partial = partial;
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RydWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2NoZWNrcy9zdHJ1Y3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0NBQXdDO0FBQ3hDLGtDQUE0RjtBQUc1Rjs7Ozs7R0FLRztBQUNILE1BQWEsVUFBVTtJQUNyQixZQUFxQixJQUFPO1FBQVAsU0FBSSxHQUFKLElBQUksQ0FBRztJQUFHLENBQUM7Q0FDakM7QUFGRCxnQ0FFQztBQUVEOzs7R0FHRztBQUNILE1BQWEsV0FBVztJQUN0QixZQUFxQixJQUFPO1FBQVAsU0FBSSxHQUFKLElBQUksQ0FBRztJQUFHLENBQUM7Q0FDakM7QUFGRCxrQ0FFQztBQVNELE1BQWUsYUFBaUIsU0FBUSwrQkFBMkI7SUFDakUsR0FBRyxDQUFXLElBQW9CO1FBQ2hDLElBQUcsSUFBSSxZQUFZLGFBQWEsRUFBRSxDQUFDO1lBQ2pDLGFBQWE7WUFDYixPQUFPLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN4QyxDQUFDO2FBQ0ksSUFBRyxJQUFJLFlBQVksYUFBTSxFQUFFLENBQUM7WUFDL0IsT0FBTyxJQUFJLGFBQU0sQ0FDZixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQ2pCLENBQUM7UUFDSixDQUFDO2FBQ0ksSUFBRyxJQUFJLFlBQVksdUJBQWdCLEVBQUUsQ0FBQztZQUN6QyxPQUFPLElBQUksdUJBQWdCLENBQ3pCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDakIsQ0FBQztRQUNKLENBQUM7YUFDSSxJQUFHLElBQUksWUFBWSxjQUFPLEVBQUUsQ0FBQztZQUNoQyxPQUFPLElBQUksY0FBTyxDQUFDLElB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QUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvRixJQUFHLElBQUksWUFBWSxjQUFjO1FBQUUsT0FBTyxJQUFJLHVCQUFnQixDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pILE9BQU8sSUFBSSx1QkFBZ0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsSUFBNEI7SUFDNUMsS0FBSSxNQUFNLENBQUMsSUFBSSxjQUFNLEVBQUUsQ0FBQztRQUN0QixJQUFHLElBQUksWUFBWSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7SUFDcEMsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLE1BQW1CO0lBQ3BDLEtBQUksTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2pDLElBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBZ0IsT0FBTyxDQUF1QixNQUFpQjtJQUM3RCxPQUFPLElBQUksYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFGRCwwQkFFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVyciwgUmVzdWx0IH0gZnJvbSBcIi4uL3Jlc3VsdFwiO1xuaW1wb3J0IHsgVHlwZSwgQ3VzdG9tQ29tbXV0YXRpdmVBbmRUeXBlLCBFaXRoZXIsIERlZmF1bHRJbnRlcnNlY3QsIENvbW1lbnQgfSBmcm9tIFwiLi4vdHlwZVwiO1xuaW1wb3J0IHsgR2V0VHlwZSB9IGZyb20gXCIuLi9nZXQtdHlwZVwiO1xuXG4vKlxuICogTWlzc2luZ0tleSBpcyBhIG1hcmtlciB0eXBlIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIGtleSBpbiBhIHN0cnVjdCB0aGF0IGhvbGRzIGFuIE1pc3NpbmdLZXkgaXNcbiAqIG9wdGlvbmFsLiBIb3dldmVyLCBpZiB0aGUga2V5IGlzIHByZXNlbnQsIHRoZSB2YWx1ZSBtdXN0IHR5cGVjaGVjayBUOyBpdCBjYW4ndCBiZSBsZWZ0IHVuZGVmaW5lZC5cbiAqIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgdmVyaWZpY2F0aW9uIGJ1dCBpdCdzIG5vdCBlcXVpdmFsZW50IHRvIFR5cGVTY3JpcHQncyBvcHRpb25hbCBmaWVsZHMsXG4gKiB3aGljaCBjYW4gYmUgbGVmdCB1bmRlZmluZWQgZXZlbiB3aGVuIHByZXNlbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNaXNzaW5nS2V5PFQgZXh0ZW5kcyBUeXBlPGFueT4+IHtcbiAgY29uc3RydWN0b3IocmVhZG9ubHkgdHlwZTogVCkge31cbn1cblxuLypcbiAqIE9wdGlvbmFsS2V5IG1pbWljcyBUeXBlU2NyaXB0J3MgPzogb3B0aW9uYWwgZmllbGQgc3ludGF4IGluIHR5cGVzL2ludGVyZmFjZXM6IGl0IGFsbG93cyB0aGUga2V5XG4gKiB0byBiZSBtaXNzaW5nLCBvciBzZXQgdG8gdW5kZWZpbmVkLlxuICovXG5leHBvcnQgY2xhc3MgT3B0aW9uYWxLZXk8VCBleHRlbmRzIFR5cGU8YW55Pj4ge1xuICBjb25zdHJ1Y3RvcihyZWFkb25seSB0eXBlOiBUKSB7fVxufVxuXG50eXBlIFdyYXBwZXJPclR5cGU8VD4gPSBUIGV4dGVuZHMgTWlzc2luZ0tleTxpbmZlciBJbm5lcj4gPyBJbm5lciA6XG4gIFQgZXh0ZW5kcyBPcHRpb25hbEtleTxpbmZlciBJbm5lcj4gPyBJbm5lciA6IFQ7XG5cbnR5cGUgUmF3RGljdDxWPiA9IHtcbiAgW2tleTogc3RyaW5nXTogVjtcbn07XG5cbmFic3RyYWN0IGNsYXNzIE1lcmdlYWJsZVR5cGU8VD4gZXh0ZW5kcyBDdXN0b21Db21tdXRhdGl2ZUFuZFR5cGU8VD4ge1xuICBhbmQ8SW5jb21pbmc+KHR5cGU6IFR5cGU8SW5jb21pbmc+KTogVHlwZTxUICYgSW5jb21pbmc+IHtcbiAgICBpZih0eXBlIGluc3RhbmNlb2YgTWVyZ2VhYmxlVHlwZSkge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgcmV0dXJuIG5ldyBNZXJnZUludGVyc2VjdCh0aGlzLCB0eXBlKTtcbiAgICB9XG4gICAgZWxzZSBpZih0eXBlIGluc3RhbmNlb2YgRWl0aGVyKSB7XG4gICAgICByZXR1cm4gbmV3IEVpdGhlcihcbiAgICAgICAgdGhpcy5hbmQodHlwZS5sKSxcbiAgICAgICAgdGhpcy5hbmQodHlwZS5yKSxcbiAgICAgICk7XG4gICAgfVxuICAgIGVsc2UgaWYodHlwZSBpbnN0YW5jZW9mIERlZmF1bHRJbnRlcnNlY3QpIHtcbiAgICAgIHJldHVybiBuZXcgRGVmYXVsdEludGVyc2VjdChcbiAgICAgICAgdGhpcy5hbmQodHlwZS5sKSxcbiAgICAgICAgdGhpcy5hbmQodHlwZS5yKSxcbiAgICAgICk7XG4gICAgfVxuICAgIGVsc2UgaWYodHlwZSBpbnN0YW5jZW9mIENvbW1lbnQpIHtcbiAgICAgIHJldHVybiBuZXcgQ29tbWVudCh0eXBlLmNvbW1lbnRTdHIsIHRoaXMuYW5kKHR5cGUud3JhcHBlZCkpO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuYW5kKHR5cGUpO1xuICB9XG59XG5cbi8vIERpY3RzIGFuZCBzdHJ1Y3RzIG1lcmdlIHRvZ2V0aGVyIGluIFR5cGVTY3JpcHQsIHNvIHdlIHB1dCBib3RoIGluIHRoZSBzdHJ1Y3QgZmlsZVxuZXhwb3J0IGNsYXNzIERpY3Q8Vj4gZXh0ZW5kcyBNZXJnZWFibGVUeXBlPFJhd0RpY3Q8Vj4+IHtcbiAgcmVhZG9ubHkgdmFsdWVUeXBlOiBUeXBlPFY+O1xuICBjb25zdHJ1Y3Rvcih2OiBUeXBlPFY+LCByZWFkb25seSBuYW1lZEtleTogc3RyaW5nID0gXCJrZXlcIikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy52YWx1ZVR5cGUgPSB2O1xuICB9XG5cbiAga2V5TmFtZShrZXk6IHN0cmluZyk6IERpY3Q8Vj4ge1xuICAgIHJldHVybiBuZXcgRGljdCh0aGlzLnZhbHVlVHlwZSwga2V5KTtcbiAgfVxuXG4gIGNoZWNrKHZhbDogYW55KTogUmVzdWx0PFJhd0RpY3Q8Vj4+IHtcbiAgICBjb25zdCBlcnIgPSBiYXNpY0RpY3RFcnJzKHZhbCk7XG4gICAgaWYoZXJyKSByZXR1cm4gZXJyO1xuXG4gICAgZm9yKGNvbnN0IHByb3AgaW4gdmFsKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnZhbHVlVHlwZS5jaGVjayh2YWxbcHJvcF0pO1xuICAgICAgaWYocmVzdWx0IGluc3RhbmNlb2YgRXJyKSByZXR1cm4gbmV3IEVycihgWyR7cHJvcH1dOiAke3Jlc3VsdC5tZXNzYWdlfWApO1xuICAgIH1cblxuICAgIHJldHVybiB2YWwgYXMgUmVzdWx0PFJhd0RpY3Q8Vj4+O1xuICB9XG5cbiAgc2xpY2VSZXN1bHQodmFsOiBhbnkpOiBSZXN1bHQ8UmF3RGljdDxWPj4ge1xuICAgIGNvbnN0IGVyciA9IGJhc2ljRGljdEVycnModmFsKTtcbiAgICBpZihlcnIpIHJldHVybiBlcnI7XG5cbiAgICBjb25zdCByZXN1bHQ6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fTtcbiAgICBmb3IoY29uc3QgcHJvcCBpbiB2YWwpIHtcbiAgICAgIGNvbnN0IHNsaWNlZCA9IHRoaXMudmFsdWVUeXBlLnNsaWNlUmVzdWx0KHZhbFtwcm9wXSk7XG4gICAgICBpZihzbGljZWQgaW5zdGFuY2VvZiBFcnIpIHJldHVybiBuZXcgRXJyKGBbJHtwcm9wfV06ICR7cmVzdWx0Lm1lc3NhZ2V9YCk7XG4gICAgICByZXN1bHRbcHJvcF0gPSBzbGljZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdCBhcyBSZXN1bHQ8UmF3RGljdDxWPj47XG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzaWNEaWN0RXJyczxWPih2YWw6IGFueSk6IEVycjxWPiB8IG51bGwge1xuICBpZih0eXBlb2YgdmFsICE9PSAnb2JqZWN0JykgcmV0dXJuIG5ldyBFcnIoYCR7dmFsfSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gIGlmKEFycmF5LmlzQXJyYXkodmFsKSkgcmV0dXJuIG5ldyBFcnIoYCR7dmFsfSBpcyBhbiBhcnJheWApO1xuICBpZih2YWwgPT09IG51bGwpIHJldHVybiBuZXcgRXJyKGAke3ZhbH0gaXMgbnVsbGApO1xuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpY3Q8Vj4odjogVHlwZTxWPik6IERpY3Q8Vj4ge1xuICByZXR1cm4gbmV3IERpY3Qodik7XG59XG5cbmV4cG9ydCB0eXBlIEZpZWxkRGVmID0gVHlwZTxhbnk+IHwgTWlzc2luZ0tleTxhbnk+IHwgT3B0aW9uYWxLZXk8YW55PjtcblxuZXhwb3J0IHR5cGUgVHlwZVN0cnVjdCA9IHtcbiAgW2tleTogc3RyaW5nXTogRmllbGREZWZcbn07XG5cbi8vIHNlZSB0aGlzIGJsb2cgcG9zdCBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhpcyB0eXBlIHNoZW5hbmlnYW5zXG4vLyBodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay9yZWxlYXNlLW5vdGVzL3R5cGVzY3JpcHQtMi04Lmh0bWxcblxuLy8gUmV0dXJucyBhIHR5cGUgbGlrZSBgXCJmb29cIiB8IFwiYmFyXCJgIGZvciBhbGwgdGhlIG9wdGlvbmFsIGtleXMgaW4gYSB0eXBlc3RydWN0XG50eXBlIE9wdGlvbmFsUHJvcGVydHlOYW1lczxUIGV4dGVuZHMgVHlwZVN0cnVjdD4gPSB7XG4gIFtLIGluIGtleW9mIFRdOiBUW0tdIGV4dGVuZHMgTWlzc2luZ0tleTxhbnk+ID8gSyA6IFRbS10gZXh0ZW5kcyBPcHRpb25hbEtleTxhbnk+ID8gSyA6IG5ldmVyO1xufVtrZXlvZiBUXTtcblxuLy8gVW53cmFwcyBUeXBlPFQ+IGFuZCBPcHRpb25hbEtleTxUeXBlPFQ+PiB0byBUIGZvciBhbGwga2V5cyBpbiBhIHR5cGVzdHJ1Y3RcbnR5cGUgVW53cmFwVHlwZXM8VCBleHRlbmRzIFR5cGVTdHJ1Y3Q+ID0ge1xuICBbSyBpbiBrZXlvZiBUXTogR2V0VHlwZTxXcmFwcGVyT3JUeXBlPFRbS10+Pjtcbn07XG5cbmV4cG9ydCB0eXBlIFVud3JhcHBlZFR5cGVTdHJ1Y3Q8VCBleHRlbmRzIFR5cGVTdHJ1Y3Q+ID1cbiAgLyogcmVxdWlyZWQgcHJvcHMgKi8gUGljazxVbndyYXBUeXBlczxUPiwgRXhjbHVkZTxrZXlvZiBULCBPcHRpb25hbFByb3BlcnR5TmFtZXM8VD4+PiAmXG4gIC8qIG9wdGlvbmFsIHByb3BzICovIFBhcnRpYWw8UGljazxVbndyYXBUeXBlczxUPiwgT3B0aW9uYWxQcm9wZXJ0eU5hbWVzPFQ+Pj47XG5cbmV4cG9ydCB0eXBlIFR5cGVTdHJ1Y3RGb3I8VD4gPSB7XG4gIFtLIGluIGtleW9mIFRdOiBUeXBlPFRbS10+O1xufTtcblxuZXhwb3J0IHR5cGUgU3RydWN0Rm9yPFQ+ID0gU3RydWN0PFR5cGVTdHJ1Y3RGb3I8VD4+O1xuXG5leHBvcnQgZnVuY3Rpb24ga2V5VHlwZTxUPihib3g6IE1pc3NpbmdLZXk8VHlwZTxUPj4gfCBPcHRpb25hbEtleTxUeXBlPFQ+PiB8IFR5cGU8VD4pOiBUeXBlPFQ+IHtcbiAgaWYoYm94IGluc3RhbmNlb2YgTWlzc2luZ0tleSB8fCBib3ggaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgIHJldHVybiBib3gudHlwZTtcbiAgfVxuXG4gIHJldHVybiBib3g7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd3NNaXNzaW5nPFQgZXh0ZW5kcyBUeXBlPGFueT4+KGJveDogTWlzc2luZ0tleTxUPiB8IFQpOiBib3ggaXMgTWlzc2luZ0tleTxUPiB7XG4gIHJldHVybiAoYm94IGluc3RhbmNlb2YgTWlzc2luZ0tleSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd3NPcHRpb25hbDxUIGV4dGVuZHMgVHlwZTxhbnk+Pihib3g6IE1pc3NpbmdLZXk8VD4gfCBUKTogYm94IGlzIE9wdGlvbmFsS2V5PFQ+IHtcbiAgcmV0dXJuIChib3ggaW5zdGFuY2VvZiBPcHRpb25hbEtleSk7XG59XG5cbmV4cG9ydCBjbGFzcyBTdHJ1Y3Q8VCBleHRlbmRzIFR5cGVTdHJ1Y3Q+IGV4dGVuZHMgTWVyZ2VhYmxlVHlwZTxVbndyYXBwZWRUeXBlU3RydWN0PFQ+PiB7XG4gIHJlYWRvbmx5IGRlZmluaXRpb246IFQ7XG4gIHJlYWRvbmx5IGV4YWN0OiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKGRlZmluaXRpb246IFQsIGV4YWN0OiBib29sZWFuKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uO1xuICAgIHRoaXMuZXhhY3QgPSBleGFjdDtcbiAgfVxuXG4gIGNoZWNrKHZhbDogYW55KTogUmVzdWx0PFVud3JhcHBlZFR5cGVTdHJ1Y3Q8VD4+IHtcbiAgICBjb25zdCB0eXBlRXJyID0gdGhpcy5jaGVja1R5cGUodmFsKTtcbiAgICBpZih0eXBlRXJyKSByZXR1cm4gdHlwZUVycjtcblxuICAgIGNvbnN0IGVycnMgPSB0aGlzLmNoZWNrRmllbGRzKHZhbCwgKHQsIHZhbCkgPT4gdC5jaGVjayh2YWwpKTtcblxuICAgIGlmKGVycnMubGVuZ3RoID09PSAwKSByZXR1cm4gdmFsIGFzIFVud3JhcHBlZFR5cGVTdHJ1Y3Q8VD47XG4gICAgcmV0dXJuIG5ldyBFcnIoYCR7dmFsfSBmYWlsZWQgdGhlIGZvbGxvd2luZyBjaGVja3M6XFxuJHtlcnJzLmpvaW4oJ1xcbicpfWApO1xuICB9XG5cbiAgc2xpY2VSZXN1bHQodmFsOiBhbnkpOiBSZXN1bHQ8VW53cmFwcGVkVHlwZVN0cnVjdDxUPj4ge1xuICAgIGNvbnN0IHR5cGVFcnIgPSB0aGlzLmNoZWNrVHlwZSh2YWwpO1xuICAgIGlmKHR5cGVFcnIpIHJldHVybiB0eXBlRXJyO1xuICAgIGNvbnN0IHNsaWNlZDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuXG4gICAgY29uc3QgZXJycyA9IHRoaXMuY2hlY2tGaWVsZHModmFsLCAodCwgdmFsKSA9PiB0LnNsaWNlUmVzdWx0KHZhbCksIChrZXksIHZhbCkgPT4ge1xuICAgICAgc2xpY2VkW2tleV0gPSB2YWw7XG4gICAgfSk7XG5cbiAgICBpZihlcnJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHNsaWNlZCBhcyBVbndyYXBwZWRUeXBlU3RydWN0PFQ+O1xuICAgIHJldHVybiBuZXcgRXJyKGAke3ZhbH0gZmFpbGVkIHRoZSBmb2xsb3dpbmcgY2hlY2tzOlxcbiR7ZXJycy5qb2luKCdcXG4nKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tUeXBlKHZhbDogYW55KTogRXJyPFVud3JhcHBlZFR5cGVTdHJ1Y3Q8VD4+IHwgdW5kZWZpbmVkIHtcbiAgICBpZih0eXBlb2YgdmFsICE9PSAnb2JqZWN0JykgcmV0dXJuIG5ldyBFcnIoYCR7dmFsfSBpcyBub3QgYW4gb2JqZWN0YCk7XG4gICAgaWYoQXJyYXkuaXNBcnJheSh2YWwpKSByZXR1cm4gbmV3IEVycihgJHt2YWx9IGlzIGFuIGFycmF5YCk7XG4gICAgaWYodmFsID09PSBudWxsKSByZXR1cm4gbmV3IEVycihgJHt2YWx9IGlzIG51bGxgKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0ZpZWxkcyh2YWw6IGFueSwgY2hlY2tGbjogKHQ6IFR5cGU8YW55PiwgdmFsOiBhbnkpID0+IFJlc3VsdDxhbnk+LCBjb2xsZWN0PzogKGtleTogc3RyaW5nLCB2YWw6IGFueSkgPT4gYW55KTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGVycnM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yKGNvbnN0IHByb3AgaW4gdGhpcy5kZWZpbml0aW9uKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IHRoaXMuZGVmaW5pdGlvbltwcm9wXVxuICAgICAgaWYoIShwcm9wIGluIHZhbCkpIHtcbiAgICAgICAgaWYoYWxsb3dzTWlzc2luZyhmaWVsZCkpIGNvbnRpbnVlO1xuICAgICAgICBpZihhbGxvd3NPcHRpb25hbChmaWVsZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIGVycnMucHVzaChgbWlzc2luZyBrZXkgJyR7cHJvcH0nYCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWxGaWVsZCA9IHZhbFtwcm9wXTtcbiAgICAgIGlmKHZhbEZpZWxkID09PSB1bmRlZmluZWQgJiYgYWxsb3dzT3B0aW9uYWwoZmllbGQpKSB7XG4gICAgICAgIGlmKGNvbGxlY3QpIGNvbGxlY3QocHJvcCwgdW5kZWZpbmVkKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNoZWNrRm4oa2V5VHlwZShmaWVsZCksIHZhbEZpZWxkKTtcbiAgICAgIGlmKHJlc3VsdCBpbnN0YW5jZW9mIEVycikgZXJycy5wdXNoKHJlc3VsdC5tZXNzYWdlKTtcbiAgICAgIGlmKGNvbGxlY3QpIGNvbGxlY3QocHJvcCwgcmVzdWx0KTtcbiAgICB9XG5cbiAgICBpZih0aGlzLmV4YWN0ICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IoY29uc3QgcHJvcCBpbiB2YWwpIHtcbiAgICAgICAgaWYoIShwcm9wIGluIHRoaXMuZGVmaW5pdGlvbikpIHtcbiAgICAgICAgICBlcnJzLnB1c2goYHVua25vd24ga2V5ICR7cHJvcH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlcnJzO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0eXBlPFQgZXh0ZW5kcyBUeXBlU3RydWN0PihkZWY6IFQpOiBTdHJ1Y3Q8VD4ge1xuICByZXR1cm4gbmV3IFN0cnVjdChkZWYsIGZhbHNlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4YWN0PFQgZXh0ZW5kcyBUeXBlU3RydWN0PihkZWY6IFQpOiBTdHJ1Y3Q8VD4ge1xuICByZXR1cm4gbmV3IFN0cnVjdChkZWYsIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWw8VCBleHRlbmRzIFR5cGU8YW55Pj4oY2hlY2s6IFQpOiBPcHRpb25hbEtleTxUPiB7XG4gIHJldHVybiBuZXcgT3B0aW9uYWxLZXkoY2hlY2spO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dNaXNzaW5nPFQgZXh0ZW5kcyBUeXBlPGFueT4+KGNoZWNrOiBUKTogTWlzc2luZ0tleTxUPiB7XG4gIHJldHVybiBuZXcgTWlzc2luZ0tleShjaGVjayk7XG59XG5cbnR5cGUgTWFrZU9wdGlvbmFsPFQgZXh0ZW5kcyBGaWVsZERlZj4gPSBUIGV4dGVuZHMgVHlwZTxhbnk+ID8gT3B0aW9uYWxLZXk8VD4gOlxuICBUIGV4dGVuZHMgTWlzc2luZ0tleTxpbmZlciBLPiA/IE9wdGlvbmFsS2V5PEs+IDogVDtcblxudHlwZSBEZWVwUGFydGlhbFR5cGVTdHJ1Y3Q8VCBleHRlbmRzIFR5cGVTdHJ1Y3Q+ID0ge1xuICBbSyBpbiBrZXlvZiBUXTogVFtLXSBleHRlbmRzIFN0cnVjdDxpbmZlciBUMj4gPyBPcHRpb25hbEtleTxTdHJ1Y3Q8RGVlcFBhcnRpYWxUeXBlU3RydWN0PFQyPj4+IDpcbiAgICBNYWtlT3B0aW9uYWw8VFtLXT5cbn1cblxudHlwZSBQYXJ0aWFsVHlwZVN0cnVjdDxUIGV4dGVuZHMgVHlwZVN0cnVjdD4gPSB7XG4gIFtLIGluIGtleW9mIFRdOiBNYWtlT3B0aW9uYWw8VFtLXT5cbn07XG5cbmV4cG9ydCBjbGFzcyBQYXJ0aWFsU3RydWN0PFQgZXh0ZW5kcyBUeXBlU3RydWN0PiBleHRlbmRzIE1lcmdlYWJsZVR5cGU8VW53cmFwcGVkVHlwZVN0cnVjdDxQYXJ0aWFsVHlwZVN0cnVjdDxUPj4+IHtcbiAgcHJpdmF0ZSByZWFkb25seSBoaWRkZW5TdHJ1Y3Q6IFN0cnVjdDxQYXJ0aWFsVHlwZVN0cnVjdDxUPj47XG4gIHByaXZhdGUgcmVhZG9ubHkgaGlkZGVuVHlwZVN0cnVjdDogUGFydGlhbFR5cGVTdHJ1Y3Q8VD47XG4gIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHN0cnVjdDogU3RydWN0PFQ+KSB7XG4gICAgc3VwZXIoKTtcbiAgICBjb25zdCBwYXJ0aWFsRGVmOiBQYXJ0aWFsPFBhcnRpYWxUeXBlU3RydWN0PFQ+PiA9IHt9O1xuICAgIGZvcihjb25zdCBrIGluIHN0cnVjdC5kZWZpbml0aW9uKSB7XG4gICAgICBjb25zdCB2ID0gc3RydWN0LmRlZmluaXRpb25ba107XG4gICAgICBpZih2IGluc3RhbmNlb2YgTWlzc2luZ0tleSkge1xuICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgcGFydGlhbERlZltrXSA9IG9wdGlvbmFsKHYudHlwZSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHYgaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgcGFydGlhbERlZltrXSA9IG9wdGlvbmFsKHYudHlwZSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9AdHMtaWdub3JlXG4gICAgICAgIHBhcnRpYWxEZWZba10gPSBvcHRpb25hbCh2KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5oaWRkZW5UeXBlU3RydWN0ID0gcGFydGlhbERlZiBhcyBQYXJ0aWFsVHlwZVN0cnVjdDxUPjtcbiAgICB0aGlzLmhpZGRlblN0cnVjdCA9IG5ldyBTdHJ1Y3QodGhpcy5oaWRkZW5UeXBlU3RydWN0LCBzdHJ1Y3QuZXhhY3QpO1xuICB9XG4gIGNoZWNrKHZhbDogYW55KTogUmVzdWx0PFVud3JhcHBlZFR5cGVTdHJ1Y3Q8UGFydGlhbFR5cGVTdHJ1Y3Q8VD4+PiB7XG4gICAgcmV0dXJuIHRoaXMuaGlkZGVuU3RydWN0LmNoZWNrKHZhbCk7XG4gIH1cbiAgc2xpY2VSZXN1bHQodmFsOiBhbnkpOiBSZXN1bHQ8VW53cmFwcGVkVHlwZVN0cnVjdDxQYXJ0aWFsVHlwZVN0cnVjdDxUPj4+IHtcbiAgICByZXR1cm4gdGhpcy5oaWRkZW5TdHJ1Y3Quc2xpY2VSZXN1bHQodmFsKTtcbiAgfVxuXG4gIHJlaWZ5KCk6IFN0cnVjdDxQYXJ0aWFsVHlwZVN0cnVjdDxUPj4ge1xuICAgIHJldHVybiBuZXcgU3RydWN0KHRoaXMuaGlkZGVuVHlwZVN0cnVjdCwgdGhpcy5oaWRkZW5TdHJ1Y3QuZXhhY3QpO1xuICB9XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBQYXJ0aWFsPFQgZXh0ZW5kcyBUeXBlU3RydWN0PihvZ3N0cnVjdDogU3RydWN0PFQ+KTogUGFydGlhbFN0cnVjdDxEZWVwUGFydGlhbFR5cGVTdHJ1Y3Q8VD4+IHtcbiAgLy8gSWYgdGhlIG9yaWdpbmFsIHN0cnVjdCBpc24ndCBuZXN0ZWQsIGl0J3MganVzdCBhbiBvcmRpbmFyeSBwYXJ0aWFsIGNhbGwuIERvbid0IG1vZGlmeSB0aGVcbiAgLy8gZGVmaW5pdGlvbiwgb3IgZWxzZSB3aGVuIHlvdSBjb252ZXJ0IHRvIFR5cGVTY3JpcHQgaXQgd29uJ3QgY29ycmVjdGx5IHJlZiBvdXQgdGhlIHN0cnVjdFxuICBpZighaGFzTmVzdGVkKG9nc3RydWN0KSkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gcGFydGlhbChvZ3N0cnVjdCk7XG4gIH1cblxuICAvLyBJZiB3ZSBnb3QgdGhpcyBmYXIsIHRoZSBzdHJ1Y3QgaGFzIG5lc3RpbmcsIGFuZCB0aGVyZWZvcmUgY2FuJ3Qgc2ltcGx5IGJlIHJlZi1lZCBvdXQgd2hlblxuICAvLyBjb252ZXJ0aW5nIHRvIFR5cGVTY3JpcHQuIFdlIG11c3QgbW9kaWZ5IGl0IHJlY3Vyc2l2ZWx5LlxuICBjb25zdCBwYXJ0aWFsRGVmOiBQYXJ0aWFsPERlZXBQYXJ0aWFsVHlwZVN0cnVjdDxUPj4gPSB7fTtcbiAgZm9yKGNvbnN0IGsgaW4gb2dzdHJ1Y3QuZGVmaW5pdGlvbikge1xuICAgIGNvbnN0IHYgPSBvZ3N0cnVjdC5kZWZpbml0aW9uW2tdO1xuICAgIGlmKHYgaW5zdGFuY2VvZiBNaXNzaW5nS2V5KSB7XG4gICAgICAvL0B0cy1pZ25vcmVcbiAgICAgIHBhcnRpYWxEZWZba10gPSBuZXcgTWlzc2luZ0tleSh2LnR5cGUpO1xuICAgIH1cbiAgICBlbHNlIGlmKHYgaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgICAgLy9AdHMtaWdub3JlXG4gICAgICBwYXJ0aWFsRGVmW2tdID0gb3B0aW9uYWwodi50eXBlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBkZWVwS2luZCA9IGRlZXBQYXJ0aWFsS2luZCh2KTtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHBhcnRpYWxEZWZba10gPSBkZWVwS2luZDtcbiAgICB9XG4gIH1cbiAgY29uc3Qgc3RydWN0ID0gbmV3IFN0cnVjdChwYXJ0aWFsRGVmIGFzIERlZXBQYXJ0aWFsVHlwZVN0cnVjdDxUPiwgb2dzdHJ1Y3QuZXhhY3QpO1xuICByZXR1cm4gbmV3IFBhcnRpYWxTdHJ1Y3Qoc3RydWN0KTtcbn1cblxuZXhwb3J0IGNsYXNzIE1lcmdlSW50ZXJzZWN0PFxuICBMVmFsLCBSVmFsLFxuICBMIGV4dGVuZHMgTWVyZ2VhYmxlVHlwZTxMVmFsPixcbiAgUiBleHRlbmRzIE1lcmdlYWJsZVR5cGU8UlZhbD4sXG4+IGV4dGVuZHMgTWVyZ2VhYmxlVHlwZTxMVmFsICYgUlZhbD4ge1xuXG4gIC8vIERBTkdFUjogTkVWRVIgRVZFUiBMRUFLIFRISVMgT0JKRUNUXG4gIC8vIFRoaXMgaXMgZm9yIGludGVybmFsIHVzZSBvbmx5LiBEbyBub3QgdXNlIGl0cyAuYW5kIGZ1bmN0aW9uLiBEbyBub3QgcGFzcyBpdCB0byBvdGhlciAuYW5kIG9yXG4gIC8vIC5vciBmdW5jdGlvbnMuIERvIG5vdCB1c2UgaXQgQVQgQUxMIGV4Y2VwdCB0byBjYWxsIC5jaGVjayBvciAuc2xpY2VSZXN1bHQgb24gaXQuIEl0IE1BWSBiZSBhXG4gIC8vIHNlY3JldCBpbnRlcm5hbCBjbGFzcyBjYWxsZWQgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2UgKGRlZmluZWQgYmVsb3cpIHRoYXQgZG9lcyBub3QgcGxheSB3ZWxsXG4gIC8vIHdpdGggb3RoZXIgdHlwZXMgb3IgdHlwZSBhbGdlYnJhLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbWVyZ2VkOiBUeXBlPExWYWwgJiBSVmFsPjtcblxuICBjb25zdHJ1Y3RvcihyZWFkb25seSBsOiBMLCByZWFkb25seSByOiBSKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMubWVyZ2VkID0gbWVyZ2UobCwge1xuICAgICAgZGljdDogbCA9PiB0aGlzLm1lcmdlRGljdEFuZE1lcmdlYWJsZShsLCByKSxcbiAgICAgIHN0cnVjdDogbCA9PiB0aGlzLm1lcmdlU3RydWN0QW5kTWVyZ2VhYmxlKGwsIHIpLFxuICAgICAgcGFydGlhbDogbCA9PiB0aGlzLm1lcmdlU3RydWN0QW5kTWVyZ2VhYmxlKGwucmVpZnkoKSwgciksXG4gICAgICBtZXJnZTogbCA9PiB0aGlzLm1lcmdlSW50ZXJzZWN0QW5kTWVyZ2VhYmxlKGwsIHIpLFxuICAgICAgaW50ZXJuYWw6ICgpID0+IHtcbiAgICAgICAgdGhyb3cgYGxlYWtlZCBpbnRlcm5hbCBkaWN0L3N0cnVjdCBtZXJnZSBjbGFzczsgc3RydWN0dXJhbCBlcnJvcmA7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY2hlY2sodmFsOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tZXJnZWQuY2hlY2sodmFsKTtcbiAgfVxuXG4gIHNsaWNlUmVzdWx0KHZhbDogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMubWVyZ2VkLnNsaWNlUmVzdWx0KHZhbCk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlRGljdEFuZE1lcmdlYWJsZShcbiAgICBkOiBEaWN0PGFueT4sXG4gICAgbTogTWVyZ2VhYmxlVHlwZTxhbnk+IHwgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2U8YW55LCBhbnksIGFueSwgYW55PlxuICApOiBNZXJnZWFibGVUeXBlPGFueT4gfCBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZTxhbnksIGFueSwgYW55LCBhbnk+IHtcbiAgICByZXR1cm4gbWVyZ2UobSwge1xuICAgICAgZGljdDogKG0pID0+IHRoaXMubWVyZ2VEaWN0cyhkLCBtKSxcbiAgICAgIHBhcnRpYWw6IChtKSA9PiBuZXcgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2UobS5yZWlmeSgpLCBkKSxcbiAgICAgIHN0cnVjdDogKG0pID0+IHRoaXMubWVyZ2VEaWN0QW5kU3RydWN0KGQsIG0pLFxuICAgICAgbWVyZ2U6IChtKSA9PiB0aGlzLm1lcmdlRGljdEFuZE1lcmdlYWJsZShkLCBtLm1lcmdlZCksXG4gICAgICBpbnRlcm5hbDogKG0pID0+IHRoaXMubWVyZ2VJbnRlcm5hbEFuZERpY3QobSwgZCksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlU3RydWN0QW5kTWVyZ2VhYmxlKFxuICAgIHM6IFN0cnVjdDxhbnk+LFxuICAgIG06IE1lcmdlYWJsZVR5cGU8YW55PiB8IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT5cbiAgKTogTWVyZ2VhYmxlVHlwZTxhbnk+IHwgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2U8YW55LCBhbnksIGFueSwgYW55PiB7XG4gICAgcmV0dXJuIG1lcmdlKG0sIHtcbiAgICAgIGRpY3Q6IG0gPT4gdGhpcy5tZXJnZURpY3RBbmRTdHJ1Y3QobSwgcyksXG4gICAgICBwYXJ0aWFsOiBtID0+IHRoaXMubWVyZ2VTdHJ1Y3RzKHMsIG0ucmVpZnkoKSksXG4gICAgICBzdHJ1Y3Q6IG0gPT4gdGhpcy5tZXJnZVN0cnVjdHMocywgbSksXG4gICAgICBtZXJnZTogbSA9PiB0aGlzLm1lcmdlU3RydWN0QW5kTWVyZ2VhYmxlKHMsIG0ubWVyZ2VkKSxcbiAgICAgIGludGVybmFsOiBtID0+IHRoaXMubWVyZ2VJbnRlcm5hbEFuZFN0cnVjdChtLCBzKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VQYXJ0aWFsQW5kTWVyZ2VhYmxlKFxuICAgIHA6IFBhcnRpYWxTdHJ1Y3Q8YW55PixcbiAgICBtOiBNZXJnZWFibGVUeXBlPGFueT4gfCBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZTxhbnksIGFueSwgYW55LCBhbnk+LFxuICApOiBNZXJnZWFibGVUeXBlPGFueT4gfCBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZTxhbnksIGFueSwgYW55LCBhbnk+IHtcbiAgICByZXR1cm4gbWVyZ2UobSwge1xuICAgICAgZGljdDogbSA9PiBuZXcgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2UocC5yZWlmeSgpLCBtKSxcbiAgICAgIHBhcnRpYWw6IG0gPT4gdGhpcy5tZXJnZVN0cnVjdHMocC5yZWlmeSgpLCBtLnJlaWZ5KCkpLFxuICAgICAgc3RydWN0OiBtID0+IHRoaXMubWVyZ2VTdHJ1Y3RzKHAucmVpZnkoKSwgbSksXG4gICAgICBtZXJnZTogbSA9PiB0aGlzLm1lcmdlUGFydGlhbEFuZE1lcmdlYWJsZShwLCBtLm1lcmdlZCksXG4gICAgICBpbnRlcm5hbDogbSA9PiB0aGlzLm1lcmdlSW50ZXJuYWxBbmRTdHJ1Y3QobSwgcC5yZWlmeSgpKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VJbnRlcnNlY3RBbmRNZXJnZWFibGUoXG4gICAgaTogTWVyZ2VJbnRlcnNlY3Q8YW55LCBhbnksIGFueSwgYW55PixcbiAgICBtOiBNZXJnZWFibGVUeXBlPGFueT4gfCBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZTxhbnksIGFueSwgYW55LCBhbnk+XG4gICk6IE1lcmdlYWJsZVR5cGU8YW55PiB8IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT4ge1xuICAgIHJldHVybiBtZXJnZShtLCB7XG4gICAgICBkaWN0OiBtID0+IHRoaXMubWVyZ2VEaWN0QW5kTWVyZ2VhYmxlKG0sIGkubWVyZ2VkKSxcbiAgICAgIHBhcnRpYWw6IG0gPT4gdGhpcy5tZXJnZVBhcnRpYWxBbmRNZXJnZWFibGUobSwgaS5tZXJnZWQpLFxuICAgICAgc3RydWN0OiBtID0+IHRoaXMubWVyZ2VTdHJ1Y3RBbmRNZXJnZWFibGUobSwgaS5tZXJnZWQpLFxuICAgICAgbWVyZ2U6IG0gPT4gdGhpcy5tZXJnZUludGVyc2VjdEFuZE1lcmdlYWJsZShtLCBpLm1lcmdlZCksXG4gICAgICBpbnRlcm5hbDogbSA9PiB0aGlzLm1lcmdlSW50ZXJuYWxBbmRJbnRlcnNlY3QobSwgaSksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlSW50ZXJuYWxBbmREaWN0KGw6IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT4sIHI6IERpY3Q8YW55Pikge1xuICAgIHJldHVybiBuZXcgSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2UobC5zLCB0aGlzLm1lcmdlRGljdHMobC5kLCByKSk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlSW50ZXJuYWxBbmRTdHJ1Y3QobDogSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2U8YW55LCBhbnksIGFueSwgYW55PiwgcjogU3RydWN0PGFueT4pIHtcbiAgICByZXR1cm4gbmV3IEludGVybmFsRGljdFN0cnVjdE1lcmdlKHRoaXMubWVyZ2VTdHJ1Y3RzKGwucywgciksIGwuZCk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlSW50ZXJuYWxBbmRJbnRlcnNlY3QoXG4gICAgbDogSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2U8YW55LCBhbnksIGFueSwgYW55PixcbiAgICByOiBNZXJnZUludGVyc2VjdDxhbnksIGFueSwgYW55LCBhbnk+XG4gICk6IE1lcmdlYWJsZVR5cGU8YW55PiB8IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT4ge1xuICAgIHJldHVybiBtZXJnZShyLm1lcmdlZCwge1xuICAgICAgZGljdDogbWVyZ2VkID0+IHRoaXMubWVyZ2VJbnRlcm5hbEFuZERpY3QobCwgbWVyZ2VkKSxcbiAgICAgIHBhcnRpYWw6IG1lcmdlZCA9PiB0aGlzLm1lcmdlSW50ZXJuYWxBbmRTdHJ1Y3QobCwgbWVyZ2VkLnJlaWZ5KCkpLFxuICAgICAgc3RydWN0OiBtZXJnZWQgPT4gdGhpcy5tZXJnZUludGVybmFsQW5kU3RydWN0KGwsIG1lcmdlZCksXG4gICAgICBtZXJnZTogKCkgPT4ge1xuICAgICAgICB0aHJvdyBgTWVyZ2VJbnRlcnNlY3QgY2FuJ3QgYmUgYSBjaGlsZCBvZiBhIE1lcmdlSW50ZXJzZWN0OyBzdHJ1Y3R1cmFsIGludGVybmFsIGVycm9yYFxuICAgICAgfSxcbiAgICAgIGludGVybmFsOiBtZXJnZWQgPT4gdGhpcy5tZXJnZUludGVybmFsQW5kSW50ZXJuYWwobCwgbWVyZ2VkKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VJbnRlcm5hbEFuZEludGVybmFsKFxuICAgIGw6IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT4sXG4gICAgcjogSW50ZXJuYWxEaWN0U3RydWN0TWVyZ2U8YW55LCBhbnksIGFueSwgYW55PixcbiAgKSB7XG4gICAgcmV0dXJuIG5ldyBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZShcbiAgICAgIHRoaXMubWVyZ2VTdHJ1Y3RzKGwucywgci5zKSxcbiAgICAgIHRoaXMubWVyZ2VEaWN0cyhsLmQsIHIuZCksXG4gICAgKVxuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZURpY3RzKGw6IERpY3Q8TD4sIHI6IERpY3Q8Uj4pOiBEaWN0PEwgJiBSPiB7XG4gICAgcmV0dXJuIGRpY3QobC52YWx1ZVR5cGUuYW5kKHIudmFsdWVUeXBlKSk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlRGljdEFuZFN0cnVjdChsOiBEaWN0PEw+LCByOiBTdHJ1Y3RGb3I8Uj4pIHtcbiAgICByZXR1cm4gbmV3IEludGVybmFsRGljdFN0cnVjdE1lcmdlKHIsIGwpO1xuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZVN0cnVjdHMobDogU3RydWN0PGFueT4sIHI6IFN0cnVjdDxhbnk+KSB7XG4gICAgY29uc3QgZGVmaW5pdGlvbjogeyBba2V5OiBzdHJpbmddOiBGaWVsZERlZiB9ID0ge307XG5cbiAgICBmb3IoY29uc3QgcHJvcCBpbiBsLmRlZmluaXRpb24pIHtcbiAgICAgIGRlZmluaXRpb25bcHJvcF0gPSBsLmRlZmluaXRpb25bcHJvcF07XG4gICAgfVxuICAgIGZvcihjb25zdCBwcm9wIGluIHIuZGVmaW5pdGlvbikge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBkZWZpbml0aW9uW3Byb3BdO1xuICAgICAgY29uc3QgbWVyZ2luZyA9IHIuZGVmaW5pdGlvbltwcm9wXTtcbiAgICAgIC8vIElmIGl0J3MgYW4gYWRkaXRpb25hbCBrZXksIHNsYXAgaXQgaW5cbiAgICAgIGlmKGV4aXN0aW5nID09IG51bGwpIGRlZmluaXRpb25bcHJvcF0gPSByLmRlZmluaXRpb25bcHJvcF07XG4gICAgICAvLyBJZiBpdCdzIGEgbWlzc2luZyBrZXksIGhhbmRsZVxuICAgICAgZWxzZSBpZihleGlzdGluZyBpbnN0YW5jZW9mIE1pc3NpbmdLZXkpIHtcbiAgICAgICAgLy8gTWlzc2luZyBrZXlzIGFyZSBzdHJpY3RlciB0aGFuIG9wdGlvbmFsLCBzbyBib3RoIGNvbnZlcmdlIHRvIG1pc3Npbmcga2V5XG4gICAgICAgIGlmKG1lcmdpbmcgaW5zdGFuY2VvZiBNaXNzaW5nS2V5IHx8IG1lcmdpbmcgaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgICAgICAgIGRlZmluaXRpb25bcHJvcF0gPSBuZXcgTWlzc2luZ0tleShleGlzdGluZy50eXBlLmFuZChtZXJnaW5nLnR5cGUpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgc3RyaWN0ZXN0IGlzIGp1c3QgYSByYXcgdHlwZSwgc28gdW53cmFwIGFuZCBtZXJnZVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWZpbml0aW9uW3Byb3BdID0gZXhpc3RpbmcudHlwZS5hbmQobWVyZ2luZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIElmIGl0J3MgYW4gb3B0aW9uYWwga2V5LCBoYW5kbGVcbiAgICAgIGVsc2UgaWYoZXhpc3RpbmcgaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgICAgICAvLyBNaXNzaW5nIGtleSBpcyBzdHJpY3RlciB0aGFuIG9wdGlvbmFsLCBzbyBpdCB3aW5zXG4gICAgICAgIGlmKG1lcmdpbmcgaW5zdGFuY2VvZiBNaXNzaW5nS2V5KSB7XG4gICAgICAgICAgZGVmaW5pdGlvbltwcm9wXSA9IG5ldyBNaXNzaW5nS2V5KGV4aXN0aW5nLnR5cGUuYW5kKG1lcmdpbmcudHlwZSkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFR3byBvcHRpb25hbHMgbWVyZ2UgaW50byBhbiBvcHRpb25hbFxuICAgICAgICBlbHNlIGlmKG1lcmdpbmcgaW5zdGFuY2VvZiBPcHRpb25hbEtleSkge1xuICAgICAgICAgIGRlZmluaXRpb25bcHJvcF0gPSBuZXcgT3B0aW9uYWxLZXkoZXhpc3RpbmcudHlwZS5hbmQobWVyZ2luZy50eXBlKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQSByYXcgdHlwZSBpcyBzdHJpY3RlciB0aGFuIG9wdGlvbmFsLCBzbyBpdCB1bndyYXBzIHRoZSBvcHRpb25hbGl0eVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWZpbml0aW9uW3Byb3BdID0gZXhpc3RpbmcudHlwZS5hbmQobWVyZ2luZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvLyBSYXcgdHlwZXMgYXJlIHN0cmljdGVyIHRoYW4gbWlzc2luZyBvciBvcHRpb25hbCB0eXBlc1xuICAgICAgICBpZihtZXJnaW5nIGluc3RhbmNlb2YgTWlzc2luZ0tleSB8fCBtZXJnaW5nIGluc3RhbmNlb2YgT3B0aW9uYWxLZXkpIHtcbiAgICAgICAgICBkZWZpbml0aW9uW3Byb3BdID0gZXhpc3RpbmcuYW5kKG1lcmdpbmcudHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmluYWxseSwgbWVyZ2luZyB0d28gcmF3IHR5cGVzXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlZmluaXRpb25bcHJvcF0gPSBleGlzdGluZy5hbmQobWVyZ2luZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFN0cnVjdChkZWZpbml0aW9uLCBsLmV4YWN0ICYmIHIuZXhhY3QpO1xuICB9XG59XG5cbnR5cGUgTWVyZ2VIYW5kbGVycyA9IHtcbiAgICBkaWN0OiAoZDogRGljdDxhbnk+KSA9PiBNZXJnZVJlc3VsdCxcbiAgICBwYXJ0aWFsOiAocDogUGFydGlhbFN0cnVjdDxhbnk+KSA9PiBNZXJnZVJlc3VsdCxcbiAgICBzdHJ1Y3Q6IChzOiBTdHJ1Y3Q8YW55PikgPT4gTWVyZ2VSZXN1bHQsXG4gICAgbWVyZ2U6IChtOiBNZXJnZUludGVyc2VjdDxhbnksIGFueSwgYW55LCBhbnk+KSA9PiBNZXJnZVJlc3VsdCxcbiAgICBpbnRlcm5hbDogKGk6IEludGVybmFsRGljdFN0cnVjdE1lcmdlPGFueSwgYW55LCBhbnksIGFueT4pID0+IE1lcmdlUmVzdWx0LFxufTtcbnR5cGUgTWVyZ2VSZXN1bHQgPSBNZXJnZWFibGVUeXBlPGFueT4gfCBJbnRlcm5hbERpY3RTdHJ1Y3RNZXJnZTxhbnksIGFueSwgYW55LCBhbnk+O1xuZnVuY3Rpb24gbWVyZ2U8SW5wdXQgZXh0ZW5kcyBNZXJnZWFibGVUeXBlPGFueT4+KFxuICBpOiBJbnB1dCxcbiAgaGFuZGxlcnM6IE1lcmdlSGFuZGxlcnMsXG4pOiBNZXJnZVJlc3VsdCB7XG4gIGlmKGkgaW5zdGFuY2VvZiBEaWN0KSByZXR1cm4gaGFuZGxlcnMuZGljdChpKTtcbiAgaWYoaSBpbnN0YW5jZW9mIFBhcnRpYWxTdHJ1Y3QpIHJldHVybiBoYW5kbGVycy5wYXJ0aWFsKGkpO1xuICBpZihpIGluc3RhbmNlb2YgU3RydWN0KSByZXR1cm4gaGFuZGxlcnMuc3RydWN0KGkpO1xuICBpZihpIGluc3RhbmNlb2YgTWVyZ2VJbnRlcnNlY3QpIHJldHVybiBoYW5kbGVycy5tZXJnZShpKTtcbiAgaWYoaSBpbnN0YW5jZW9mIEludGVybmFsRGljdFN0cnVjdE1lcmdlKSByZXR1cm4gaGFuZGxlcnMuaW50ZXJuYWwoaSk7XG4gIHRocm93IGBVbmtub3duIHR5cGUgJHtpfWA7XG59XG5cbmNsYXNzIEludGVybmFsRGljdFN0cnVjdE1lcmdlPFxuICBTVmFsIGV4dGVuZHMgVHlwZVN0cnVjdCwgRFZhbCxcbiAgUyBleHRlbmRzIFN0cnVjdDxTVmFsPixcbiAgRCBleHRlbmRzIERpY3Q8RFZhbD5cbj4gZXh0ZW5kcyBUeXBlPEdldFR5cGU8Uz4gJiBHZXRUeXBlPEQ+PiB7XG4gIHJlYWRvbmx5IHM6IFM7XG4gIGNvbnN0cnVjdG9yKHM6IFMsIHJlYWRvbmx5IGQ6IEQpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucyA9IG5ldyBTdHJ1Y3Qocy5kZWZpbml0aW9uLCBmYWxzZSkgYXMgUztcbiAgfVxuXG4gIGNoZWNrKHZhbDogYW55KSB7XG4gICAgY29uc3QgZFJlc3VsdCA9IHRoaXMuZC5jaGVjayh2YWwpO1xuICAgIGlmKGRSZXN1bHQgaW5zdGFuY2VvZiBFcnIpIHJldHVybiBkUmVzdWx0O1xuICAgIGNvbnN0IHNSZXN1bHQgPSB0aGlzLnMuY2hlY2sodmFsKTtcbiAgICBpZihzUmVzdWx0IGluc3RhbmNlb2YgRXJyKSByZXR1cm4gc1Jlc3VsdDtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgc2xpY2VSZXN1bHQodmFsOiBhbnkpIHtcbiAgICBjb25zdCBkUmVzdWx0ID0gdGhpcy5kLnNsaWNlUmVzdWx0KHZhbCk7XG4gICAgaWYoZFJlc3VsdCBpbnN0YW5jZW9mIEVycikgcmV0dXJuIGRSZXN1bHQ7XG4gICAgY29uc3Qgc1Jlc3VsdCA9IHRoaXMucy5zbGljZVJlc3VsdCh2YWwpO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBkUmVzdWx0LCBzUmVzdWx0KSBhcyBHZXRUeXBlPFM+ICYgR2V0VHlwZTxEPjtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTmVzdGVkID0gW1xuICBTdHJ1Y3QsXG4gIFBhcnRpYWxTdHJ1Y3QsXG4gIERpY3QsXG4gIEVpdGhlcixcbiAgRGVmYXVsdEludGVyc2VjdCxcbiAgTWVyZ2VJbnRlcnNlY3QsXG4gIENvbW1lbnQsXG5dIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgTmVzdGVkVHlwZSA9IEluc3RhbmNlVHlwZTwodHlwZW9mIE5lc3RlZClbbnVtYmVyXT47XG5cbmZ1bmN0aW9uIGRlZXBQYXJ0aWFsS2luZChraW5kOiBUeXBlPGFueT4pOiBUeXBlPGFueT4ge1xuICBpZihpc05lc3RlZChraW5kKSkgcmV0dXJuIGhhbmRsZU5lc3RlZChraW5kKTtcbiAgcmV0dXJuIGtpbmQ7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU5lc3RlZChraW5kOiBOZXN0ZWRUeXBlKTogVHlwZTxhbnk+IHtcbiAgaWYoa2luZCBpbnN0YW5jZW9mIFN0cnVjdCkge1xuICAgIGlmKGhhc05lc3RlZChraW5kKSkgcmV0dXJuIGRlZXBQYXJ0aWFsKGtpbmQpO1xuICAgIHJldHVybiBuZXcgUGFydGlhbFN0cnVjdChraW5kKTtcbiAgfVxuICBpZihraW5kIGluc3RhbmNlb2YgUGFydGlhbFN0cnVjdCkgcmV0dXJuIGRlZXBQYXJ0aWFsKGtpbmQuc3RydWN0KTtcbiAgaWYoa2luZCBpbnN0YW5jZW9mIENvbW1lbnQpIHJldHVybiBuZXcgQ29tbWVudChraW5kLmNvbW1lbnRTdHIsIGRlZXBQYXJ0aWFsS2luZChraW5kLndyYXBwZWQpKTtcbiAgaWYoa2luZCBpbnN0YW5jZW9mIERpY3QpIHJldHVybiBuZXcgRGljdChkZWVwUGFydGlhbEtpbmQoa2luZC52YWx1ZVR5cGUpLCBraW5kLm5hbWVkS2V5KTtcbiAgaWYoa2luZCBpbnN0YW5jZW9mIEVpdGhlcikgcmV0dXJuIG5ldyBFaXRoZXIoZGVlcFBhcnRpYWxLaW5kKGtpbmQubCksIGRlZXBQYXJ0aWFsS2luZChraW5kLnIpKTtcbiAgaWYoa2luZCBpbnN0YW5jZW9mIE1lcmdlSW50ZXJzZWN0KSByZXR1cm4gbmV3IERlZmF1bHRJbnRlcnNlY3QoZGVlcFBhcnRpYWxLaW5kKGtpbmQubCksIGRlZXBQYXJ0aWFsS2luZChraW5kLnIpKTtcbiAgcmV0dXJuIG5ldyBEZWZhdWx0SW50ZXJzZWN0KGRlZXBQYXJ0aWFsS2luZChraW5kLmwpLCBkZWVwUGFydGlhbEtpbmQoa2luZC5yKSk7XG59XG5cbmZ1bmN0aW9uIGlzTmVzdGVkKGtpbmQ6IFR5cGU8YW55PiB8IE5lc3RlZFR5cGUpOiBraW5kIGlzIE5lc3RlZFR5cGUge1xuICBmb3IoY29uc3QgdCBvZiBOZXN0ZWQpIHtcbiAgICBpZihraW5kIGluc3RhbmNlb2YgdCkgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBoYXNOZXN0ZWQoc3RydWN0OiBTdHJ1Y3Q8YW55Pikge1xuICBmb3IoY29uc3QgayBpbiBzdHJ1Y3QuZGVmaW5pdGlvbikge1xuICAgIGlmKGlzTmVzdGVkKHN0cnVjdC5kZWZpbml0aW9uW2tdKSkgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFydGlhbDxUIGV4dGVuZHMgVHlwZVN0cnVjdD4oc3RydWN0OiBTdHJ1Y3Q8VD4pOiBQYXJ0aWFsU3RydWN0PFQ+IHtcbiAgcmV0dXJuIG5ldyBQYXJ0aWFsU3RydWN0KHN0cnVjdCk7XG59XG4iXX0=
|