foop
Version:
interfaces that describe their intentions.
178 lines (160 loc) • 14.2 kB
JavaScript
/**
* @name matcher
* @member matcher
* @see https://github.com/sindresorhus/matcher/blob/master/index.js
* @symb 🎯
* @types matcher
* @tests deps/matcher
*/
var ObjectAssign = require('../util/assign')
var isMatcher = require('../is/matcher')
var cache = require('../cache')
var toarr = require('../to-arr')
var newRegExp = require('../construct/regexp')
var pipe = require('../fp/pipeTwo')
var toEscapedRegExp = require('../cast/toRegExp')
var replaceEscapedStar = require('../string/escapedToDotStar')
var escapeStringRegExp = require('../string/escapeRegExp')
var esc = pipe(escapeStringRegExp, replaceEscapedStar)
var m = {}
/**
* @desc turn any string[], function[], or RegExp[] into a matcher
* @memberOf matcher
* @since 3.0.0
* @func make
*
* @param {Array<string> | string | Function | RegExp} pattern a matchable pattern
* @param {boolean | undefined} shouldNegate turn into a negated regex
* @param {boolean | undefined} alphaOmega should have regex start at the beginning and the end
* @return {Array<string> | string | Function | RegExp} matchable
*
* @example
*
* matcher.make('*')
* //=> RegExp('.*', 'i')
*
* @example
*
* var any = new RgExp('.*', 'i')
* matcher.make(any)
* //=> any
*
* @example
*
* var strings = x => typeof x === 'string'
* matcher.make(strings)
* //=> {test: strings}
*
* @example
*
* var tester = {test: x => x === true}
* matcher.make(tester)
* //=> tester
*
* @example
*
* var noName = '!name'
* matcher.make(noName, true)
* //=> new RegExp('(?:name)', 'i')
*
* @example
*
* var noName = '!name'
* matcher.make(noName, true, true)
* //=> new RegExp('^(?:name)$', 'i')
*
*/
m.make = function (pattern, shouldNegate, alphaOmega) {
if (cache.has(pattern)) { return cache.get(pattern) }
var matchable = pattern
if (isMatcher(matchable) && !matchable.test) { matchable.test = matchable }
if (isMatcher(matchable)) { return matchable }
// if (!matchable) {
// console.log({pattern, shouldNegate, alphaOmega})
// throw new Error('eh')
// }
var negated = matchable[0] === '!'
if (negated) { matchable = matchable.slice(1) }
matchable = esc(matchable)
if (negated && shouldNegate) { matchable = "(?!" + matchable + ")" }
if (alphaOmega) { matchable = "^" + matchable + "$" }
matchable = newRegExp(("" + matchable), 'i')
matchable.negated = negated
cache.set(pattern, matchable)
return matchable
}
/**
* @desc same as .make but also accepts inputs, and returns an array
* @memberOf matcher
* @func match
* @since 3.0.0
*
* @param {Array<string> | string} inputs input to use patterns as predicates on
* @param {Array<string> | string | Function | RegExp} patterns predicates to match with, transformed to Matcher
* @param {boolean | undefined} shouldNegate should negate, passed to matcher.make
* @param {boolean | undefined} alphaOmega should enforce regex @beginning and end, passed to .matcher
* @return {Array<any>}
*
* @see Matcher.make
* @see compose/Observe
*
* @example
*
*
* matcher(['foo', 'bar', 'moo'], ['*oo', '!foo']);
* //=> ['moo']
*
* matcher(['foo', 'bar', 'moo'], ['!*oo']);
*
*
* @example
*
*
* matcher('kinga', 'kinga')
* //=> ['kinga']
* matcher('k*nga', 'kinga')
* //=> ['kinga']
* matcher('kinga', 'nope')
* //=> []
*
* matcher(new RegExp(/kinga/), 'kinga')
* //=> ['kinga']
* matcher(new RegExp(/kinga/), 'nope')
* //=> ['nope']
*
* matcher(x => x === 'kinga', 'kinga')
* //=> ['kinga']
* matcher(x => x === 'kinga', 'nope')
* //=> []
*
* matcher({test: x => x === 'kinga'}, 'kinga')
* //=> ['kinga']
* matcher({test: x => x === 'kinga'}, 'nope')
* //=> []
*
*
*/
m.matcher = function (inputs, patterns, shouldNegate, alphaOmega) {
patterns = toarr(patterns).map(function (p) { return m.make(p, shouldNegate, alphaOmega); })
inputs = toarr(inputs)
var firstNegated = patterns[0].negated
var matchesToReturn = []
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i]
// If first pattern is negated we include everything to match user expectation
var matches = firstNegated
for (var j = 0; j < patterns.length; j++) {
if (patterns[j].test(input)) {
matches = !patterns[j].negated
}
}
if (matches) { matchesToReturn.push(input) }
}
return matchesToReturn
}
/**
* @TODO replace to-test
*/
// m.test = (inputs, patterns) => m.matcher(inputs, patterns).length !== 0
module.exports = ObjectAssign(m.matcher, m)
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0Y2hlci5qcyIsInNvdXJjZXMiOlsibWF0Y2hlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBuYW1lIG1hdGNoZXJcbiAqIEBtZW1iZXIgbWF0Y2hlclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vc2luZHJlc29yaHVzL21hdGNoZXIvYmxvYi9tYXN0ZXIvaW5kZXguanNcbiAqIEBzeW1iIPCfjq9cbiAqIEB0eXBlcyBtYXRjaGVyXG4gKiBAdGVzdHMgZGVwcy9tYXRjaGVyXG4gKi9cblxuY29uc3QgT2JqZWN0QXNzaWduID0gcmVxdWlyZSgnLi4vdXRpbC9hc3NpZ24nKVxuY29uc3QgaXNNYXRjaGVyID0gcmVxdWlyZSgnLi4vaXMvbWF0Y2hlcicpXG5jb25zdCBjYWNoZSA9IHJlcXVpcmUoJy4uL2NhY2hlJylcbmNvbnN0IHRvYXJyID0gcmVxdWlyZSgnLi4vdG8tYXJyJylcbmNvbnN0IG5ld1JlZ0V4cCA9IHJlcXVpcmUoJy4uL2NvbnN0cnVjdC9yZWdleHAnKVxuY29uc3QgcGlwZSA9IHJlcXVpcmUoJy4uL2ZwL3BpcGVUd28nKVxuY29uc3QgdG9Fc2NhcGVkUmVnRXhwID0gcmVxdWlyZSgnLi4vY2FzdC90b1JlZ0V4cCcpXG5jb25zdCByZXBsYWNlRXNjYXBlZFN0YXIgPSByZXF1aXJlKCcuLi9zdHJpbmcvZXNjYXBlZFRvRG90U3RhcicpXG5jb25zdCBlc2NhcGVTdHJpbmdSZWdFeHAgPSByZXF1aXJlKCcuLi9zdHJpbmcvZXNjYXBlUmVnRXhwJylcblxuY29uc3QgZXNjID0gcGlwZShlc2NhcGVTdHJpbmdSZWdFeHAsIHJlcGxhY2VFc2NhcGVkU3RhcilcblxuY29uc3QgbSA9IHt9XG5cbi8qKlxuICogQGRlc2MgdHVybiBhbnkgc3RyaW5nW10sIGZ1bmN0aW9uW10sIG9yIFJlZ0V4cFtdIGludG8gYSBtYXRjaGVyXG4gKiBAbWVtYmVyT2YgbWF0Y2hlclxuICogQHNpbmNlIDMuMC4wXG4gKiBAZnVuYyBtYWtlXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPiB8IHN0cmluZyB8IEZ1bmN0aW9uIHwgUmVnRXhwfSBwYXR0ZXJuIGEgbWF0Y2hhYmxlIHBhdHRlcm5cbiAqIEBwYXJhbSAge2Jvb2xlYW4gfCB1bmRlZmluZWR9IHNob3VsZE5lZ2F0ZSB0dXJuIGludG8gYSBuZWdhdGVkIHJlZ2V4XG4gKiBAcGFyYW0gIHtib29sZWFuIHwgdW5kZWZpbmVkfSBhbHBoYU9tZWdhIHNob3VsZCBoYXZlIHJlZ2V4IHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgYW5kIHRoZSBlbmRcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZz4gfCBzdHJpbmcgfCBGdW5jdGlvbiB8IFJlZ0V4cH0gbWF0Y2hhYmxlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICBtYXRjaGVyLm1ha2UoJyonKVxuICogICAgLy89PiBSZWdFeHAoJy4qJywgJ2knKVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogICAgdmFyIGFueSA9IG5ldyBSZ0V4cCgnLionLCAnaScpXG4gKiAgICBtYXRjaGVyLm1ha2UoYW55KVxuICogICAgLy89PiBhbnlcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIHZhciBzdHJpbmdzID0geCA9PiB0eXBlb2YgeCA9PT0gJ3N0cmluZydcbiAqICAgIG1hdGNoZXIubWFrZShzdHJpbmdzKVxuICogICAgLy89PiB7dGVzdDogc3RyaW5nc31cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIHZhciB0ZXN0ZXIgPSB7dGVzdDogeCA9PiB4ID09PSB0cnVlfVxuICogICAgbWF0Y2hlci5tYWtlKHRlc3RlcilcbiAqICAgIC8vPT4gdGVzdGVyXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICB2YXIgbm9OYW1lID0gJyFuYW1lJ1xuICogICAgbWF0Y2hlci5tYWtlKG5vTmFtZSwgdHJ1ZSlcbiAqICAgIC8vPT4gbmV3IFJlZ0V4cCgnKD86bmFtZSknLCAnaScpXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICB2YXIgbm9OYW1lID0gJyFuYW1lJ1xuICogICAgbWF0Y2hlci5tYWtlKG5vTmFtZSwgdHJ1ZSwgdHJ1ZSlcbiAqICAgIC8vPT4gbmV3IFJlZ0V4cCgnXig/Om5hbWUpJCcsICdpJylcbiAqXG4gKi9cbm0ubWFrZSA9IChwYXR0ZXJuLCBzaG91bGROZWdhdGUsIGFscGhhT21lZ2EpID0+IHtcbiAgaWYgKGNhY2hlLmhhcyhwYXR0ZXJuKSkgcmV0dXJuIGNhY2hlLmdldChwYXR0ZXJuKVxuXG4gIGxldCBtYXRjaGFibGUgPSBwYXR0ZXJuXG4gIGlmIChpc01hdGNoZXIobWF0Y2hhYmxlKSAmJiAhbWF0Y2hhYmxlLnRlc3QpIG1hdGNoYWJsZS50ZXN0ID0gbWF0Y2hhYmxlXG4gIGlmIChpc01hdGNoZXIobWF0Y2hhYmxlKSkgcmV0dXJuIG1hdGNoYWJsZVxuXG4gIC8vIGlmICghbWF0Y2hhYmxlKSB7XG4gIC8vICAgY29uc29sZS5sb2coe3BhdHRlcm4sIHNob3VsZE5lZ2F0ZSwgYWxwaGFPbWVnYX0pXG4gIC8vICAgdGhyb3cgbmV3IEVycm9yKCdlaCcpXG4gIC8vIH1cbiAgbGV0IG5lZ2F0ZWQgPSBtYXRjaGFibGVbMF0gPT09ICchJ1xuICBpZiAobmVnYXRlZCkgbWF0Y2hhYmxlID0gbWF0Y2hhYmxlLnNsaWNlKDEpXG5cbiAgbWF0Y2hhYmxlID0gZXNjKG1hdGNoYWJsZSlcblxuICBpZiAobmVnYXRlZCAmJiBzaG91bGROZWdhdGUpIG1hdGNoYWJsZSA9IGAoPyEke21hdGNoYWJsZX0pYFxuICBpZiAoYWxwaGFPbWVnYSkgbWF0Y2hhYmxlID0gYF4ke21hdGNoYWJsZX0kYFxuXG4gIG1hdGNoYWJsZSA9IG5ld1JlZ0V4cChgJHttYXRjaGFibGV9YCwgJ2knKVxuICBtYXRjaGFibGUubmVnYXRlZCA9IG5lZ2F0ZWRcblxuICBjYWNoZS5zZXQocGF0dGVybiwgbWF0Y2hhYmxlKVxuICByZXR1cm4gbWF0Y2hhYmxlXG59XG5cbi8qKlxuICogQGRlc2Mgc2FtZSBhcyAubWFrZSBidXQgYWxzbyBhY2NlcHRzIGlucHV0cywgYW5kIHJldHVybnMgYW4gYXJyYXlcbiAqIEBtZW1iZXJPZiBtYXRjaGVyXG4gKiBAZnVuYyBtYXRjaFxuICogQHNpbmNlIDMuMC4wXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPiB8IHN0cmluZ30gaW5wdXRzIGlucHV0IHRvIHVzZSBwYXR0ZXJucyBhcyBwcmVkaWNhdGVzIG9uXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+IHwgc3RyaW5nIHwgRnVuY3Rpb24gfCBSZWdFeHB9IHBhdHRlcm5zIHByZWRpY2F0ZXMgdG8gbWF0Y2ggd2l0aCwgdHJhbnNmb3JtZWQgdG8gTWF0Y2hlclxuICogQHBhcmFtICB7Ym9vbGVhbiB8IHVuZGVmaW5lZH0gc2hvdWxkTmVnYXRlIHNob3VsZCBuZWdhdGUsIHBhc3NlZCB0byBtYXRjaGVyLm1ha2VcbiAqIEBwYXJhbSAge2Jvb2xlYW4gfCB1bmRlZmluZWR9IGFscGhhT21lZ2Egc2hvdWxkIGVuZm9yY2UgcmVnZXggQGJlZ2lubmluZyBhbmQgZW5kLCBwYXNzZWQgdG8gLm1hdGNoZXJcbiAqIEByZXR1cm4ge0FycmF5PGFueT59XG4gKlxuICogQHNlZSBNYXRjaGVyLm1ha2VcbiAqIEBzZWUgY29tcG9zZS9PYnNlcnZlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKlxuICogICBtYXRjaGVyKFsnZm9vJywgJ2JhcicsICdtb28nXSwgWycqb28nLCAnIWZvbyddKTtcbiAqICAgLy89PiBbJ21vbyddXG4gKlxuICogICBtYXRjaGVyKFsnZm9vJywgJ2JhcicsICdtb28nXSwgWychKm9vJ10pO1xuICpcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqXG4gKiAgIG1hdGNoZXIoJ2tpbmdhJywgJ2tpbmdhJylcbiAqICAgLy89PiBbJ2tpbmdhJ11cbiAqICAgbWF0Y2hlcignaypuZ2EnLCAna2luZ2EnKVxuICogICAvLz0+IFsna2luZ2EnXVxuICogICBtYXRjaGVyKCdraW5nYScsICdub3BlJylcbiAqICAgLy89PiBbXVxuICpcbiAqICAgbWF0Y2hlcihuZXcgUmVnRXhwKC9raW5nYS8pLCAna2luZ2EnKVxuICogICAvLz0+IFsna2luZ2EnXVxuICogICBtYXRjaGVyKG5ldyBSZWdFeHAoL2tpbmdhLyksICdub3BlJylcbiAqICAgLy89PiBbJ25vcGUnXVxuICpcbiAqICAgbWF0Y2hlcih4ID0+IHggPT09ICdraW5nYScsICdraW5nYScpXG4gKiAgIC8vPT4gWydraW5nYSddXG4gKiAgIG1hdGNoZXIoeCA9PiB4ID09PSAna2luZ2EnLCAnbm9wZScpXG4gKiAgIC8vPT4gW11cbiAqXG4gKiAgIG1hdGNoZXIoe3Rlc3Q6IHggPT4geCA9PT0gJ2tpbmdhJ30sICdraW5nYScpXG4gKiAgIC8vPT4gWydraW5nYSddXG4gKiAgIG1hdGNoZXIoe3Rlc3Q6IHggPT4geCA9PT0gJ2tpbmdhJ30sICdub3BlJylcbiAqICAgLy89PiBbXVxuICpcbiAqXG4gKi9cbm0ubWF0Y2hlciA9IChpbnB1dHMsIHBhdHRlcm5zLCBzaG91bGROZWdhdGUsIGFscGhhT21lZ2EpID0+IHtcbiAgcGF0dGVybnMgPSB0b2FycihwYXR0ZXJucykubWFwKHAgPT4gbS5tYWtlKHAsIHNob3VsZE5lZ2F0ZSwgYWxwaGFPbWVnYSkpXG4gIGlucHV0cyA9IHRvYXJyKGlucHV0cylcblxuICBjb25zdCBmaXJzdE5lZ2F0ZWQgPSBwYXR0ZXJuc1swXS5uZWdhdGVkXG4gIGNvbnN0IG1hdGNoZXNUb1JldHVybiA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBpbnB1dCA9IGlucHV0c1tpXVxuICAgIC8vIElmIGZpcnN0IHBhdHRlcm4gaXMgbmVnYXRlZCB3ZSBpbmNsdWRlIGV2ZXJ5dGhpbmcgdG8gbWF0Y2ggdXNlciBleHBlY3RhdGlvblxuICAgIGxldCBtYXRjaGVzID0gZmlyc3ROZWdhdGVkXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBwYXR0ZXJucy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKHBhdHRlcm5zW2pdLnRlc3QoaW5wdXQpKSB7XG4gICAgICAgIG1hdGNoZXMgPSAhcGF0dGVybnNbal0ubmVnYXRlZFxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXRjaGVzKSBtYXRjaGVzVG9SZXR1cm4ucHVzaChpbnB1dClcbiAgfVxuXG4gIHJldHVybiBtYXRjaGVzVG9SZXR1cm5cbn1cblxuLyoqXG4gKiBAVE9ETyByZXBsYWNlIHRvLXRlc3RcbiAqL1xuLy8gbS50ZXN0ID0gKGlucHV0cywgcGF0dGVybnMpID0+IG0ubWF0Y2hlcihpbnB1dHMsIHBhdHRlcm5zKS5sZW5ndGggIT09IDBcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3RBc3NpZ24obS5tYXRjaGVyLCBtKVxuIl0sIm5hbWVzIjpbImNvbnN0IiwibGV0Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7O0FBU0FBLEdBQUssQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzlDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDMUNBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztBQUNqQ0EsR0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztBQUNoREEsR0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ3JDQSxHQUFLLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUNuREEsR0FBSyxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQztBQUNoRUEsR0FBSyxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQzs7QUFFNURBLEdBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDOztBQUV4REEsR0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaURaLENBQUMsQ0FBQyxJQUFJLEdBQUcsU0FBQSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLEFBQUc7RUFDOUMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUEsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFBOztFQUVqREMsR0FBRyxDQUFDLFNBQVMsR0FBRyxPQUFPO0VBQ3ZCLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxFQUFBLFNBQVMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxFQUFBO0VBQ3ZFLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUEsT0FBTyxTQUFTLEVBQUE7Ozs7OztFQU0xQ0EsR0FBRyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztFQUNsQyxJQUFJLE9BQU8sRUFBRSxFQUFBLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFBOztFQUUzQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQzs7RUFFMUIsSUFBSSxPQUFPLElBQUksWUFBWSxFQUFFLEVBQUEsU0FBUyxHQUFHLEtBQUksR0FBRSxTQUFTLE1BQUUsQUFBQyxFQUFBO0VBQzNELElBQUksVUFBVSxFQUFFLEVBQUEsU0FBUyxHQUFHLEdBQUUsR0FBRSxTQUFTLE1BQUUsQUFBQyxFQUFBOztFQUU1QyxTQUFTLEdBQUcsU0FBUyxDQUFDLENBQUEsRUFBQyxHQUFFLFNBQVMsQ0FBRSxFQUFFLEdBQUcsQ0FBQztFQUMxQyxTQUFTLENBQUMsT0FBTyxHQUFHLE9BQU87O0VBRTNCLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQztFQUM3QixPQUFPLFNBQVM7Q0FDakI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcURELENBQUMsQ0FBQyxPQUFPLEdBQUcsU0FBQSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxBQUFHO0VBQzFELFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQyxDQUFBLENBQUMsQUFBRyxTQUFBLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsR0FBQSxDQUFDO0VBQ3hFLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDOztFQUV0QkQsR0FBSyxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztFQUN4Q0EsR0FBSyxDQUFDLGVBQWUsR0FBRyxFQUFFOztFQUUxQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUN0Q0EsR0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDOztJQUV2QkMsR0FBRyxDQUFDLE9BQU8sR0FBRyxZQUFZO0lBQzFCLEtBQUtBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO01BQ3hDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUMzQixPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztPQUMvQjtLQUNGOztJQUVELElBQUksT0FBTyxFQUFFLEVBQUEsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQTtHQUN6Qzs7RUFFRCxPQUFPLGVBQWU7Q0FDdkI7Ozs7Ozs7QUFPRCxNQUFNLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQzsifQ==