UNPKG

breeze-client

Version:

Breeze data management for JavaScript clients

712 lines (711 loc) 85.4 kB
/** See if this comment will make it into .d.ts */ import { BreezeEnum } from './enum'; let hasOwnProperty = uncurry(Object.prototype.hasOwnProperty); let arraySlice = uncurry(Array.prototype.slice); let isES5Supported = function () { try { return !!(Object.getPrototypeOf && Object.defineProperty({}, 'x', {})); } catch (e) { return false; } }(); // iterate over object function objectForEach(obj, kvFn) { for (let key in obj) { if (hasOwnProperty(obj, key)) { kvFn(key, obj[key]); } } } function objectMap(obj, kvFn) { let results = []; for (let key in obj) { if (hasOwnProperty(obj, key)) { let result = kvFn ? kvFn(key, obj[key]) : obj[key]; if (result !== undefined) { results.push(result); } } } return results; } function objectFirst(obj, kvPredicate) { for (let key in obj) { if (hasOwnProperty(obj, key)) { let value = obj[key]; if (kvPredicate(key, value)) { return { key: key, value: value }; } } } return null; } function arrayFlatMap(arr, mapFn) { return Array.prototype.concat.apply([], arr.map(mapFn)); } function isSettable(obj, propertyName) { let pd = getPropDescriptor(obj, propertyName); if (pd == null) return true; return !!(pd.writable || pd.set); } function getPropDescriptor(obj, propertyName) { if (!isES5Supported) return undefined; if (obj.hasOwnProperty(propertyName)) { return Object.getOwnPropertyDescriptor(obj, propertyName); } else { let nextObj = Object.getPrototypeOf(obj); if (nextObj == null) return undefined; return getPropDescriptor(nextObj, propertyName); } } // Functional extensions /** can be used like: persons.filter(propEq("firstName", "John")) */ function propEq(propertyName, value) { return function (obj) { return obj[propertyName] === value; }; } /** can be used like: persons.filter(propEq("firstName", "FirstName", "John")) */ function propsEq(property1Name, property2Name, value) { return function (obj) { return obj[property1Name] === value || obj[property2Name] === value; }; } /** can be used like persons.map(pluck("firstName")) */ function pluck(propertyName) { return function (obj) { return obj[propertyName]; }; } // end functional extensions /** Return an array of property values from source */ function getOwnPropertyValues(source) { let result = []; for (let name in source) { if (hasOwnProperty(source, name)) { result.push(source[name]); } } return result; } /** Copy properties from source to target. Returns target. */ function extend(target, source, propNames) { if (!source) return target; if (propNames) { propNames.forEach(function (propName) { target[propName] = source[propName]; }); } else { for (let propName in source) { if (hasOwnProperty(source, propName)) { target[propName] = source[propName]; } } } return target; } /** Copy properties from defaults iff undefined on target. Returns target. */ function updateWithDefaults(target, defaults) { for (let name in defaults) { if (target[name] === undefined) { target[name] = defaults[name]; } } return target; } /** Set ctor.defaultInstance to an instance of ctor with properties from target. We want to insure that the object returned by ctor.defaultInstance is always immutable Use 'target' as the primary template for the ctor.defaultInstance; Use current 'ctor.defaultInstance' as the template for any missing properties creates a new instance for ctor.defaultInstance returns target unchanged */ function setAsDefault(target, ctor) { ctor.defaultInstance = updateWithDefaults(new ctor(target), ctor.defaultInstance); return target; } /** 'source' is an object that will be transformed into another 'template' is a map where the keys: are the keys to return if a key contains ','s then the key is treated as a delimited string with first of the keys being the key to return and the others all valid aliases for this key 'values' are either 1) the 'default' value of the key 2) a function that takes in the source value and should return the value to set The value from the source is then set on the target, after first passing thru the fn, if provided, UNLESS: 1) it is the default value 2) it is undefined ( nulls WILL be set) 'target' is optional - if it exists then properties of the target will be set ( overwritten if the exist) - if it does not exist then a new object will be created as filled. 'target is returned. */ function toJson(source, template, target = {}) { for (let key in template) { let aliases = key.split(","); let defaultValue = template[key]; // using some as a forEach with a 'break' aliases.some(function (propName) { if (!(propName in source)) return false; let value = source[propName]; // there is a functional property defined with this alias ( not what we want to replace). if (typeof value === 'function') return false; // '==' is deliberate here - idea is that null or undefined values will never get serialized // if default value is set to null. // tslint:disable-next-line if (value == defaultValue) return true; if (Array.isArray(value) && value.length === 0) return true; if (typeof (defaultValue) === "function") { value = defaultValue(value); } else if (typeof (value) === "object") { if (value && value instanceof BreezeEnum) { value = value.name; } } if (value === undefined) return true; target[aliases[0]] = value; return true; }); } return target; } /** Replacer function for toJSONSafe, when serializing entities. Excludes entityAspect and other internal properties. */ function toJSONSafeReplacer(prop, val) { if (prop === "entityAspect" || prop === "complexAspect" || prop === "entityType" || prop === "complexType" || prop === "getProperty" || prop === "setProperty" || prop === "constructor" || prop.charAt(0) === '_' || prop.charAt(0) === '$') return; return val; } /** Safely perform toJSON logic on objects with cycles. */ function toJSONSafe(obj, replacer) { if (obj !== Object(obj)) return obj; // primitive value if (obj._$visited) return undefined; if (obj.toJSON) { let newObj = obj.toJSON(); if (newObj !== Object(newObj)) return newObj; // primitive value if (newObj !== obj) return toJSONSafe(newObj, replacer); // toJSON returned the object unchanged. obj = newObj; } obj._$visited = true; let result; if (obj instanceof Array) { result = obj.map(function (o) { return toJSONSafe(o, replacer); }); } else if (typeof (obj) === "function") { result = undefined; } else { result = {}; for (let prop in obj) { if (prop === "_$visited") continue; let val = obj[prop]; if (replacer) { val = replacer(prop, val); if (val === undefined) continue; } val = toJSONSafe(val, replacer); if (val === undefined) continue; result[prop] = val; } } delete obj._$visited; return result; } /** Resolves the values of a list of properties by checking each property in multiple sources until a value is found. */ function resolveProperties(sources, propertyNames) { let r = {}; let length = sources.length; propertyNames.forEach(function (pn) { for (let i = 0; i < length; i++) { let src = sources[i]; if (src) { let val = src[pn]; if (val !== undefined) { r[pn] = val; break; } } } }); return r; } // array functions function toArray(item) { if (item == null) { return []; } else if (Array.isArray(item)) { return item; } else { return [item]; } } /** a version of Array.map that doesn't require an array, i.e. works on arrays and scalars. */ // function map<T, U>(items: T | T[], fn: (v: T, ix?: number) => U, includeNull?: boolean): U | U[] { function map(items, fn, includeNull) { // whether to return nulls in array of results; default = true; includeNull = includeNull == null ? true : includeNull; if (items == null) return items; // let result: U[]; if (Array.isArray(items)) { let result = []; items.forEach(function (v, ix) { let r = fn(v, ix); if (r != null || includeNull) { result[ix] = r; } }); return result; } else { let result = fn(items); return result; } } function arrayFirst(array, predicate) { for (let i = 0, j = array.length; i < j; i++) { if (predicate(array[i])) { return array[i]; } } return null; } function arrayIndexOf(array, predicate) { for (let i = 0, j = array.length; i < j; i++) { if (predicate(array[i])) return i; } return -1; } /** Add item if not already in array */ function arrayAddItemUnique(array, item) { let ix = array.indexOf(item); if (ix === -1) array.push(item); } /** Remove items from the array * @param array * @param predicateOrItem - item to remove, or function to determine matching item * @param shouldRemoveMultiple - true to keep removing after first match, false otherwise */ function arrayRemoveItem(array, predicateOrItem, shouldRemoveMultiple) { let predicate = (isFunction(predicateOrItem) ? predicateOrItem : undefined); let lastIx = array.length - 1; let removed = false; for (let i = lastIx; i >= 0; i--) { if (predicate ? predicate(array[i]) : (array[i] === predicateOrItem)) { array.splice(i, 1); removed = true; if (!shouldRemoveMultiple) { return true; } } } return removed; } /** Combine array elements using the callback. Returns array with length == min(a1.length, a2.length) */ function arrayZip(a1, a2, callback) { let result = []; let n = Math.min(a1.length, a2.length); for (let i = 0; i < n; ++i) { result.push(callback(a1[i], a2[i])); } return result; } //function arrayDistinct(array) { // array = array || []; // let result = []; // for (let i = 0, j = array.length; i < j; i++) { // if (result.indexOf(array[i]) < 0) // result.push(array[i]); // } // return result; //} // Not yet needed //// much faster but only works on array items with a toString method that //// returns distinct string for distinct objects. So this is safe for arrays with primitive //// types but not for arrays with object types, unless toString() has been implemented. //function arrayDistinctUnsafe(array) { // let o = {}, i, l = array.length, r = []; // for (i = 0; i < l; i += 1) { // let v = array[i]; // o[v] = v; // } // for (i in o) r.push(o[i]); // return r; //} function arrayEquals(a1, a2, equalsFn) { //Check if the arrays are undefined/null if (!a1 || !a2) return false; if (a1.length !== a2.length) return false; //go thru all the vars for (let i = 0; i < a1.length; i++) { //if the let is an array, we need to make a recursive check //otherwise we'll just compare the values if (Array.isArray(a1[i])) { if (!arrayEquals(a1[i], a2[i])) return false; } else { if (equalsFn) { if (!equalsFn(a1[i], a2[i])) return false; } else { if (a1[i] !== a2[i]) return false; } } } return true; } // end of array functions /** Returns an array for a source and a prop, and creates the prop if needed. */ function getArray(source, propName) { let arr = source[propName]; if (!arr) { arr = []; source[propName] = arr; } return arr; } /** Calls requireLibCore on semicolon-separated libNames */ function requireLib(libNames, errMessage) { let arrNames = libNames.split(";"); for (let i = 0, j = arrNames.length; i < j; i++) { let lib = requireLibCore(arrNames[i]); if (lib) return lib; } if (errMessage) { throw new Error("Unable to initialize " + libNames + ". " + errMessage); } } /** Returns the 'libName' module if loaded or else returns undefined */ function requireLibCore(libName) { let win = window || (global ? global.window : undefined); if (!win) return; // Must run in a browser. Todo: add commonjs support // get library from browser globals if we can let lib = win[libName]; if (lib) return lib; // if require exists, maybe require can get it. // This method is synchronous so it can't load modules with AMD. // It can only obtain modules from require that have already been loaded. // Developer should bootstrap such that the breeze module // loads after all other libraries that breeze should find with this method // See documentation let r = win.require; if (r) { // if require exists if (r.defined) { // require.defined is not standard and may not exist // require.defined returns true if module has been loaded return r.defined(libName) ? r(libName) : undefined; } else { // require.defined does not exist so we have to call require('libName') directly. // The require('libName') overload is synchronous and does not load modules. // It throws an exception if the module isn't already loaded. try { return r(libName); } catch (e) { // require('libName') threw because module not loaded return; } } } } /** Execute fn while obj has tempValue for property */ function using(obj, property, tempValue, fn) { if (!obj) { return fn(); } let originalValue = obj[property]; if (tempValue === originalValue) { return fn(); } obj[property] = tempValue; try { return fn(); } finally { if (originalValue === undefined) { delete obj[property]; } else { obj[property] = originalValue; } } } /** Call state = startFn(), call fn(), call endFn(state) */ function wrapExecution(startFn, endFn, fn) { let state; try { state = startFn(); return fn(); } catch (e) { if (typeof (state) === 'object') { state.error = e; } throw e; } finally { endFn(state); } } /** Remember & return the value of fn() when it was called with its current args */ function memoize(fn) { return function () { let args = arraySlice(arguments), hash = "", i = args.length, currentArg = null; while (i--) { currentArg = args[i]; hash += (currentArg === Object(currentArg)) ? JSON.stringify(currentArg) : currentArg; fn.memoize || (fn.memoize = {}); } return (hash in fn.memoize) ? fn.memoize[hash] : fn.memoize[hash] = fn.apply(this, args); }; } const uuidrex = /[xy]/g; function getUuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(uuidrex, function (c) { // tslint:disable-next-line let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } const durationrex = /^P((\d+Y)?(\d+M)?(\d+D)?)?(T(\d+H)?(\d+M)?(\d+S)?)?$/; const lettersrex = /[A-Za-z]+/g; function durationToSeconds(duration) { // basic algorithm from https://github.com/nezasa/iso8601-js-period if (typeof duration !== "string") throw new Error("Invalid ISO8601 duration '" + duration + "'"); // regex splits as follows - grp0, grp1, y, m, d, grp2, h, m, s // 0 1 2 3 4 5 6 7 8 let struct = durationrex.exec(duration); if (!struct) throw new Error("Invalid ISO8601 duration '" + duration + "'"); let ymdhmsIndexes = [2, 3, 4, 6, 7, 8]; // -> grp1,y,m,d,grp2,h,m,s let factors = [31104000, 2592000, 86400, 3600, 60, 1]; // second (1) let seconds = 0; for (let i = 0; i < 6; i++) { let digit = struct[ymdhmsIndexes[i]]; // remove letters, replace by 0 if not defined digit = (digit ? +digit.replace(lettersrex, '') : 0); seconds += digit * factors[i]; } return seconds; } // is functions function noop() { // does nothing } function identity(x) { return x; } function classof(o) { if (o === null) { return "null"; } if (o === undefined) { return "undefined"; } return Object.prototype.toString.call(o).slice(8, -1).toLowerCase(); } function isDate(o) { return classof(o) === "date" && !isNaN(o.getTime()); } const isdaterex = /^((\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)))$/; function isDateString(s) { // let rx = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/; return (typeof s === "string") && isdaterex.test(s); } function isFunction(o) { return classof(o) === "function"; } // function isString(o: any) { // return (typeof o === "string"); // } // function isObject(o: any) { // return (typeof o === "object"); // } const isguidrex = /^[a-fA-F\d]{8}-(?:[a-fA-F\d]{4}-){3}[a-fA-F\d]{12}$/; function isGuid(value) { return (typeof value === "string") && isguidrex.test(value); } const isdurationrex = /^(-|)?P[T]?[\d\.,\-]+[YMDTHS]/; function isDuration(value) { return (typeof value === "string") && isdurationrex.test(value); } function isEmpty(obj) { if (obj === null || obj === undefined) { return true; } for (let key in obj) { if (hasOwnProperty(obj, key)) { return false; } } return true; } function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } // end of is Functions // string functions function stringStartsWith(str, prefix) { // returns true for empty string or null prefix if ((!str)) return false; if (prefix === "" || prefix == null) return true; return str.indexOf(prefix, 0) === 0; } function stringEndsWith(str, suffix) { // returns true for empty string or null suffix if ((!str)) return false; if (suffix === "" || suffix == null) return true; return str.indexOf(suffix, str.length - suffix.length) !== -1; } // Based on fragment from Dean Edwards' Base 2 library /** format("a %1 and a %2", "cat", "dog") -> "a cat and a dog" */ function formatString(str, ...params) { let args = arguments; let pattern = RegExp("%([1-" + (arguments.length - 1) + "])", "g"); return str.replace(pattern, function (match, index) { return args[index]; }); } // See http://stackoverflow.com/questions/7225407/convert-camelcasetext-to-camel-case-text /** Change text to title case with spaces, e.g. 'myPropertyName12' to 'My Property Name 12' */ const camelEdges = /([A-Z](?=[A-Z][a-z])|[^A-Z](?=[A-Z])|[a-zA-Z](?=[^a-zA-Z]))/g; function titleCaseSpace(text) { text = text.replace(camelEdges, '$1 '); text = text.charAt(0).toUpperCase() + text.slice(1); return text; } // end of string functions // See Mark Miller’s explanation of what this does. // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming function uncurry(f) { let call = Function.call; return function () { return call.apply(f, arguments); }; } // shims if (!Object.create) { Object.create = function (parent) { let F = function () { }; F.prototype = parent; return new F(); }; } // strings for error messages const strings = { "TO_TYPE": "Add 'EntityQuery.toType()' to your query, or call 'MetadataStore.setEntityTypeForResourceName()' to register an EntityType for this resourceName." }; // // not all methods above are exported export const core = { isES5Supported: isES5Supported, hasOwnProperty: hasOwnProperty, getOwnPropertyValues: getOwnPropertyValues, getPropertyDescriptor: getPropDescriptor, objectForEach: objectForEach, objectFirst: objectFirst, objectMap: objectMap, extend: extend, propEq: propEq, propsEq: propsEq, pluck: pluck, map: map, resolveProperties: resolveProperties, setAsDefault: setAsDefault, updateWithDefaults: updateWithDefaults, getArray: getArray, toArray: toArray, arrayEquals: arrayEquals, arraySlice: arraySlice, arrayFirst: arrayFirst, arrayIndexOf: arrayIndexOf, arrayRemoveItem: arrayRemoveItem, arrayZip: arrayZip, arrayAddItemUnique: arrayAddItemUnique, arrayFlatMap: arrayFlatMap, requireLib: requireLib, using: using, wrapExecution: wrapExecution, memoize: memoize, getUuid: getUuid, durationToSeconds: durationToSeconds, isSettable: isSettable, isDate: isDate, isDateString: isDateString, isGuid: isGuid, isDuration: isDuration, isFunction: isFunction, isEmpty: isEmpty, isNumeric: isNumeric, identity: identity, noop: noop, stringStartsWith: stringStartsWith, stringEndsWith: stringEndsWith, formatString: formatString, titleCase: titleCaseSpace, toJson: toJson, toJSONSafe: toJSONSafe, toJSONSafeReplacer: toJSONSafeReplacer, strings: strings }; // Unused /* // returns true for booleans, numbers, strings and dates // false for null, and non-date objects, functions, and arrays function isPrimitive(obj: any) { if (obj == null) return false; // true for numbers, strings, booleans and null, false for objects if (obj != Object(obj)) return true; return isDate(obj); } */ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGtEQUFrRDtBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBZXBDLElBQUksY0FBYyxHQUEwQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUNyRyxJQUFJLFVBQVUsR0FBdUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEcsSUFBSSxjQUFjLEdBQVk7SUFDMUIsSUFBSTtRQUNBLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGNBQWMsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUMxRTtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1IsT0FBTyxLQUFLLENBQUM7S0FDaEI7QUFDTCxDQUFDLEVBQUcsQ0FBQztBQUVMLHNCQUFzQjtBQUN0QixTQUFTLGFBQWEsQ0FBQyxHQUFXLEVBQUUsSUFBb0M7SUFDcEUsS0FBSyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUU7UUFDakIsSUFBSSxjQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQzFCLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdkI7S0FDSjtBQUNMLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxHQUFXLEVBQUUsSUFBcUM7SUFDakUsSUFBSSxPQUFPLEdBQVUsRUFBRSxDQUFDO0lBQ3hCLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFO1FBQ2pCLElBQUksY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUMxQixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElB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WSxFQUFFLFlBQVk7SUFDMUIsZUFBZSxFQUFFLGVBQWU7SUFDaEMsUUFBUSxFQUFFLFFBQVE7SUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0lBQ3RDLFlBQVksRUFBRSxZQUFZO0lBRTFCLFVBQVUsRUFBRSxVQUFVO0lBQ3RCLEtBQUssRUFBRSxLQUFLO0lBQ1osYUFBYSxFQUFFLGFBQWE7SUFFNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsaUJBQWlCLEVBQUUsaUJBQWlCO0lBRXBDLFVBQVUsRUFBRSxVQUFVO0lBRXRCLE1BQU0sRUFBRSxNQUFNO0lBQ2QsWUFBWSxFQUFFLFlBQVk7SUFDMUIsTUFBTSxFQUFFLE1BQU07SUFDZCxVQUFVLEVBQUUsVUFBVTtJQUN0QixVQUFVLEVBQUUsVUFBVTtJQUN0QixPQUFPLEVBQUUsT0FBTztJQUNoQixTQUFTLEVBQUUsU0FBUztJQUVwQixRQUFRLEVBQUUsUUFBUTtJQUNsQixJQUFJLEVBQUUsSUFBSTtJQUVWLGdCQUFnQixFQUFFLGdCQUFnQjtJQUNsQyxjQUFjLEVBQUUsY0FBYztJQUM5QixZQUFZLEVBQUUsWUFBWTtJQUMxQixTQUFTLEVBQUUsY0FBYztJQUV6QixNQUFNLEVBQUUsTUFBTTtJQUNkLFVBQVUsRUFBRSxVQUFVO0lBQ3RCLGtCQUFrQixFQUFFLGtCQUFrQjtJQUV0QyxPQUFPLEVBQUUsT0FBTztDQUNuQixDQUFDO0FBT0YsU0FBUztBQUNUOzs7Ozs7Ozs7O0VBVUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogU2VlIGlmIHRoaXMgY29tbWVudCB3aWxsIG1ha2UgaXQgaW50byAuZC50cyAqL1xyXG5pbXBvcnQgeyBCcmVlemVFbnVtIH0gZnJvbSAnLi9lbnVtJztcclxuZGVjbGFyZSB2YXIgZ2xvYmFsOiBhbnk7XHJcbmRlY2xhcmUgdmFyIHdpbmRvdzogYW55O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBFcnJvckNhbGxiYWNrIHtcclxuICAgIChlcnJvcjogRXJyb3IpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENhbGxiYWNrIHtcclxuICAgIChkYXRhOiBhbnkpOiB2b2lkO1xyXG59XHJcblxyXG4vLyB0eXBlIFByZWRpY2F0ZSA9IChpOiBhbnkpID0+IGJvb2xlYW47XHJcbnR5cGUgUHJlZGljYXRlPFQ+ID0gKGk6IFQpID0+IGJvb2xlYW47XHJcblxyXG5sZXQgaGFzT3duUHJvcGVydHk6IChvYmo6IE9iamVjdCwga2V5OiBzdHJpbmcpID0+IGJvb2xlYW4gPSB1bmN1cnJ5KE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkpO1xyXG5sZXQgYXJyYXlTbGljZTogKGFyOiBhbnlbXSwgc3RhcnQ/OiBudW1iZXIsIGVuZD86IG51bWJlcikgPT4gYW55W10gPSB1bmN1cnJ5KEFycmF5LnByb3RvdHlwZS5zbGljZSk7XHJcbmxldCBpc0VTNVN1cHBvcnRlZDogYm9vbGVhbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuICEhKE9iamVjdC5nZXRQcm90b3R5cGVPZiAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICd4Jywge30pKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn0gKCk7XHJcblxyXG4vLyBpdGVyYXRlIG92ZXIgb2JqZWN0XHJcbmZ1bmN0aW9uIG9iamVjdEZvckVhY2gob2JqOiBPYmplY3QsIGt2Rm46IChrZXk6IHN0cmluZ