foop
Version:
interfaces that describe their intentions.
272 lines (210 loc) • 20.3 kB
JavaScript
// ---
// with a huge refactor to this,
// with tons of safety
// configuration like debugging on condition in certain places
// stacktrace & sourcemap forcing on certain builds
// this would provide a lovely debugging tool
// ---
var reStack = /(?:\n {4}at .*)+/;
var errStack = function (err) {
var stack = err instanceof Error ? err.stack : err;
if (!stack) {
return '';
}
var match = stack.match(reStack);
if (!match) {
return '';
}
return match[0].slice(1);
};
// ---
// https://github.com/ValYouW/njsTrace WRAPS ALL FN1?
// https://github.com/scottnonnenberg/notate/blob/master/src/notate.js#L137
// https://github.com/Breeze/breeze.js.labs/blob/master/breeze.metadata-helper.js
// https://github.com/v8/v8/wiki/Stack-Trace-API
// https://github.com/sindresorhus/callsites
var stacker = function () {
var _ = Error.prepareStackTrace;
Error.prepareStackTrace = function (_, stack) { return stack; };
var stack = new Error().stack.slice(1);
Error.prepareStackTrace = _;
return stack;
};
// ---
var stringify = function (x) {
try {
var str$1 = JSON.stringify(x, null, 2)
return str$1
}
catch (e) {
var str = {}
str.type = Object.prototype.toString.call(x)
for (var prop in x) {
str[prop] = stringify(x[prop])
}
return stringify(x)
}
}
var pretty = function (x) { return stringify(x).replace(/["\\[\]\,\']/g, ''); }
// ---
var weakCache = new WeakMap()
var record = new WeakSet()
var list = new Set()
var cache = new Map()
function debuggableStorage(x) {
if (weakCache.has(x)) { weakCache.get(x).count += 1 }
else { weakCache.set(x, x) }
if (cache.has(x)) { cache.get(x).count += 1 }
else { cache.set(x, x) }
list.add(x)
record.add(x)
return debuggable
}
// ---
function metadata() {
var time = Date.now()
var count = 0
return {time: time, count: count}
}
// ---
function stackAt(index) {
if ( index === void 0 ) index = 1;
var stacks = stacker()
var stack = stacks[index]
var meta = {}
// huge
meta.thisArg = stack.getThis()
meta.fn = stack.getFunction()
// helpful
meta.methodName = stack.getMethodName()
meta.typeName = stack.getTypeName()
meta.functionName = stack.getFunctionName()
// file
meta.fileName = stack.getFileName()
meta.lineNumber = stack.getLineNumber()
meta.columnNumber = stack.getColumnNumber()
meta.origin = stack.getEvalOrigin()
// bools
var stackIs = {
topLevel: stack.isToplevel(),
constructor: stack.isConstructor(),
native: stack.isNative(),
}
var topLevel = stackIs.topLevel;
var constructor = stackIs.constructor;
var native = stackIs.native;
var methodName = meta.methodName;
var functionName = meta.functionName;
var thisArg = meta.thisArg;
var fn = meta.fn;
var fileName = meta.fileName;
var lineNumber = meta.lineNumber;
var columnNumber = meta.columnNumber;
var origin = meta.origin;
var called = {functionName: functionName, methodName: methodName, fileName: fileName, lineNumber: lineNumber}
if (topLevel || constructor || native) {
called.is = stackIs
}
if (origin != fileName) {
called.origin = origin
}
if (called.thisArg === global) { called.thisArg = 'global' }
return called
}
// could clone the data too
function debuggable() {
var stack = stackAt(2)
var meta = metadata()
var result = Object.assign({}, stack, {}, meta)
result.args = arguments
result.str = arguments.length !== 0 ? stringify(arguments) : '0 args'
debuggableStorage(result)
return result
}
debuggable.list = list
debuggable.record = record
debuggable.cache = cache
debuggable.metadata = metadata
debuggable.stackAt = stackAt
// ---
// where, pluck, evolve
debuggable.values = function(cb) {
var values = Array.from(debuggable.list.values())
// for entries
// let index = 0
// const keys = Object.keys(where)
// .reduce(function(reduced, value) {
// reduced[index++] = next
// return reduced
// }, {})
if (cb) { return cb(values) }
else { return values }
}
debuggable.where = function(where) {
return debuggable.values().filter(where)
}
var queryable = [
'functionName',
'methodName',
'fileName',
'lineNumber',
'count',
'args',
'str',
'time'
]
// ---
// filter, unique keys, index of the values with the uniq keys
// debuggable.keys()
// --- example ---
// function gogo() {
// debuggable(arguments)
// }
// class Go {}
// Go.prototype.gogo = gogo
// Go.prototype.zoomzoon = function() {
// debuggable(arguments)
// }
// // gogo()
// new Go().gogo()
// new Go().gogo(1)
// new Go().gogo(1)
// new Go().zoomzoom('heyya')
// -----
// functionName: 'gogo',
// methodName: 'gogo',
// fileName: '_play.js',
// lineNumber: 189,
// count: 0,
// args: { '0': [Object] },
// str: '{\n "0": {\n "0": 1\n }\n}' } => { functionName: 'gogo',
// const values = debuggable.values()
// const R = require('ramda')
// const propped = R.props(['functionName', 'methodName'], values)
// const result = R.where(R.contains('zoomzoom'), propped)
// console.log({result, propped})
// debuggable.cache.forEach(eh => console.log('list', eh))
// console.log(cache)
// @example ramda filtering
// const vals = Array.from(debuggable.values())
// const propped = vals.map(val => R.props(['functionName', 'methodName'], val))
// const funcLens = R.lensProp('functionName')
// const funcWhere = R.where(funcLens, R.contains('zoomzoom'))
// const funcSatisfies = R.where({
// functionName: R.equals('zoomzoom'),
// })
// const evolved = vals.map(val => {
// const lensed = R.view(funcLens, val)
// const satisfies = funcSatisfies(val)
// // console.log({lensed, satisfies, val})
// if (satisfies) return R.evolve({functionName: R.identity}, val)
// else return false
// })
// .filter(Boolean)
// // .map(v => v[0] && v[1] ? R.fromPairs(v): v)
// const result = R.where(R.contains('zoomzoom'), propped)
// // console.log('eh', propped)
// // console.log({result, propped, vals})
// console.log(evolved)
module.exports = debuggable
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWdnYWJsZS5qcyIsInNvdXJjZXMiOlsiZGVidWdnYWJsZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8vIC0tLVxuXG4vLyB3aXRoIGEgaHVnZSByZWZhY3RvciB0byB0aGlzLCBcbi8vIHdpdGggdG9ucyBvZiBzYWZldHlcbi8vIGNvbmZpZ3VyYXRpb24gbGlrZSBkZWJ1Z2dpbmcgb24gY29uZGl0aW9uIGluIGNlcnRhaW4gcGxhY2VzXG4vLyBzdGFja3RyYWNlICYgc291cmNlbWFwIGZvcmNpbmcgb24gY2VydGFpbiBidWlsZHNcbi8vIHRoaXMgd291bGQgcHJvdmlkZSBhIGxvdmVseSBkZWJ1Z2dpbmcgdG9vbFxuXG4vLyAtLS1cbmNvbnN0IHJlU3RhY2sgPSAvKD86XFxuIHs0fWF0IC4qKSsvO1xuY29uc3QgZXJyU3RhY2sgPSBlcnIgPT4ge1xuXHRjb25zdCBzdGFjayA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnN0YWNrIDogZXJyO1xuXG5cdGlmICghc3RhY2spIHtcblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuXHRjb25zdCBtYXRjaCA9IHN0YWNrLm1hdGNoKHJlU3RhY2spO1xuXG5cdGlmICghbWF0Y2gpIHtcblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuICByZXR1cm4gbWF0Y2hbMF0uc2xpY2UoMSk7XG59O1xuXG4vLyAtLS1cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9WYWxZb3VXL25qc1RyYWNlIFdSQVBTIEFMTCBGTjE/XG4vLyBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRub25uZW5iZXJnL25vdGF0ZS9ibG9iL21hc3Rlci9zcmMvbm90YXRlLmpzI0wxMzdcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9CcmVlemUvYnJlZXplLmpzLmxhYnMvYmxvYi9tYXN0ZXIvYnJlZXplLm1ldGFkYXRhLWhlbHBlci5qc1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3Y4L3Y4L3dpa2kvU3RhY2stVHJhY2UtQVBJXG4vLyBodHRwczovL2dpdGh1Yi5jb20vc2luZHJlc29yaHVzL2NhbGxzaXRlc1xuY29uc3Qgc3RhY2tlciA9ICgpID0+IHtcblx0Y29uc3QgXyA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlO1xuXHRFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IChfLCBzdGFjaykgPT4gc3RhY2s7XG5cdGNvbnN0IHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2suc2xpY2UoMSk7XG5cdEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gXztcblx0cmV0dXJuIHN0YWNrO1xufTtcblxuLy8gLS0tXG52YXIgc3RyaW5naWZ5ID0geCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gSlNPTi5zdHJpbmdpZnkoeCwgbnVsbCwgMilcbiAgICByZXR1cm4gc3RyXG4gIH1cbiAgY2F0Y2ggKGUpIHtcbiAgICB2YXIgc3RyID0ge31cbiAgICBzdHIudHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KVxuICAgIGZvciAodmFyIHByb3AgaW4geCkge1xuICAgICAgc3RyW3Byb3BdID0gc3RyaW5naWZ5KHhbcHJvcF0pXG4gICAgfVxuICAgIHJldHVybiBzdHJpbmdpZnkoeClcbiAgfVxufVxuXG52YXIgcHJldHR5ID0geCA9PiBzdHJpbmdpZnkoeCkucmVwbGFjZSgvW1wiXFxcXFtcXF1cXCxcXCddL2csICcnKVxuXG4vLyAtLS1cblxudmFyIHdlYWtDYWNoZSA9IG5ldyBXZWFrTWFwKClcbnZhciByZWNvcmQgPSBuZXcgV2Vha1NldCgpXG52YXIgbGlzdCA9IG5ldyBTZXQoKVxudmFyIGNhY2hlID0gbmV3IE1hcCgpXG5cbmZ1bmN0aW9uIGRlYnVnZ2FibGVTdG9yYWdlKHgpIHtcbiAgaWYgKHdlYWtDYWNoZS5oYXMoeCkpIHdlYWtDYWNoZS5nZXQoeCkuY291bnQgKz0gMSBcbiAgZWxzZSB3ZWFrQ2FjaGUuc2V0KHgsIHgpXG4gIFxuICBpZiAoY2FjaGUuaGFzKHgpKSBjYWNoZS5nZXQoeCkuY291bnQgKz0gMSBcbiAgZWxzZSBjYWNoZS5zZXQoeCwgeClcbiAgICBcbiAgbGlzdC5hZGQoeClcbiAgcmVjb3JkLmFkZCh4KVxuICByZXR1cm4gZGVidWdnYWJsZVxufVxuXG4vLyAtLS1cblxuZnVuY3Rpb24gbWV0YWRhdGEoKSB7XG4gIGNvbnN0IHRpbWUgPSBEYXRlLm5vdygpXG4gIGNvbnN0IGNvdW50ID0gMFxuICByZXR1cm4ge3RpbWUsIGNvdW50fVxufVxuXG4vLyAtLS1cblxuZnVuY3Rpb24gc3RhY2tBdChpbmRleCA9IDEpIHtcbiAgY29uc3Qgc3RhY2tzID0gc3RhY2tlcigpXG4gIGNvbnN0IHN0YWNrID0gc3RhY2tzW2luZGV4XVxuICBjb25zdCBtZXRhID0ge31cblxuICAvLyBodWdlXG4gIG1ldGEudGhpc0FyZyA9IHN0YWNrLmdldFRoaXMoKVxuICBtZXRhLmZuID0gc3RhY2suZ2V0RnVuY3Rpb24oKVxuXG4gIC8vIGhlbHBmdWxcbiAgbWV0YS5tZXRob2ROYW1lID0gc3RhY2suZ2V0TWV0aG9kTmFtZSgpXG4gIG1ldGEudHlwZU5hbWUgPSBzdGFjay5nZXRUeXBlTmFtZSgpXG4gIG1ldGEuZnVuY3Rpb25OYW1lID0gc3RhY2suZ2V0RnVuY3Rpb25OYW1lKClcbiAgXG4gIC8vIGZpbGVcbiAgbWV0YS5maWxlTmFtZSA9IHN0YWNrLmdldEZpbGVOYW1lKCkgXG4gIG1ldGEubGluZU51bWJlciA9IHN0YWNrLmdldExpbmVOdW1iZXIoKVxuICBtZXRhLmNvbHVtbk51bWJlciA9IHN0YWNrLmdldENvbHVtbk51bWJlcigpXG4gIG1ldGEub3JpZ2luID0gc3RhY2suZ2V0RXZhbE9yaWdpbigpXG5cbiAgLy8gYm9vbHNcbiAgY29uc3Qgc3RhY2tJcyA9IHtcbiAgICB0b3BMZXZlbDogc3RhY2suaXNUb3BsZXZlbCgpLFxuICAgIGNvbnN0cnVjdG9yOiBzdGFjay5pc0NvbnN0cnVjdG9yKCksXG4gICAgbmF0aXZlOiBzdGFjay5pc05hdGl2ZSgpLFxuICB9XG5cbiAgY29uc3Qge1xuICAgIHRvcExldmVsLCBcbiAgICBjb25zdHJ1Y3RvciwgXG4gICAgbmF0aXZlLFxuICB9ID0gc3RhY2tJc1xuICBjb25zdCB7XG4gICAgbWV0aG9kTmFtZSwgXG4gICAgZnVuY3Rpb25OYW1lLFxuICAgIHRoaXNBcmcsIFxuICAgIGZuLCBcbiAgICBmaWxlTmFtZSwgXG4gICAgbGluZU51bWJlciwgXG4gICAgY29sdW1uTnVtYmVyLCBcbiAgICBvcmlnaW4sXG4gIH0gPSBtZXRhXG5cbiAgbGV0IGNhbGxlZCA9IHtmdW5jdGlvbk5hbWUsIG1ldGhvZE5hbWUsIGZpbGVOYW1lLCBsaW5lTnVtYmVyfVxuXG4gIGlmICh0b3BMZXZlbCB8fCBjb25zdHJ1Y3RvciB8fCBuYXRpdmUpIHtcbiAgICBjYWxsZWQuaXMgPSBzdGFja0lzXG4gIH1cbiAgXG4gIGlmIChvcmlnaW4gIT0gZmlsZU5hbWUpIHtcbiAgICBjYWxsZWQub3JpZ2luID0gb3JpZ2luXG4gIH1cblxuICBpZiAoY2FsbGVkLnRoaXNBcmcgPT09IGdsb2JhbCkgY2FsbGVkLnRoaXNBcmcgPSAnZ2xvYmFsJ1xuXG4gIHJldHVybiBjYWxsZWRcbn1cblxuLy8gY291bGQgY2xvbmUgdGhlIGRhdGEgdG9vXG5mdW5jdGlvbiBkZWJ1Z2dhYmxlKCkge1xuICBjb25zdCBzdGFjayA9IHN0YWNrQXQoMilcbiAgY29uc3QgbWV0YSA9IG1ldGFkYXRhKClcbiAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhY2ssIHt9LCBtZXRhKVxuICByZXN1bHQuYXJncyA9IGFyZ3VtZW50cyBcbiAgcmVzdWx0LnN0ciA9IGFyZ3VtZW50cy5sZW5ndGggIT09IDAgPyBzdHJpbmdpZnkoYXJndW1lbnRzKSA6ICcwIGFyZ3MnXG5cbiAgZGVidWdnYWJsZVN0b3JhZ2UocmVzdWx0KVxuXG4gIHJldHVybiByZXN1bHRcbn1cbmRlYnVnZ2FibGUubGlzdCA9IGxpc3RcbmRlYnVnZ2FibGUucmVjb3JkID0gcmVjb3JkXG5kZWJ1Z2dhYmxlLmNhY2hlID0gY2FjaGVcbmRlYnVnZ2FibGUubWV0YWRhdGEgPSBtZXRhZGF0YVxuZGVidWdnYWJsZS5zdGFja0F0ID0gc3RhY2tBdFxuXG4vLyAtLS1cblxuLy8gd2hlcmUsIHBsdWNrLCBldm9sdmVcbmRlYnVnZ2FibGUudmFsdWVzID0gZnVuY3Rpb24oY2IpIHtcbiAgY29uc3QgdmFsdWVzID0gQXJyYXkuZnJvbShkZWJ1Z2dhYmxlLmxpc3QudmFsdWVzKCkpXG5cbiAgLy8gZm9yIGVudHJpZXNcbiAgLy8gbGV0IGluZGV4ID0gMFxuICAvLyBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMod2hlcmUpXG4gIC8vIC5yZWR1Y2UoZnVuY3Rpb24ocmVkdWNlZCwgdmFsdWUpIHtcbiAgLy8gICByZWR1Y2VkW2luZGV4KytdID0gbmV4dFxuICAvLyAgIHJldHVybiByZWR1Y2VkXG4gIC8vIH0sIHt9KVxuXG4gIGlmIChjYikgcmV0dXJuIGNiKHZhbHVlcylcbiAgZWxzZSByZXR1cm4gdmFsdWVzXG59XG5cbmRlYnVnZ2FibGUud2hlcmUgPSBmdW5jdGlvbih3aGVyZSkge1xuICByZXR1cm4gZGVidWdnYWJsZS52YWx1ZXMoKS5maWx0ZXIod2hlcmUpXG59XG5cbnZhciBxdWVyeWFibGUgPSBbXG4gICdmdW5jdGlvbk5hbWUnLFxuICAgJ21ldGhvZE5hbWUnLFxuICAgJ2ZpbGVOYW1lJyxcbiAgICdsaW5lTnVtYmVyJyxcbiAgICdjb3VudCcsXG4gICAnYXJncycsXG4gICAnc3RyJyxcbiAgICd0aW1lJ1xuICBdXG5cbi8vIC0tLVxuXG4vLyBmaWx0ZXIsIHVuaXF1ZSBrZXlzLCBpbmRleCBvZiB0aGUgdmFsdWVzIHdpdGggdGhlIHVuaXEga2V5c1xuLy8gZGVidWdnYWJsZS5rZXlzKClcblxuXG4vLyAtLS0gZXhhbXBsZSAtLS1cblxuLy8gZnVuY3Rpb24gZ29nbygpIHtcbi8vICAgZGVidWdnYWJsZShhcmd1bWVudHMpXG4vLyB9XG5cbi8vIGNsYXNzIEdvIHt9XG4vLyBHby5wcm90b3R5cGUuZ29nbyA9IGdvZ29cbi8vIEdvLnByb3RvdHlwZS56b29tem9vbiA9IGZ1bmN0aW9uKCkge1xuLy8gICBkZWJ1Z2dhYmxlKGFyZ3VtZW50cylcbi8vIH1cblxuLy8gLy8gZ29nbygpXG4vLyBuZXcgR28oKS5nb2dvKClcbi8vIG5ldyBHbygpLmdvZ28oMSlcbi8vIG5ldyBHbygpLmdvZ28oMSlcbi8vIG5ldyBHbygpLnpvb216b29tKCdoZXl5YScpXG5cbi8vIC0tLS0tXG5cbi8vIGZ1bmN0aW9uTmFtZTogJ2dvZ28nLFxuLy8gbWV0aG9kTmFtZTogJ2dvZ28nLFxuLy8gZmlsZU5hbWU6ICdfcGxheS5qcycsXG4vLyBsaW5lTnVtYmVyOiAxODksXG4vLyBjb3VudDogMCxcbi8vIGFyZ3M6IHsgJzAnOiBbT2JqZWN0XSB9LFxuLy8gc3RyOiAne1xcbiAgXCIwXCI6IHtcXG4gICAgXCIwXCI6IDFcXG4gIH1cXG59JyB9ID0+IHsgZnVuY3Rpb25OYW1lOiAnZ29nbycsXG5cbi8vIGNvbnN0IHZhbHVlcyA9IGRlYnVnZ2FibGUudmFsdWVzKClcbi8vIGNvbnN0IFIgPSByZXF1aXJlKCdyYW1kYScpXG4vLyBjb25zdCBwcm9wcGVkID0gUi5wcm9wcyhbJ2Z1bmN0aW9uTmFtZScsICdtZXRob2ROYW1lJ10sIHZhbHVlcylcbi8vIGNvbnN0IHJlc3VsdCA9IFIud2hlcmUoUi5jb250YWlucygnem9vbXpvb20nKSwgcHJvcHBlZClcblxuLy8gY29uc29sZS5sb2coe3Jlc3VsdCwgcHJvcHBlZH0pXG5cbi8vIGRlYnVnZ2FibGUuY2FjaGUuZm9yRWFjaChlaCA9PiBjb25zb2xlLmxvZygnbGlzdCcsIGVoKSlcbi8vIGNvbnNvbGUubG9nKGNhY2hlKVxuXG4vLyBAZXhhbXBsZSByYW1kYSBmaWx0ZXJpbmcgXG5cbi8vIGNvbnN0IHZhbHMgPSBBcnJheS5mcm9tKGRlYnVnZ2FibGUudmFsdWVzKCkpXG4vLyBjb25zdCBwcm9wcGVkID0gdmFscy5tYXAodmFsID0+IFIucHJvcHMoWydmdW5jdGlvbk5hbWUnLCAnbWV0aG9kTmFtZSddLCB2YWwpKVxuXG4vLyBjb25zdCBmdW5jTGVucyA9IFIubGVuc1Byb3AoJ2Z1bmN0aW9uTmFtZScpXG4vLyBjb25zdCBmdW5jV2hlcmUgPSBSLndoZXJlKGZ1bmNMZW5zLCBSLmNvbnRhaW5zKCd6b29tem9vbScpKVxuLy8gY29uc3QgZnVuY1NhdGlzZmllcyA9IFIud2hlcmUoe1xuLy8gICAgIGZ1bmN0aW9uTmFtZTogUi5lcXVhbHMoJ3pvb216b29tJyksXG4vLyAgIH0pXG5cbi8vIGNvbnN0IGV2b2x2ZWQgPSB2YWxzLm1hcCh2YWwgPT4ge1xuICBcbi8vICAgY29uc3QgbGVuc2VkID0gUi52aWV3KGZ1bmNMZW5zLCB2YWwpXG4vLyAgIGNvbnN0IHNhdGlzZmllcyA9IGZ1bmNTYXRpc2ZpZXModmFsKVxuICBcbi8vICAgLy8gY29uc29sZS5sb2coe2xlbnNlZCwgc2F0aXNmaWVzLCB2YWx9KVxuICBcbi8vICAgaWYgKHNhdGlzZmllcykgcmV0dXJuIFIuZXZvbHZlKHtmdW5jdGlvbk5hbWU6IFIuaWRlbnRpdHl9LCB2YWwpXG4vLyAgIGVsc2UgcmV0dXJuIGZhbHNlXG4vLyB9KVxuLy8gLmZpbHRlcihCb29sZWFuKVxuXG4vLyAvLyAubWFwKHYgPT4gdlswXSAmJiB2WzFdID8gUi5mcm9tUGFpcnModik6IHYpXG4vLyBjb25zdCByZXN1bHQgPSBSLndoZXJlKFIuY29udGFpbnMoJ3pvb216b29tJyksIHByb3BwZWQpXG5cbi8vIC8vIGNvbnNvbGUubG9nKCdlaCcsIHByb3BwZWQpXG5cbi8vIC8vIGNvbnNvbGUubG9nKHtyZXN1bHQsIHByb3BwZWQsIHZhbHN9KVxuLy8gY29uc29sZS5sb2coZXZvbHZlZClcblxubW9kdWxlLmV4cG9ydHMgPSBkZWJ1Z2dhYmxlIl0sIm5hbWVzIjpbImNvbnN0Iiwic3RyIiwibGV0Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztBQVVBQSxHQUFLLENBQUMsT0FBTyxHQUFHLGtCQUFrQixDQUFDO0FBQ25DQSxHQUFLLENBQUMsUUFBUSxHQUFHLFVBQUEsR0FBRyxDQUFBLENBQUMsQUFBRztDQUN2QkEsR0FBSyxDQUFDLEtBQUss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